提交 a13ffe7b 编写于 作者: M mfang

Merge

......@@ -281,3 +281,6 @@ c6d0108aca9f8f45b9cddeb6e483d464509e0127 jdk8u20-b06
0f821eb7e92b242c878dca68ef63f9626643ee8f jdk8u20-b08
aa0cb3af23d376e012a142b0531c4f42032fdacf jdk8u20-b09
a0d9c18a1041c4217db9cda1817f0e348f1be885 jdk8u20-b10
7ad480b982bf95b8a7290c8769b2698f6aacaf6b jdk8u20-b11
e101a12a45a777268a2e729803499a7514255e5b jdk8u20-b12
b5c2375893e2bca1883e5571bd911b6f0b533bf4 jdk8u20-b13
......@@ -191,6 +191,9 @@ public enum Source {
public boolean allowObjectToPrimitiveCast() {
return compareTo(JDK1_7) >= 0;
}
public boolean enforceThisDotInit() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowPoly() {
return compareTo(JDK1_8) >= 0;
}
......
......@@ -703,10 +703,10 @@ public abstract class Symbol extends AnnoConstruct implements Element {
}
/**
* A total ordering between type symbols that refines the
* A partial ordering between type symbols that refines the
* class inheritance graph.
*
* Typevariables always precede other kinds of symbols.
* Type variables always precede other kinds of symbols.
*/
public final boolean precedes(TypeSymbol that, Types types) {
if (this == that)
......
......@@ -1445,12 +1445,19 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
* Inference variable bound kinds
*/
public enum InferenceBound {
/** upper bounds */
UPPER,
/** lower bounds */
LOWER,
/** equality constraints */
EQ;
UPPER {
public InferenceBound complement() { return LOWER; }
},
/** lower bounds */
LOWER {
public InferenceBound complement() { return UPPER; }
},
/** equality constraints */
EQ {
public InferenceBound complement() { return EQ; }
};
public abstract InferenceBound complement();
}
/** inference variable bounds */
......@@ -1636,6 +1643,9 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
//only change bounds if request comes from substBounds
super.addBound(ib, bound, types, update);
}
else if (bound.hasTag(UNDETVAR) && !((UndetVar) bound).isCaptured()) {
((UndetVar) bound).addBound(ib.complement(), this, types, false);
}
}
@Override
......
......@@ -43,6 +43,7 @@ import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
import static com.sun.tools.javac.code.Flags.*;
......@@ -151,31 +152,31 @@ public class Types {
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="lowerBound">
// <editor-fold defaultstate="collapsed" desc="wildLowerBound">
/**
* The "lvalue conversion".<br>
* The lower bound of most types is the type
* itself. Wildcards, on the other hand have upper
* and lower bounds.
* @param t a type
* @return the lower bound of the given type
* Get a wildcard's lower bound, returning non-wildcards unchanged.
* @param t a type argument, either a wildcard or a type
*/
public Type lowerBound(Type t) {
return lowerBound.visit(t);
public Type wildLowerBound(Type t) {
if (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType) t;
return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type);
}
else return t;
}
// where
private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
@Override
public Type visitWildcardType(WildcardType t, Void ignored) {
return t.isExtendsBound() ? syms.botType : visit(t.type);
}
// </editor-fold>
@Override
public Type visitCapturedType(CapturedType t, Void ignored) {
return visit(t.getLowerBound());
}
};
// <editor-fold defaultstate="collapsed" desc="cvarLowerBound">
/**
* Get a capture variable's lower bound, returning other types unchanged.
* @param t a type
*/
public Type cvarLowerBound(Type t) {
if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) {
return cvarLowerBound(t.getLowerBound());
}
else return t;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
......@@ -305,8 +306,8 @@ public class Types {
}
/**
* Is t a subtype of or convertiable via boxing/unboxing
* convertions to s?
* Is t a subtype of or convertible via boxing/unboxing
* conversions to s?
*/
public boolean isConvertible(Type t, Type s) {
return isConvertible(t, s, noWarnings);
......@@ -827,9 +828,15 @@ public class Types {
return true;
}
Type lower = lowerBound(s);
if (s != lower)
return isSubtype(capture ? capture(t) : t, lower, false);
// Generally, if 's' is a type variable, recur on lower bound; but
// for inference variables and intersections, we need to keep 's'
// (see JLS 4.10.2 for intersections and 18.2.3 for inference vars)
if (!t.hasTag(UNDETVAR) && !t.isCompound()) {
// TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s
Type lower = cvarLowerBound(wildLowerBound(s));
if (s != lower)
return isSubtype(capture ? capture(t) : t, lower, false);
}
return isSubtype.visit(capture ? capture(t) : t, s);
}
......@@ -913,14 +920,11 @@ public class Types {
@Override
public Boolean visitClassType(ClassType t, Type s) {
Type sup = asSuper(t, s.tsym);
return sup != null
&& sup.tsym == s.tsym
// You're not allowed to write
// Vector<Object> vec = new Vector<String>();
// But with wildcards you can write
// Vector<? extends Object> vec = new Vector<String>();
// which means that subtype checking must be done
// here instead of same-type checking (via containsType).
if (sup == null) return false;
// If t is an intersection, sup might not be a class type
if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
return sup.tsym == s.tsym
// Check type variable containment
&& (!s.isParameterized() || containsTypeRecursive(s, sup))
&& isSubtypeNoCapture(sup.getEnclosingType(),
s.getEnclosingType());
......@@ -1136,7 +1140,7 @@ public class Types {
return visit(s, t);
if (s.isSuperBound() && !s.isExtendsBound())
return visit(t, upperBound(s)) && visit(t, lowerBound(s));
return visit(t, upperBound(s)) && visit(t, wildLowerBound(s));
if (t.isCompound() && s.isCompound()) {
if (!visit(supertype(t), supertype(s)))
......@@ -1291,7 +1295,7 @@ public class Types {
break;
}
case SUPER: {
Type bound = lowerBound(s);
Type bound = wildLowerBound(s);
undetvar.addBound(InferenceBound.LOWER, bound, this);
break;
}
......@@ -1384,9 +1388,9 @@ public class Types {
// t.isSuperBound()
// || isSubtypeNoCapture(upperBound(s), U(t)));
// System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
// L(t), t, s, lowerBound(s),
// L(t), t, s, wildLowerBound(s),
// t.isExtendsBound()
// || isSubtypeNoCapture(L(t), lowerBound(s)));
// || isSubtypeNoCapture(L(t), wildLowerBound(s)));
// System.err.println();
// }
......@@ -1398,7 +1402,7 @@ public class Types {
// debugContainsType(t, s);
return isSameWildcard(t, s)
|| isCaptureOf(s, t)
|| ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
|| ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) &&
(t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
}
}
......@@ -1760,7 +1764,7 @@ public class Types {
if (s.isExtendsBound())
return !isCastableRecursive(t.type, upperBound(s));
else if (s.isSuperBound())
return notSoftSubtypeRecursive(lowerBound(s), t.type);
return notSoftSubtypeRecursive(wildLowerBound(s), t.type);
} else if (t.isSuperBound()) {
if (s.isExtendsBound())
return notSoftSubtypeRecursive(t.type, upperBound(s));
......@@ -1770,19 +1774,13 @@ public class Types {
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
/**
* Returns the lower bounds of the formals of a method.
*/
public List<Type> lowerBoundArgtypes(Type t) {
return lowerBounds(t.getParameterTypes());
}
public List<Type> lowerBounds(List<Type> ts) {
return map(ts, lowerBoundMapping);
// <editor-fold defaultstate="collapsed" desc="cvarLowerBounds">
public List<Type> cvarLowerBounds(List<Type> ts) {
return map(ts, cvarLowerBoundMapping);
}
private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
private final Mapping cvarLowerBoundMapping = new Mapping("cvarLowerBound") {
public Type apply(Type t) {
return lowerBound(t);
return cvarLowerBound(t);
}
};
// </editor-fold>
......@@ -1934,6 +1932,17 @@ public class Types {
* @param sym a symbol
*/
public Type asSuper(Type t, Symbol sym) {
/* Some examples:
*
* (Enum<E>, Comparable) => Comparable<E>
* (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
* (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
* (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
* Iterable<capture#160 of ? extends c.s.s.d.DocTree>
*/
if (sym.type == syms.objectType) { //optimization
return syms.objectType;
}
return asSuper.visit(t, sym);
}
// where
......@@ -1949,16 +1958,18 @@ public class Types {
return t;
Type st = supertype(t);
if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) {
if (st.hasTag(CLASS) || st.hasTag(TYPEVAR)) {
Type x = asSuper(st, sym);
if (x != null)
return x;
}
if ((sym.flags() & INTERFACE) != 0) {
for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
Type x = asSuper(l.head, sym);
if (x != null)
return x;
if (!l.head.hasTag(ERROR)) {
Type x = asSuper(l.head, sym);
if (x != null)
return x;
}
}
}
return null;
......@@ -2240,7 +2251,8 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="makeCompoundType">
/**
* Make a compound type from non-empty list of types
* Make a compound type from non-empty list of types. The list should be
* ordered according to {@link Symbol#precedes(TypeSymbol,Types)}.
*
* @param bounds the types from which the compound type is formed
* @param supertype is objectType if all bounds are interfaces,
......@@ -3330,12 +3342,15 @@ public class Types {
* Insert a type in a closure
*/
public List<Type> insert(List<Type> cl, Type t) {
if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
if (cl.isEmpty()) {
return cl.prepend(t);
} else if (cl.head.tsym.precedes(t.tsym, this)) {
return insert(cl.tail, t).prepend(cl.head);
} else {
} else if (t.tsym == cl.head.tsym) {
return cl;
} else if (t.tsym.precedes(cl.head.tsym, this)) {
return cl.prepend(t);
} else {
// t comes after head, or the two are unrelated
return insert(cl.tail, t).prepend(cl.head);
}
}
......@@ -3347,12 +3362,15 @@ public class Types {
return cl2;
} else if (cl2.isEmpty()) {
return cl1;
} else if (cl1.head.tsym == cl2.head.tsym) {
return union(cl1.tail, cl2.tail).prepend(cl1.head);
} else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
return union(cl1.tail, cl2).prepend(cl1.head);
} else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
return union(cl1, cl2.tail).prepend(cl2.head);
} else {
return union(cl1.tail, cl2.tail).prepend(cl1.head);
// unrelated types
return union(cl1.tail, cl2).prepend(cl1.head);
}
}
......@@ -3462,18 +3480,31 @@ public class Types {
private List<Type> closureMin(List<Type> cl) {
ListBuffer<Type> classes = new ListBuffer<>();
ListBuffer<Type> interfaces = new ListBuffer<>();
Set<Type> toSkip = new HashSet<>();
while (!cl.isEmpty()) {
Type current = cl.head;
if (current.isInterface())
interfaces.append(current);
else
classes.append(current);
ListBuffer<Type> candidates = new ListBuffer<>();
for (Type t : cl.tail) {
if (!isSubtypeNoCapture(current, t))
candidates.append(t);
boolean keep = !toSkip.contains(current);
if (keep && current.hasTag(TYPEVAR)) {
// skip lower-bounded variables with a subtype in cl.tail
for (Type t : cl.tail) {
if (isSubtypeNoCapture(t, current)) {
keep = false;
break;
}
}
}
cl = candidates.toList();
if (keep) {
if (current.isInterface())
interfaces.append(current);
else
classes.append(current);
for (Type t : cl.tail) {
// skip supertypes of 'current' in cl.tail
if (isSubtypeNoCapture(current, t))
toSkip.add(t);
}
}
cl = cl.tail;
}
return classes.appendList(interfaces).toList();
}
......@@ -3633,7 +3664,19 @@ public class Types {
return s;
List<Type> closure = union(closure(t), closure(s));
List<Type> bounds = closureMin(closure);
return glbFlattened(closure, t);
}
//where
/**
* Perform glb for a list of non-primitive, non-error, non-compound types;
* redundant elements are removed. Bounds should be ordered according to
* {@link Symbol#precedes(TypeSymbol,Types)}.
*
* @param flatBounds List of type to glb
* @param errT Original type to use if the result is an error type
*/
private Type glbFlattened(List<Type> flatBounds, Type errT) {
List<Type> bounds = closureMin(flatBounds);
if (bounds.isEmpty()) { // length == 0
return syms.objectType;
......@@ -3641,11 +3684,21 @@ public class Types {
return bounds.head;
} else { // length > 1
int classCount = 0;
for (Type bound : bounds)
if (!bound.isInterface())
List<Type> lowers = List.nil();
for (Type bound : bounds) {
if (!bound.isInterface()) {
classCount++;
if (classCount > 1)
return createErrorType(t);
Type lower = cvarLowerBound(bound);
if (bound != lower && !lower.hasTag(BOT))
lowers = insert(lowers, lower);
}
}
if (classCount > 1) {
if (lowers.isEmpty())
return createErrorType(errT);
else
return glbFlattened(union(bounds, lowers), errT);
}
}
return makeCompoundType(bounds);
}
......@@ -3869,9 +3922,11 @@ public class Types {
}
return buf.reverse();
}
public Type capture(Type t) {
if (!t.hasTag(CLASS))
if (!t.hasTag(CLASS)) {
return t;
}
if (t.getEnclosingType() != Type.noType) {
Type capturedEncl = capture(t.getEnclosingType());
if (capturedEncl != t.getEnclosingType()) {
......@@ -4123,7 +4178,7 @@ public class Types {
if (source.isExtendsBound())
adaptRecursive(upperBound(source), upperBound(target));
else if (source.isSuperBound())
adaptRecursive(lowerBound(source), lowerBound(target));
adaptRecursive(wildLowerBound(source), wildLowerBound(target));
return null;
}
......@@ -4135,7 +4190,7 @@ public class Types {
Type val = mapping.get(source.tsym);
if (val != null) {
if (val.isSuperBound() && target.isSuperBound()) {
val = isSubtype(lowerBound(val), lowerBound(target))
val = isSubtype(wildLowerBound(val), wildLowerBound(target))
? target : val;
} else if (val.isExtendsBound() && target.isExtendsBound()) {
val = isSubtype(upperBound(val), upperBound(target))
......@@ -4249,7 +4304,7 @@ public class Types {
}
public Type visitType(Type t, Void s) {
return high ? upperBound(t) : lowerBound(t);
return high ? upperBound(t) : t;
}
@Override
......
......@@ -2618,7 +2618,7 @@ public class Attr extends JCTree.Visitor {
* - an instance field, we use the first constructor.
* - a static field, we create a fake clinit method.
*/
private Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
Env<AttrContext> lambdaEnv;
Symbol owner = env.info.scope.owner;
if (owner.kind == VAR && owner.owner.kind == TYP) {
......
......@@ -510,6 +510,11 @@ public class Check {
public DeferredAttrContext deferredAttrContext() {
return deferredAttr.emptyDeferredAttrContext;
}
@Override
public String toString() {
return "CheckContext: basicHandler";
}
};
/** Check that a given type is assignable to a given proto-type.
......@@ -616,7 +621,7 @@ public class Check {
} else if (a.isExtendsBound()) {
return types.isCastable(bound, types.upperBound(a), types.noWarnings);
} else if (a.isSuperBound()) {
return !types.notSoftSubtype(types.lowerBound(a), bound);
return !types.notSoftSubtype(types.wildLowerBound(a), bound);
}
return true;
}
......@@ -2680,7 +2685,7 @@ public class Check {
if (types.isSameType(type, syms.stringType)) return;
if ((type.tsym.flags() & Flags.ENUM) != 0) return;
if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
if (types.lowerBound(type).tsym == syms.classType.tsym) return;
if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
validateAnnotationType(pos, types.elemtype(type));
return;
......
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,7 +25,7 @@
package com.sun.tools.javac.comp;
import com.sun.source.tree.MemberReferenceTree;
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
......@@ -35,10 +35,8 @@ import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr.ResultInfo;
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper;
import com.sun.tools.javac.tree.JCTree.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
......@@ -48,6 +46,7 @@ import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import static com.sun.tools.javac.code.Kinds.VAL;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
......@@ -76,6 +75,8 @@ public class DeferredAttr extends JCTree.Visitor {
final Symtab syms;
final TreeMaker make;
final Types types;
final Flow flow;
final Names names;
public static DeferredAttr instance(Context context) {
DeferredAttr instance = context.get(deferredAttrKey);
......@@ -96,7 +97,8 @@ public class DeferredAttr extends JCTree.Visitor {
syms = Symtab.instance(context);
make = TreeMaker.instance(context);
types = Types.instance(context);
Names names = Names.instance(context);
flow = Flow.instance(context);
names = Names.instance(context);
stuckTree = make.Ident(names.empty).setType(Type.stuckType);
emptyDeferredAttrContext =
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
......@@ -108,6 +110,11 @@ public class DeferredAttr extends JCTree.Visitor {
void complete() {
Assert.error("Empty deferred context!");
}
@Override
public String toString() {
return "Empty deferred context!";
}
};
}
......@@ -139,6 +146,11 @@ public class DeferredAttr extends JCTree.Visitor {
return DEFERRED;
}
@Override
public String toString() {
return "DeferredType";
}
/**
* A speculative cache is used to keep track of all overload resolution rounds
* that triggered speculative attribution on a given deferred type. Each entry
......@@ -378,7 +390,9 @@ public class DeferredAttr extends JCTree.Visitor {
}
}
//where
protected TreeScanner unenterScanner = new TreeScanner() {
protected UnenterScanner unenterScanner = new UnenterScanner();
class UnenterScanner extends TreeScanner {
@Override
public void visitClassDef(JCClassDecl tree) {
ClassSymbol csym = tree.sym;
......@@ -391,7 +405,7 @@ public class DeferredAttr extends JCTree.Visitor {
syms.classes.remove(csym.flatname);
super.visitClassDef(tree);
}
};
}
/**
* A deferred context is created on each method check. A deferred context is
......@@ -595,19 +609,111 @@ public class DeferredAttr extends JCTree.Visitor {
public void visitLambda(JCLambda tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (inferenceContext.inferencevars.contains(pt)) {
//ok
return;
} else {
if (!inferenceContext.inferencevars.contains(pt)) {
//must be a functional descriptor
Type descriptorType = null;
try {
Type desc = types.findDescriptorType(pt);
if (desc.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
}
descriptorType = types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
checkContext.report(null, ex.getDiagnostic());
}
if (descriptorType.getParameterTypes().length() != tree.params.length()) {
checkContext.report(tree,
diags.fragment("incompatible.arg.types.in.lambda"));
}
Type currentReturnType = descriptorType.getReturnType();
boolean returnTypeIsVoid = currentReturnType.hasTag(VOID);
if (tree.getBodyKind() == BodyKind.EXPRESSION) {
boolean isExpressionCompatible = !returnTypeIsVoid ||
TreeInfo.isExpressionStatement((JCExpression)tree.getBody());
if (!isExpressionCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
} else {
LambdaBodyStructChecker lambdaBodyChecker =
new LambdaBodyStructChecker();
tree.body.accept(lambdaBodyChecker);
boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible;
if (returnTypeIsVoid) {
if (!isVoidCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("unexpected.ret.val"));
}
} else {
boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible
&& !canLambdaBodyCompleteNormally(tree);
if (!isValueCompatible && !isVoidCompatible) {
log.error(tree.body.pos(),
"lambda.body.neither.value.nor.void.compatible");
}
if (!isValueCompatible) {
resultInfo.checkContext.report(tree.pos(),
diags.fragment("incompatible.ret.type.in.lambda",
diags.fragment("missing.ret.val", currentReturnType)));
}
}
}
}
}
boolean canLambdaBodyCompleteNormally(JCLambda tree) {
JCLambda newTree = new TreeCopier<>(make).copy(tree);
/* attr.lambdaEnv will create a meaningful env for the
* lambda expression. This is specially useful when the
* lambda is used as the init of a field. But we need to
* remove any added symbol.
*/
Env<AttrContext> localEnv = attr.lambdaEnv(newTree, env);
try {
List<JCVariableDecl> tmpParams = newTree.params;
while (tmpParams.nonEmpty()) {
tmpParams.head.vartype = make.at(tmpParams.head).Type(syms.errType);
tmpParams = tmpParams.tail;
}
attr.attribStats(newTree.params, localEnv);
/* set pt to Type.noType to avoid generating any bound
* which may happen if lambda's return type is an
* inference variable
*/
Attr.ResultInfo bodyResultInfo = attr.new ResultInfo(VAL, Type.noType);
localEnv.info.returnResult = bodyResultInfo;
// discard any log output
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
JCBlock body = (JCBlock)newTree.body;
/* we need to attribute the lambda body before
* doing the aliveness analysis. This is because
* constant folding occurs during attribution
* and the reachability of some statements depends
* on constant values, for example:
*
* while (true) {...}
*/
attr.attribStats(body.stats, localEnv);
attr.preFlow(newTree);
/* make an aliveness / reachability analysis of the lambda
* to determine if it can complete normally
*/
flow.analyzeLambda(localEnv, newTree, make, true);
} finally {
log.popDiagnosticHandler(diagHandler);
}
return newTree.canCompleteNormally;
} finally {
JCBlock body = (JCBlock)newTree.body;
unenterScanner.scan(body.stats);
localEnv.info.scope.leave();
}
}
......@@ -625,10 +731,7 @@ public class DeferredAttr extends JCTree.Visitor {
public void visitReference(JCMemberReference tree) {
Check.CheckContext checkContext = resultInfo.checkContext;
Type pt = resultInfo.pt;
if (inferenceContext.inferencevars.contains(pt)) {
//ok
return;
} else {
if (!inferenceContext.inferencevars.contains(pt)) {
try {
types.findDescriptorType(pt);
} catch (Types.FunctionDescriptorLookupError ex) {
......@@ -658,6 +761,40 @@ public class DeferredAttr extends JCTree.Visitor {
}
}
}
/* This visitor looks for return statements, its analysis will determine if
* a lambda body is void or value compatible. We must analyze return
* statements contained in the lambda body only, thus any return statement
* contained in an inner class or inner lambda body, should be ignored.
*/
class LambdaBodyStructChecker extends TreeScanner {
boolean isVoidCompatible = true;
boolean isPotentiallyValueCompatible = true;
@Override
public void visitClassDef(JCClassDecl tree) {
// do nothing
}
@Override
public void visitLambda(JCLambda tree) {
// do nothing
}
@Override
public void visitNewClass(JCNewClass tree) {
// do nothing
}
@Override
public void visitReturn(JCReturn tree) {
if (tree.expr != null) {
isVoidCompatible = false;
} else {
isPotentiallyValueCompatible = false;
}
}
}
}
/** an empty deferred attribution context - all methods throw exceptions */
......@@ -769,7 +906,7 @@ public class DeferredAttr extends JCTree.Visitor {
/**
* handler that is executed when a node has been discarded
*/
abstract void skip(JCTree tree);
void skip(JCTree tree) {}
}
/**
......@@ -781,11 +918,6 @@ public class DeferredAttr extends JCTree.Visitor {
PolyScanner() {
super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE));
}
@Override
void skip(JCTree tree) {
//do nothing
}
}
/**
......@@ -798,11 +930,6 @@ public class DeferredAttr extends JCTree.Visitor {
super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP,
FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP));
}
@Override
void skip(JCTree tree) {
//do nothing
}
}
/**
......
......@@ -45,7 +45,7 @@ import static com.sun.tools.javac.code.TypeTag.VOID;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/** This pass implements dataflow analysis for Java programs though
* different AST visitor steps. Liveness analysis (see AliveAlanyzer) checks that
* different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that
* every statement is reachable. Exception analysis (see FlowAnalyzer) ensures that
* every checked exception that is thrown is declared or caught. Definite assignment analysis
* (see AssignAnalyzer) ensures that each variable is assigned when used. Definite
......@@ -197,6 +197,7 @@ public class Flow {
private final boolean allowImprovedRethrowAnalysis;
private final boolean allowImprovedCatchAnalysis;
private final boolean allowEffectivelyFinalInInnerClasses;
private final boolean enforceThisDotInit;
public static Flow instance(Context context) {
Flow instance = context.get(flowKey);
......@@ -207,7 +208,7 @@ public class Flow {
public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
new AliveAnalyzer().analyzeTree(env, make);
new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
new FlowAnalyzer().analyzeTree(env, make);
new CaptureAnalyzer().analyzeTree(env, make);
}
......@@ -239,7 +240,7 @@ public class Flow {
//related errors, which will allow for more errors to be detected
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
new AssignAnalyzer(log, syms, lint, names).analyzeTree(env);
new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
......@@ -289,6 +290,7 @@ public class Flow {
allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis();
allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
enforceThisDotInit = source.enforceThisDotInit();
}
/**
......@@ -1427,6 +1429,8 @@ public class Flow {
protected Names names;
final boolean enforceThisDotInit;
public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
final Bits inits;
......@@ -1449,7 +1453,7 @@ public class Flow {
}
}
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) {
public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
this.inits = inits;
uninits = new Bits();
uninitsTry = new Bits();
......@@ -1459,6 +1463,7 @@ public class Flow {
uninitsWhenFalse = new Bits(true);
this.syms = syms;
this.names = names;
this.enforceThisDotInit = enforceThisDotInit;
}
private boolean isInitialConstructor = false;
......@@ -2280,12 +2285,34 @@ public class Flow {
public void visitAssign(JCAssign tree) {
JCTree lhs = TreeInfo.skipParens(tree.lhs);
if (!(lhs instanceof JCIdent)) {
if (!isIdentOrThisDotIdent(lhs))
scanExpr(lhs);
}
scanExpr(tree.rhs);
letInit(lhs);
}
private boolean isIdentOrThisDotIdent(JCTree lhs) {
if (lhs.hasTag(IDENT))
return true;
if (!lhs.hasTag(SELECT))
return false;
JCFieldAccess fa = (JCFieldAccess)lhs;
return fa.selected.hasTag(IDENT) &&
((JCIdent)fa.selected).name == names._this;
}
// check fields accessed through this.<field> are definitely
// assigned before reading their value
public void visitSelect(JCFieldAccess tree) {
super.visitSelect(tree);
if (enforceThisDotInit &&
tree.selected.hasTag(IDENT) &&
((JCIdent)tree.selected).name == names._this &&
tree.sym.kind == VAR)
{
checkInit(tree.pos(), (VarSymbol)tree.sym);
}
}
public void visitAssignop(JCAssignOp tree) {
scanExpr(tree.lhs);
......@@ -2419,8 +2446,8 @@ public class Flow {
}
}
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) {
super(new Bits(), syms, names);
public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
super(new Bits(), syms, names, enforceThisDotInit);
this.log = log;
this.lint = lint;
}
......
......@@ -142,24 +142,24 @@ public class Infer {
* Main inference entry point - instantiate a generic method type
* using given argument types and (possibly) an expected target-type.
*/
public Type instantiateMethod(Env<AttrContext> env,
List<Type> tvars,
MethodType mt,
Attr.ResultInfo resultInfo,
Symbol msym,
List<Type> argtypes,
boolean allowBoxing,
boolean useVarargs,
Resolve.MethodResolutionContext resolveContext,
Warner warn) throws InferenceException {
Type instantiateMethod( Env<AttrContext> env,
List<Type> tvars,
MethodType mt,
Attr.ResultInfo resultInfo,
MethodSymbol msym,
List<Type> argtypes,
boolean allowBoxing,
boolean useVarargs,
Resolve.MethodResolutionContext resolveContext,
Warner warn) throws InferenceException {
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
final InferenceContext inferenceContext = new InferenceContext(tvars);
final InferenceContext inferenceContext = new InferenceContext(tvars); //B0
inferenceException.clear();
try {
DeferredAttr.DeferredAttrContext deferredAttrContext =
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext,
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, //B2
argtypes, mt.getParameterTypes(), warn);
if (allowGraphInference &&
......@@ -167,7 +167,8 @@ public class Infer {
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
//inject return constraints earlier
checkWithinBounds(inferenceContext, warn); //propagation
Type newRestype = generateReturnConstraints(resultInfo, mt, inferenceContext);
Type newRestype = generateReturnConstraints(env.tree, resultInfo, //B3
mt, inferenceContext);
mt = (MethodType)types.createMethodTypeWithReturn(mt, newRestype);
//propagate outwards if needed
if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
......@@ -193,7 +194,7 @@ public class Infer {
inferenceContext.restvars().nonEmpty() &&
resultInfo != null &&
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
generateReturnConstraints(resultInfo, mt, inferenceContext);
generateReturnConstraints(env.tree, resultInfo, mt, inferenceContext);
inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst
mt = (MethodType)inferenceContext.asInstType(mt);
}
......@@ -210,6 +211,12 @@ public class Infer {
} else {
inferenceContext.notifyChange(inferenceContext.boundedVars());
}
if (resultInfo == null) {
/* if the is no result info then we can clear the capture types
* cache without affecting any result info check
*/
inferenceContext.captureTypeCache.clear();
}
}
}
......@@ -218,7 +225,7 @@ public class Infer {
* call occurs in a context where a type T is expected, use the expected
* type to derive more constraints on the generic method inference variables.
*/
Type generateReturnConstraints(Attr.ResultInfo resultInfo,
Type generateReturnConstraints(JCTree tree, Attr.ResultInfo resultInfo,
MethodType mt, InferenceContext inferenceContext) {
InferenceContext rsInfoInfContext = resultInfo.checkContext.inferenceContext();
Type from = mt.getReturnType();
......@@ -232,13 +239,29 @@ public class Infer {
}
}
}
Type qtype1 = inferenceContext.asUndetVar(from);
Type to = returnConstraintTarget(qtype1, resultInfo.pt);
Type qtype = inferenceContext.asUndetVar(from);
Type to = resultInfo.pt;
if (qtype.hasTag(VOID)) {
to = syms.voidType;
} else if (to.hasTag(NONE)) {
to = from.isPrimitive() ? from : syms.objectType;
} else if (qtype.hasTag(UNDETVAR)) {
if (resultInfo.pt.isReference()) {
to = generateReturnConstraintsUndetVarToReference(
tree, (UndetVar)qtype, to, resultInfo, inferenceContext);
} else {
if (to.isPrimitive()) {
to = generateReturnConstraintsPrimitive(tree, (UndetVar)qtype, to,
resultInfo, inferenceContext);
}
}
}
Assert.check(allowGraphInference || !rsInfoInfContext.free(to),
"legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
//we need to skip capture?
Warner retWarn = new Warner();
if (!resultInfo.checkContext.compatible(qtype1, rsInfoInfContext.asUndetVar(to), retWarn) ||
if (!resultInfo.checkContext.compatible(qtype, rsInfoInfContext.asUndetVar(to), retWarn) ||
//unchecked conversion is not allowed in source 7 mode
(!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) {
throw inferenceException
......@@ -248,30 +271,96 @@ public class Infer {
return from;
}
Type returnConstraintTarget(Type from, Type to) {
if (from.hasTag(VOID)) {
return syms.voidType;
} else if (to.hasTag(NONE)) {
return from.isPrimitive() ? from : syms.objectType;
} else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
if (!allowGraphInference) {
//if legacy, just return boxed type
return types.boxedClass(to).type;
}
//if graph inference we need to skip conflicting boxed bounds...
UndetVar uv = (UndetVar)from;
for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type boundAsPrimitive = types.unboxedType(t);
if (boundAsPrimitive == null) continue;
if (types.isConvertible(boundAsPrimitive, to)) {
//effectively skip return-type constraint generation (compatibility)
return syms.objectType;
private Type generateReturnConstraintsPrimitive(JCTree tree, UndetVar from,
Type to, Attr.ResultInfo resultInfo, InferenceContext inferenceContext) {
if (!allowGraphInference) {
//if legacy, just return boxed type
return types.boxedClass(to).type;
}
//if graph inference we need to skip conflicting boxed bounds...
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.UPPER,
InferenceBound.LOWER)) {
Type boundAsPrimitive = types.unboxedType(t);
if (boundAsPrimitive == null || boundAsPrimitive.hasTag(NONE)) {
continue;
}
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
return types.boxedClass(to).type;
}
private Type generateReturnConstraintsUndetVarToReference(JCTree tree,
UndetVar from, Type to, Attr.ResultInfo resultInfo,
InferenceContext inferenceContext) {
Type captureOfTo = types.capture(to);
/* T is a reference type, but is not a wildcard-parameterized type, and either
*/
if (captureOfTo == to) { //not a wildcard parameterized type
/* i) B2 contains a bound of one of the forms alpha = S or S <: alpha,
* where S is a wildcard-parameterized type, or
*/
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type captureOfBound = types.capture(t);
if (captureOfBound != t) {
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
/* ii) B2 contains two bounds of the forms S1 <: alpha and S2 <: alpha,
* where S1 and S2 have supertypes that are two different
* parameterizations of the same generic class or interface.
*/
for (Type aLowerBound : from.getBounds(InferenceBound.LOWER)) {
for (Type anotherLowerBound : from.getBounds(InferenceBound.LOWER)) {
if (aLowerBound != anotherLowerBound &&
commonSuperWithDiffParameterization(aLowerBound, anotherLowerBound)) {
/* self comment check if any lower bound may be and undetVar,
* in that case the result of this call may be a false positive.
* Should this be restricted to non free types?
*/
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
}
return types.boxedClass(to).type;
} else {
return to;
}
/* T is a parameterization of a generic class or interface, G,
* and B2 contains a bound of one of the forms alpha = S or S <: alpha,
* where there exists no type of the form G<...> that is a
* supertype of S, but the raw type G is a supertype of S
*/
if (to.isParameterized()) {
for (Type t : from.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
Type sup = types.asSuper(t, to.tsym);
if (sup != null && sup.isRaw()) {
return generateReferenceToTargetConstraint(tree, from, to,
resultInfo, inferenceContext);
}
}
}
return to;
}
private boolean commonSuperWithDiffParameterization(Type t, Type s) {
Pair<Type, Type> supers = getParameterizedSupers(t, s);
return (supers != null && !types.isSameType(supers.fst, supers.snd));
}
private Type generateReferenceToTargetConstraint(JCTree tree, UndetVar from,
Type to, Attr.ResultInfo resultInfo,
InferenceContext inferenceContext) {
inferenceContext.solve(List.of(from.qtype), new Warner());
Type capturedType = resultInfo.checkContext.inferenceContext()
.cachedCapture(tree, from.inst, false);
if (types.isConvertible(capturedType,
resultInfo.checkContext.inferenceContext().asUndetVar(to))) {
//effectively skip additional return-type constraint generation (compatibility)
return syms.objectType;
}
return to;
}
/**
......@@ -1318,7 +1407,7 @@ public class Infer {
Type solve(UndetVar uv, InferenceContext inferenceContext) {
Infer infer = inferenceContext.infer();
List<Type> hibounds = filterBounds(uv, inferenceContext);
//note: lobounds should have at least one element
//note: hibounds should have at least one element
Type owntype = hibounds.tail.tail == null ? hibounds.head : infer.types.glb(hibounds);
if (owntype.isPrimitive() || owntype.hasTag(ERROR)) {
throw infer.inferenceException
......@@ -2082,8 +2171,10 @@ public class Infer {
* Copy variable in this inference context to the given context
*/
void dupTo(final InferenceContext that) {
that.inferencevars = that.inferencevars.appendList(inferencevars);
that.undetvars = that.undetvars.appendList(undetvars);
that.inferencevars = that.inferencevars.appendList(
inferencevars.diff(that.inferencevars));
that.undetvars = that.undetvars.appendList(
undetvars.diff(that.undetvars));
//set up listeners to notify original inference contexts as
//propagated vars are inferred in new context
for (Type t : inferencevars) {
......@@ -2202,6 +2293,30 @@ public class Infer {
return "Inference vars: " + inferencevars + '\n' +
"Undet vars: " + undetvars;
}
/* Method Types.capture() generates a new type every time it's applied
* to a wildcard parameterized type. This is intended functionality but
* there are some cases when what you need is not to generate a new
* captured type but to check that a previously generated captured type
* is correct. There are cases when caching a captured type for later
* reuse is sound. In general two captures from the same AST are equal.
* This is why the tree is used as the key of the map below. This map
* stores a Type per AST.
*/
Map<JCTree, Type> captureTypeCache = new HashMap<>();
Type cachedCapture(JCTree tree, Type t, boolean readOnly) {
Type captured = captureTypeCache.get(tree);
if (captured != null) {
return captured;
}
Type result = types.capture(t);
if (result != t && !readOnly) { // then t is a wildcard parameterized type
captureTypeCache.put(tree, result);
}
return result;
}
}
final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
......
......@@ -36,6 +36,7 @@ import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
......@@ -50,8 +51,10 @@ import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*;
import static com.sun.tools.javac.code.Flags.*;
......@@ -438,13 +441,9 @@ public class LambdaToMethod extends TreeTranslator {
public void visitVarDef(JCVariableDecl tree) {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context;
if (context != null && lambdaContext.getSymbolMap(LOCAL_VAR).containsKey(tree.sym)) {
JCExpression init = translate(tree.init);
int prevPos = make.pos;
try {
result = make.at(tree).VarDef((VarSymbol)lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym), init);
} finally {
make.at(prevPos);
}
tree.init = translate(tree.init);
tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
result = tree;
} else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
JCExpression init = translate(tree.init);
VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
......@@ -1286,7 +1285,10 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitNewClass(JCNewClass tree) {
if (lambdaNewClassFilter(context(), tree)) {
TypeSymbol def = tree.type.tsym;
boolean inReferencedClass = currentlyInClass(def);
boolean isLocal = def.isLocal();
if ((inReferencedClass && isLocal || lambdaNewClassFilter(context(), tree))) {
TranslationContext<?> localContext = context();
while (localContext != null) {
if (localContext.tree.getTag() == LAMBDA) {
......@@ -1296,16 +1298,16 @@ public class LambdaToMethod extends TreeTranslator {
localContext = localContext.prev;
}
}
if (context() != null && tree.type.tsym.owner.kind == MTH) {
if (context() != null && !inReferencedClass && isLocal) {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context();
captureLocalClassDefs(tree.type.tsym, lambdaContext);
captureLocalClassDefs(def, lambdaContext);
}
super.visitNewClass(tree);
}
//where
void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) {
JCClassDecl localCDef = localClassDefs.get(csym);
if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) {
if (localCDef != null && lambdaContext.freeVarProcessedLocalClasses.add(csym)) {
BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() {
@Override
void addFreeVars(ClassSymbol c) {
......@@ -1331,6 +1333,18 @@ public class LambdaToMethod extends TreeTranslator {
fvc.scan(localCDef);
}
}
//where
boolean currentlyInClass(Symbol csym) {
for (Frame frame : frameStack) {
if (frame.tree.hasTag(JCTree.Tag.CLASSDEF)) {
JCClassDecl cdef = (JCClassDecl) frame.tree;
if (cdef.sym == csym) {
return true;
}
}
}
return false;
}
/**
* Method references to local class constructors, may, if the local
......@@ -1756,6 +1770,11 @@ public class LambdaToMethod extends TreeTranslator {
List<JCVariableDecl> syntheticParams;
/**
* to prevent recursion, track local classes processed
*/
final Set<Symbol> freeVarProcessedLocalClasses;
LambdaTranslationContext(JCLambda tree) {
super(tree);
Frame frame = frameStack.head;
......@@ -1785,6 +1804,8 @@ public class LambdaToMethod extends TreeTranslator {
translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>());
translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
freeVarProcessedLocalClasses = new HashSet<>();
}
/**
......@@ -1895,7 +1916,7 @@ public class LambdaToMethod extends TreeTranslator {
};
break;
case LOCAL_VAR:
ret = new VarSymbol(sym.flags() & FINAL, name, types.erasure(sym.type), translatedSym);
ret = new VarSymbol(sym.flags() & FINAL, name, sym.type, translatedSym);
((VarSymbol) ret).pos = ((VarSymbol) sym).pos;
break;
case PARAM:
......
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -2360,6 +2360,7 @@ public class Lower extends TreeTranslator {
/** Visitor method: Translate a single node.
* Attach the source position from the old tree to its replacement tree.
*/
@Override
public <T extends JCTree> T translate(T tree) {
if (tree == null) {
return null;
......
......@@ -565,7 +565,7 @@ public class Resolve {
tvars,
(MethodType)mt,
resultInfo,
m,
(MethodSymbol)m,
argtypes,
allowBoxing,
useVarargs,
......@@ -773,6 +773,7 @@ public class Resolve {
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
return nilMethodCheck;
}
}
/**
......@@ -784,6 +785,11 @@ public class Resolve {
void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
//do nothing - actual always compatible to formals
}
@Override
public String toString() {
return "arityMethodCheck";
}
};
List<Type> dummyArgs(int length) {
......@@ -869,6 +875,11 @@ public class Resolve {
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
return new MostSpecificCheck(strict, actuals);
}
@Override
public String toString() {
return "resolveMethodCheck";
}
};
/**
......@@ -900,7 +911,9 @@ public class Resolve {
@Override
public boolean compatible(Type found, Type req, Warner warn) {
found = pendingInferenceContext.asUndetVar(found);
req = infer.returnConstraintTarget(found, req);
if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
req = types.boxedClass(req).type;
}
return super.compatible(found, req, warn);
}
......@@ -955,6 +968,12 @@ public class Resolve {
public DeferredAttrContext deferredAttrContext() {
return deferredAttrContext;
}
@Override
public String toString() {
return "MethodReferenceCheck";
}
}
/**
......@@ -973,7 +992,12 @@ public class Resolve {
DeferredType dt = (DeferredType)found;
return dt.check(this);
} else {
return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType()))));
Type uResult = U(found.baseType());
Type capturedType = pos == null || pos.getTree() == null ?
types.capture(uResult) :
checkContext.inferenceContext()
.cachedCapture(pos.getTree(), uResult, true);
return super.check(pos, chk.checkNonVoid(pos, capturedType));
}
}
......@@ -1500,14 +1524,22 @@ public class Resolve {
if (m2SignatureMoreSpecific) return m2;
return ambiguityError(m1, m2);
case AMBIGUOUS:
//check if m1 is more specific than all ambiguous methods in m2
//compare m1 to ambiguous methods in m2
AmbiguityError e = (AmbiguityError)m2.baseSymbol();
boolean m1MoreSpecificThanAnyAmbiguous = true;
boolean allAmbiguousMoreSpecificThanM1 = true;
for (Symbol s : e.ambiguousSyms) {
if (mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs) != m1) {
return e.addAmbiguousSymbol(m1);
}
Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs);
m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
}
return m1;
if (m1MoreSpecificThanAnyAmbiguous)
return m1;
//if m1 is more specific than some ambiguous methods, but other ambiguous methods are
//more specific than m1, add it as a new ambiguous method:
if (!allAmbiguousMoreSpecificThanM1)
e.addAmbiguousSymbol(m1);
return e;
default:
throw new AssertionError();
}
......@@ -1525,7 +1557,7 @@ public class Resolve {
currentResolutionContext.methodCheck =
prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing);
Type mst = instantiate(env, site, m2, null,
adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
allowBoxing, useVarargs, noteWarner);
return mst != null &&
!noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
......
......@@ -512,14 +512,14 @@ public class ClassReader {
break;
case CONSTANT_Fieldref: {
ClassSymbol owner = readClassSymbol(getChar(index + 1));
NameAndType nt = (NameAndType)readPool(getChar(index + 3));
NameAndType nt = readNameAndType(getChar(index + 3));
poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner);
break;
}
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref: {
ClassSymbol owner = readClassSymbol(getChar(index + 1));
NameAndType nt = (NameAndType)readPool(getChar(index + 3));
NameAndType nt = readNameAndType(getChar(index + 3));
poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner);
break;
}
......@@ -588,13 +588,34 @@ public class ClassReader {
/** Read class entry.
*/
ClassSymbol readClassSymbol(int i) {
return (ClassSymbol) (readPool(i));
Object obj = readPool(i);
if (obj != null && !(obj instanceof ClassSymbol))
throw badClassFile("bad.const.pool.entry",
currentClassFile.toString(),
"CONSTANT_Class_info", i);
return (ClassSymbol)obj;
}
/** Read name.
*/
Name readName(int i) {
return (Name) (readPool(i));
Object obj = readPool(i);
if (obj != null && !(obj instanceof Name))
throw badClassFile("bad.const.pool.entry",
currentClassFile.toString(),
"CONSTANT_Utf8_info or CONSTANT_String_info", i);
return (Name)obj;
}
/** Read name and type.
*/
NameAndType readNameAndType(int i) {
Object obj = readPool(i);
if (obj != null && !(obj instanceof NameAndType))
throw badClassFile("bad.const.pool.entry",
currentClassFile.toString(),
"CONSTANT_NameAndType_info", i);
return (NameAndType)obj;
}
/************************************************************************
......@@ -1245,7 +1266,7 @@ public class ClassReader {
sym.owner.members().remove(sym);
ClassSymbol self = (ClassSymbol)sym;
ClassSymbol c = readClassSymbol(nextChar());
NameAndType nt = (NameAndType)readPool(nextChar());
NameAndType nt = readNameAndType(nextChar());
if (c.members_field == null)
throw badClassFile("bad.enclosing.class", self, c);
......
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -2818,7 +2818,7 @@ public class Gen extends JCTree.Visitor {
}
private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
super(new LVTBits(), syms, names);
super(new LVTBits(), syms, names, false);
lvtInits = (LVTBits)inits;
this.lvtRanges = lvtRanges;
}
......
......@@ -35,9 +35,6 @@ import java.util.MissingResourceException;
import java.util.Queue;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
......@@ -1304,11 +1301,16 @@ public class JavaCompiler {
* Perform dataflow checks on an attributed parse tree.
*/
protected void flow(Env<AttrContext> env, Queue<Env<AttrContext>> results) {
if (compileStates.isDone(env, CompileState.FLOW)) {
results.add(env);
return;
}
try {
if (shouldStop(CompileState.FLOW))
return;
if (relax || compileStates.isDone(env, CompileState.FLOW)) {
if (relax) {
results.add(env);
return;
}
......
......@@ -3406,16 +3406,28 @@ public class JavacParser implements Parser {
* | ModifiersOpt
* ( Type Ident
* ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
* | VOID Ident MethodDeclaratorRest
* | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
* | VOID Ident VoidMethodDeclaratorRest
* | TypeParameters [Annotations]
* ( Type Ident MethodDeclaratorRest
* | VOID Ident VoidMethodDeclaratorRest
* )
* | Ident ConstructorDeclaratorRest
* | TypeParameters Ident ConstructorDeclaratorRest
* | ClassOrInterfaceOrEnumDeclaration
* )
* InterfaceBodyDeclaration =
* ";"
* | ModifiersOpt Type Ident
* ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
* | ModifiersOpt
* ( Type Ident
* ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
* | VOID Ident MethodDeclaratorRest
* | TypeParameters [Annotations]
* ( Type Ident MethodDeclaratorRest
* | VOID Ident VoidMethodDeclaratorRest
* )
* | ClassOrInterfaceOrEnumDeclaration
* )
*
*/
protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
if (token.kind == SEMI) {
......@@ -3444,28 +3456,29 @@ public class JavacParser implements Parser {
}
List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
if (annosAfterParams.nonEmpty()) {
checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
mods.annotations = mods.annotations.appendList(annosAfterParams);
if (mods.pos == Position.NOPOS)
mods.pos = mods.annotations.head.pos;
}
Token tk = token;
pos = token.pos;
JCExpression type;
boolean isVoid = token.kind == VOID;
if (isVoid) {
if (annosAfterParams.nonEmpty())
illegal(annosAfterParams.head.pos);
type = to(F.at(pos).TypeIdent(TypeTag.VOID));
nextToken();
} else {
if (annosAfterParams.nonEmpty()) {
checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
mods.annotations = mods.annotations.appendList(annosAfterParams);
if (mods.pos == Position.NOPOS)
mods.pos = mods.annotations.head.pos;
}
// method returns types are un-annotated types
type = unannotatedType();
}
if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
if (isInterface || tk.name() != className)
error(pos, "invalid.meth.decl.ret.type.req");
else if (annosAfterParams.nonEmpty())
illegal(annosAfterParams.head.pos);
return List.of(methodDeclaratorRest(
pos, mods, null, names.init, typarams,
isInterface, true, dc));
......@@ -3497,13 +3510,9 @@ public class JavacParser implements Parser {
}
/** MethodDeclaratorRest =
* FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
* FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
* VoidMethodDeclaratorRest =
* FormalParameters [Throws TypeList] ( MethodBody | ";")
* InterfaceMethodDeclaratorRest =
* FormalParameters BracketsOpt [THROWS TypeList] ";"
* VoidInterfaceMethodDeclaratorRest =
* FormalParameters [THROWS TypeList] ";"
* FormalParameters [THROWS TypeList] ( MethodBody | ";")
* ConstructorDeclaratorRest =
* "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
*/
......
#
# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -735,6 +735,9 @@ compiler.misc.incompatible.ret.type.in.mref=\
bad return type in method reference\n\
{0}
compiler.err.lambda.body.neither.value.nor.void.compatible=\
lambda body is neither value nor void compatible
# 0: list of type
compiler.err.incompatible.thrown.types.in.mref=\
incompatible thrown types {0} in method reference
......@@ -1702,6 +1705,11 @@ compiler.err.cant.access=\
cannot access {0}\n\
{1}
# 0: file name, 1: expected CP entry type, 2: constant pool index
compiler.misc.bad.const.pool.entry=\
bad constant pool entry in {0}\n\
expected {1} at index {2}
# 0: file name, 1: message segment
compiler.misc.bad.class.file.header=\
bad class file: {0}\n\
......
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -56,9 +56,9 @@ public class TreeTranslator extends JCTree.Visitor {
return null;
} else {
tree.accept(this);
JCTree result = this.result;
JCTree tmpResult = this.result;
this.result = null;
return (T)result; // XXX cast
return (T)tmpResult; // XXX cast
}
}
......
/*
* @test /nodynamiccopyright/
* @bug 8039026
* @summary Definitely unassigned field can be accessed
* @compile/fail/ref=T8039026.out -XDrawDiagnostics T8039026.java
*/
public class T8039026 {
final int x,y,z;
final int a = this.y; // <- error
{
int b = true ? this.x : 0; // <- error
System.out.println(this.x); // <- error
this.y = 1;
}
T8039026() {
this.x = 1; // <- no error!
this.y = 1; // <- error
this.z = this.x; // <- no error
}
}
T8039026.java:10:23: compiler.err.var.might.not.have.been.initialized: y
T8039026.java:12:28: compiler.err.var.might.not.have.been.initialized: x
T8039026.java:18:13: compiler.err.var.might.already.be.assigned: y
3 errors
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8038788
* @summary Verify proper handling of annotations after method's type parameters.
* @build AfterMethodTypeParams
* @run main AfterMethodTypeParams
*/
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.*;
import javax.lang.model.element.Name;
import javax.tools.*;
import com.sun.source.tree.*;
import com.sun.source.util.*;
public class AfterMethodTypeParams {
public static void main(String... args) throws IOException {
new AfterMethodTypeParams().run();
}
void run() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
for (TestCase tc : testCases) {
String test = TEMPLATE.replace("CONTENT", tc.snippet);
List<JavaFileObject> files = Arrays.asList(new MyFileObject(test));
StringWriter out = new StringWriter();
List<String> options = Arrays.asList("-XDrawDiagnostics", "-XDshouldStopPolicy=FLOW");
JavacTask task = (JavacTask) compiler.getTask(out, null, null, options, null, files);
new TreePathScanner<Void, Void>() {
boolean seenAnnotation;
@Override
public Void visitAnnotation(AnnotationTree node, Void p) {
Name name = ((IdentifierTree) node.getAnnotationType()).getName();
seenAnnotation |= name.contentEquals("TA") || name.contentEquals("DA");
return null;
}
@Override
public Void visitCompilationUnit(CompilationUnitTree node, Void p) {
super.visitCompilationUnit(node, p);
if (!seenAnnotation)
error(test, "Annotation was missing");
return null;
}
}.scan(task.parse(), null);
task.analyze();
if (!tc.error.equals(out.toString().trim())) {
error(test, "Incorrect errors: " + out.toString());
}
}
if (errors > 0) {
throw new IllegalStateException("Errors found");
}
}
int errors;
void error(String code, String error) {
System.out.println("Error detected: " + error);
System.out.println("Code:");
System.out.println(code);
errors++;
}
static String TEMPLATE =
"import java.lang.annotation.*;\n" +
"public class Test {\n" +
" CONTENT\n" +
"}\n" +
"@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})\n" +
"@interface DA { }\n" +
"@Target(ElementType.TYPE_USE)\n" +
"@interface TA { }\n";
static class MyFileObject extends SimpleJavaFileObject {
final String text;
public MyFileObject(String text) {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
this.text = text;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return text;
}
}
static TestCase[] testCases = new TestCase[] {
new TestCase("<T> @DA int foo1() { return 0;}", ""),
new TestCase("<T> @DA void foo2() { }", ""),
new TestCase("<T> @TA int foo3() { return 0;}", ""),
new TestCase("<T> @TA void foo4() { }",
"Test.java:3:9: compiler.err.annotation.type.not.applicable"),
new TestCase("<T> @DA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"),
new TestCase("<T> @TA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"),
};
static class TestCase {
final String snippet;
final String error;
public TestCase(String snippet, String error) {
this.snippet = snippet;
this.error = error;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8040822
* @summary Check that all TaskEvents are balanced.
*/
import java.io.*;
import java.net.URI;
import java.util.*;
import java.util.Map.Entry;
import javax.tools.*;
import com.sun.source.util.*;
import com.sun.source.util.TaskEvent.Kind;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.comp.CompileStates.CompileState;
public class EventsBalancedTest {
JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
public static void main(String... args) throws IOException {
new EventsBalancedTest().test();
}
void test() throws IOException {
TestSource a = new TestSource("B", "class B extends A { }");
TestSource b = new TestSource("A", "abstract class A { }");
test(null, Arrays.asList(a, b));
test(null, Arrays.asList(b, a));
test(Arrays.asList("-XD-relax"), Arrays.asList(a, b));
test(Arrays.asList("-XD-relax"), Arrays.asList(b, a));
for (CompileState stop : CompileState.values()) {
test(Arrays.asList("-XDshouldStopPolicyIfNoError=" + stop,
"-XDshouldStopPolicyIfError=" + stop),
Arrays.asList(a, b));
test(Arrays.asList("-XDshouldStopPolicyIfNoError=" + stop,
"-XDshouldStopPolicyIfError=" + stop),
Arrays.asList(b, a));
}
}
void test(Iterable<String> options, Iterable<JavaFileObject> files) throws IOException {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
TestListener listener = new TestListener();
JavacTask task = tool.getTask(pw, fm, null, options, null, files);
task.setTaskListener(listener);
task.call();
for (Entry<Kind, Integer> e : listener.kind2Count.entrySet()) {
if (e.getValue() != null && e.getValue() != 0) {
throw new IllegalStateException("Not balanced event: " + e.getKey());
}
}
}
static class TestListener implements TaskListener {
final Map<Kind, Integer> kind2Count = new HashMap<>();
int get(Kind k) {
Integer count = kind2Count.get(k);
if (count == null)
kind2Count.put(k, count = 0);
return count;
}
@Override
public void started(TaskEvent e) {
kind2Count.put(e.getKind(), get(e.getKind()) + 1);
}
@Override
public void finished(TaskEvent e) {
int count = get(e.getKind());
if (count <= 0)
throw new IllegalStateException("count<=0 for: " + e.getKind());
kind2Count.put(e.getKind(), count - 1);
}
}
static class TestSource extends SimpleJavaFileObject {
final String content;
public TestSource(String fileName, String content) {
super(URI.create("myfo:/" + fileName + ".java"), JavaFileObject.Kind.SOURCE);
this.content = content;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return content;
}
}
}
......@@ -41,7 +41,7 @@ public class SyntheticClasses {
private void run() throws IOException, ConstantPoolException {
File testClasses = new File(System.getProperty("test.classes"));
for (File classFile : testClasses.listFiles()) {
for (File classFile : testClasses.listFiles(f -> f.getName().endsWith(".class"))) {
ClassFile cf = ClassFile.read(classFile);
if (cf.getName().matches(".*\\$[0-9]+")) {
EnclosingMethod_attribute encl =
......
......@@ -111,3 +111,4 @@ compiler.warn.unknown.enum.constant # in bad class file
compiler.warn.unknown.enum.constant.reason # in bad class file
compiler.warn.override.equals.but.not.hashcode # when a class overrides equals but not hashCode method from Object
compiler.err.cant.inherit.from.anon # error for subclass of anonymous class
compiler.misc.bad.const.pool.entry # constant pool entry has wrong type
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// key: compiler.err.lambda.body.neither.value.nor.void.compatible
// key: compiler.err.cant.apply.symbol
// key: compiler.misc.incompatible.ret.type.in.lambda
// key: compiler.misc.missing.ret.val
// key: compiler.misc.no.conforming.assignment.exists
class LambdaBodyNeitherValueNorVoidCompatible {
interface I {
String f(String x);
}
static void foo(I i) {}
void m() {
foo((x) -> {
if (x == null) {
return;
} else {
return x;
}
});
}
}
T7086586.java:14:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List<? super T>, java.util.List<compiler.misc.type.captureof: 1, ?>, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List<compiler.misc.type.captureof: 1, ?>, java.util.List<? super T>))
T7086586.java:15:20: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List<? super T>, java.util.List<compiler.misc.type.captureof: 1, ?>, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List<compiler.misc.type.captureof: 1, ?>, java.util.List<? super T>))
T7086586.java:16:23: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List<? super T>, java.util.List<compiler.misc.type.captureof: 1, ?>, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List<compiler.misc.type.captureof: 1, ?>, java.util.List<? super T>))
T7086586.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, java.util.List<? super T>, java.util.List<compiler.misc.type.captureof: 1, ?>, kindname.class, T7086586, (compiler.misc.infer.no.conforming.assignment.exists: T, (compiler.misc.inconvertible.types: java.util.List<compiler.misc.type.captureof: 1, ?>, java.util.List<? super T>))
T7086586.java:14:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.String)
T7086586.java:15:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Number)
T7086586.java:16:31: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.captureof: 1, ?, java.lang.Exception)
T7086586.java:17:13: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location: kindname.interface, java.util.List<compiler.misc.type.captureof: 1, ?>, null)
4 errors
......@@ -23,9 +23,10 @@
/*
* @test
* @bug 7086586
* @bug 7086586 8033718
*
* @summary Inference producing null type argument
* @summary Inference producing null type argument; inference ignores capture
* variable as upper bound
*/
import java.util.List;
......@@ -40,8 +41,8 @@ public class T7086586b {
assertionCount++;
}
<T> void m(List<? super T> dummy) { assertTrue(false); }
<T> void m(Object dummy) { assertTrue(true); }
<T> void m(List<? super T> dummy) { assertTrue(true); }
<T> void m(Object dummy) { assertTrue(false); }
void test(List<?> l) {
m(l);
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8033718
* @author dlsmith
* @summary GLB for two capture variables with lower bounds
* @compile LowerBoundGLB.java
*/
public class LowerBoundGLB {
interface Box<T> {
T get();
void set(T arg);
}
<T> T doGLB(Box<? super T> b1, Box<? super T> b2) {
return null;
}
void test(Box<? super String> l1, Box<? super CharSequence> l2) {
doGLB(l1, l2).substring(3);
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8042656
* @summary Subtyping for intersection types containing type variables
* @compile IntersectionSubVar.java
*/
class IntersectionSubVar {
interface Box<T> {
void set(T arg);
T get();
}
<I> Box<I> glb(Box<? super I> arg1, Box<? super I> arg2) {
return null;
}
<E extends Cloneable> void takeBox(Box<? super E> box) {}
<T> void test(Box<T> arg1, Box<Cloneable> arg2, Box<? super T> arg3) {
T t = glb(arg1, arg2).get(); // assign T&Cloneable to T
takeBox(arg3); // inference tests Box<CAP> <: Box<? super CAP&Cloneable>
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile EagerReturnTypeResolutionTesta.java
*/
public class EagerReturnTypeResolutionTesta {
abstract class Test1<T>{
abstract <S> S foo(S x, S y);
<S extends Number & Comparable<? extends Number>> void baz(Test1<S> a){}
void bar(Test1<Long> x, Test1<Integer> y){
baz(foo(x, y));
}
}
abstract class Test2<T>{
abstract <S> S foo(S x, S y);
abstract <S1> void baz(Test2<S1> a);
void bar(Test2<Integer> y, Test2<Long> x){
baz(foo(x, y));
}
}
abstract class Test3<T>{
abstract <S> S foo(S x, S y);
<T extends Number & Comparable<?>,
S extends Number & Comparable<? extends T>> void baz(Test3<S> a){}
void bar(Test3<Long> x, Test3<Integer> y){
baz(foo(x, y));
}
}
abstract class Test4 {
abstract class A0<T> {}
abstract class A1<T> extends A0<T> {}
abstract class A2<T> extends A0<T> {}
abstract <S> S foo(S x, S y);
abstract <S1> void baz(A0<S1> a);
void bar(A2<Integer> y, A1<Long> x){
baz(foo(x, y));
}
}
}
/*
* @test /nodynamiccopyright/
* @bug 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile/fail/ref=EagerReturnTypeResolutionTestb.out -XDrawDiagnostics EagerReturnTypeResolutionTestb.java
* @author Dan Smith
*/
import java.util.List;
public class EagerReturnTypeResolutionTestb {
interface I<S> {}
interface J<S> extends I<S> {}
interface K extends I<String> {}
interface L<S> extends I {}
<T> T lower(List<? extends T> l) { return null; }
<T> T lower2(List<? extends T> l1, List<? extends T> l2) { return null; }
<T> T upper(List<? super T> l) { return null; }
<T> T upper2(List<? super T> l1, List<? super T> l2) { return null; }
<T> T eq(List<T> l) { return null; }
<T> T eq2(List<T> l1, List<T> l2) { return null; }
<X> void takeI(I<X> i) {}
void takeIString(I<String> i) {}
I<String> iStringField;
void takeLong(long arg) {}
long longField;
void testSimpleCaptureOK(List<I<?>> i1) {
takeI(lower(i1)); // ok*
takeI(eq(i1)); // ok*
takeI(upper(i1)); // ok, no capture
takeIString(upper(i1)); // ok
iStringField = upper(i1); // ok
}
void testSimpleCaptureKO(List<I<?>> i1) {
takeIString(lower(i1)); // ERROR
takeIString(eq(i1)); // ERROR
iStringField = lower(i1); // ERROR
iStringField = eq(i1); // ERROR
}
void testMultiCaptureOK(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
/* Lines marked with JDK-8029002 should be uncommented once this bug is
* fixed
*/
takeI(lower2(i1, i2)); // ok*
takeI(lower2(i1, i3)); // ok*
takeI(upper2(i1, i3)); // ok, no capture* JDK-8029002
takeIString(upper2(i1, i3)); // ok, no capture
iStringField = upper2(i1, i3); // ok, no capture
takeI(lower2(j1, j2)); // ok*
takeI(lower2(j1, k1)); // ok, no capture
takeI(upper2(j1, k1)); // ok, no capture* JDK-8029002
takeIString(lower2(j1, k1)); // ok, no capture
takeIString(upper2(j1, k1)); // ok, no capture
iStringField = lower2(j1, k1); // ok, no capture
iStringField = upper2(j1, k1); // ok, no capture
takeI(lower2(j2, k1)); // ok*
}
void testMultiCaptureKO(List<I<String>> i1, List<I<Integer>> i2, List<I<?>> i3,
List<J<String>> j1, List<J<Integer>> j2, List<K> k1) {
takeI(eq2(i1, i2)); // ERROR, bad bounds
takeI(upper2(i1, i2)); // ERROR, bad bounds
takeIString(lower2(i1, i2)); // ERROR
takeIString(eq2(i1, i2)); // ERROR, bad bounds
takeIString(upper2(i1, i2)); // ERROR, bad bounds
iStringField = lower2(i1, i2); // ERROR
iStringField = eq2(i1, i2); // ERROR, bad bounds
iStringField = upper2(i1, i2); // ERROR, bad bounds
takeI(eq2(i1, i3)); // ERROR, bad bounds
takeIString(lower2(i1, i3)); // ERROR
takeIString(eq2(i1, i3)); // ERROR, bad bounds
iStringField = lower2(i1, i3); // ERROR
iStringField = eq2(i1, i3); // ERROR, bad bounds
takeI(eq2(j1, j2)); // ERROR, bad bounds
takeI(upper2(j1, j2)); // ERROR, bad bounds
takeIString(lower2(j1, j2)); // ERROR
takeIString(eq2(j1, j2)); // ERROR, bad bounds
takeIString(upper2(j1, j2)); // ERROR, bad bounds
iStringField = lower2(j1, j2); // ERROR
iStringField = eq2(j1, j2); // ERROR, bad bounds
iStringField = upper2(j1, j2); // ERROR, bad bounds
takeI(eq2(j1, k1)); // ERROR, bad bounds
takeIString(eq2(j1, k1)); // ERROR, bad bounds
iStringField = eq2(j1, k1); // ERROR, bad bounds
takeI(eq2(j2, k1)); // ERROR, bad bounds
takeI(upper2(j2, k1)); // ERROR, bad bounds; actual: no error, see JDK-8037474
takeIString(lower2(j2, k1)); // ERROR
takeIString(eq2(j2, k1)); // ERROR, bad bounds
takeIString(upper2(j2, k1)); // ERROR, bad bounds
iStringField = lower2(j2, k1); // ERROR
iStringField = eq2(j2, k1); // ERROR, bad bounds
iStringField = upper2(j2, k1); // ERROR, bad bounds
}
void testRawOK(List<I> i1, List<J> j1, List<L<String>> l1) {
takeI(lower(i1)); // ok, unchecked
takeI(eq(i1)); // ok, unchecked
takeI(upper(i1)); // ok, no capture, not unchecked
takeIString(lower(i1)); // ok, unchecked
takeIString(eq(i1)); // ok, unchecked
takeIString(upper(i1)); // ok, no capture, not unchecked
iStringField = lower(i1); // ok, unchecked
iStringField = eq(i1); // ok, unchecked
iStringField = upper(i1); // ok, no capture, not unchecked
takeI(lower(j1)); // ok, unchecked
takeI(eq(j1)); // ok, unchecked
takeI(upper(j1)); // bad bounds? -- spec is unclear
takeIString(lower(j1)); // ok, unchecked
takeIString(eq(j1)); // ok, unchecked
takeIString(upper(j1)); // bad bounds? -- spec is unclear
iStringField = lower(j1); // ok, unchecked
iStringField = eq(j1); // ok, unchecked
iStringField = upper(j1); // bad bounds? -- spec is unclear
takeI(lower(l1)); // ok, unchecked
takeI(eq(l1)); // ok, unchecked
takeI(upper(l1)); // bad bounds? -- spec is unclear
takeIString(lower(l1)); // ok, unchecked
takeIString(eq(l1)); // ok, unchecked
takeIString(upper(l1)); // bad bounds? -- spec is unclear
iStringField = lower(l1); // ok, unchecked
iStringField = eq(l1); // ok, unchecked
iStringField = upper(l1); // bad bounds? -- spec is unclear
}
void testPrimOK(List<Integer> i1, List<Long> l1, List<Double> d1) {
takeLong(lower(i1)); // ok
takeLong(eq(i1)); // ok
takeLong(upper(i1)); // ok*
longField = lower(i1); // ok
longField = eq(i1); // ok
longField = upper(i1); // ok*
takeLong(lower(l1)); // ok
takeLong(eq(l1)); // ok
takeLong(upper(l1)); // ok
longField = lower(l1); // ok
longField = eq(l1); // ok
longField = upper(l1); // ok
}
void testPrimKO(List<Integer> i1, List<Long> l1, List<Double> d1) {
takeLong(lower(d1)); // ERROR
takeLong(eq(d1)); // ERROR
takeLong(upper(d1)); // ERROR
longField = lower(d1); // ERROR
longField = eq(d1); // ERROR
longField = upper(d1); // ERROR
}
}
EagerReturnTypeResolutionTestb.java:42:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:43:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:44:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:45:26: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:74:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:75:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:77:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:78:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:79:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:81:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:82:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:83:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<java.lang.Integer>, EagerReturnTypeResolutionTestb.I<java.lang.Integer>,EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:85:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:86:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ?>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:87:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:89:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:90:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.I<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.I<?>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.I<?>, EagerReturnTypeResolutionTestb.I<?>,EagerReturnTypeResolutionTestb.I<java.lang.String>)
EagerReturnTypeResolutionTestb.java:91:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:92:15: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:94:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.J<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:95:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:96:21: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:98:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:99:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:100:24: compiler.err.cant.apply.symbol: kindname.method, upper2, java.util.List<? super T>,java.util.List<? super T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.J<java.lang.Integer>, EagerReturnTypeResolutionTestb.J<java.lang.Integer>,EagerReturnTypeResolutionTestb.J<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:102:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:103:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:104:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.String>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.String>)
EagerReturnTypeResolutionTestb.java:105:15: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:106:9: compiler.err.cant.apply.symbol: kindname.method, takeI, EagerReturnTypeResolutionTestb.I<X>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Integer, java.lang.Integer,java.lang.String)
EagerReturnTypeResolutionTestb.java:108:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, EagerReturnTypeResolutionTestb.I<compiler.misc.type.captureof: 1, ? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:109:21: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:110:9: compiler.err.cant.apply.symbol: kindname.method, takeIString, EagerReturnTypeResolutionTestb.I<java.lang.String>, java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object))
EagerReturnTypeResolutionTestb.java:112:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: EagerReturnTypeResolutionTestb.I<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>>, EagerReturnTypeResolutionTestb.I<java.lang.String>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:113:24: compiler.err.cant.apply.symbol: kindname.method, eq2, java.util.List<T>,java.util.List<T>, java.util.List<EagerReturnTypeResolutionTestb.J<java.lang.Integer>>,java.util.List<EagerReturnTypeResolutionTestb.K>, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.inferred.do.not.conform.to.eq.bounds: EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>)
EagerReturnTypeResolutionTestb.java:114:30: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object&EagerReturnTypeResolutionTestb.J<java.lang.Integer>&EagerReturnTypeResolutionTestb.K, EagerReturnTypeResolutionTestb.I<java.lang.String>,EagerReturnTypeResolutionTestb.K,EagerReturnTypeResolutionTestb.J<java.lang.Integer>,java.lang.Object)
EagerReturnTypeResolutionTestb.java:174:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:175:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:176:9: compiler.err.cant.apply.symbol: kindname.method, takeLong, long, java.lang.Double, kindname.class, EagerReturnTypeResolutionTestb, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.instance.exists: , T, long))
EagerReturnTypeResolutionTestb.java:178:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
EagerReturnTypeResolutionTestb.java:179:23: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
EagerReturnTypeResolutionTestb.java:180:26: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: , T, long)
- compiler.note.unchecked.filename: EagerReturnTypeResolutionTestb.java
- compiler.note.unchecked.recompile
42 errors
/*
* @test /nodynamiccopyright/
* @bug 8030741
* @summary Inference: implement eager resolution of return types, consistent with JDK-8028800
* @compile/fail/ref=PrimitiveTypeBoxingTest.out -XDrawDiagnostics PrimitiveTypeBoxingTest.java
*/
public class PrimitiveTypeBoxingTest {
static void foo(long arg) {}
static void bar(int arg) {}
interface F<X> { void get(X arg); }
<Z> void m1(F<Z> f, Z arg) {}
<Z> void m2(Z arg, F<Z> f) {}
void test() {
m1(PrimitiveTypeBoxingTest::foo, 23); // expected: error
m2(23, PrimitiveTypeBoxingTest::foo); // expected: error
m1(PrimitiveTypeBoxingTest::bar, 23); // expected: success
m2(23, PrimitiveTypeBoxingTest::bar); // expected: success
}
}
PrimitiveTypeBoxingTest.java:19:9: compiler.err.cant.apply.symbol: kindname.method, m1, PrimitiveTypeBoxingTest.F<Z>,Z, @490,int, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
PrimitiveTypeBoxingTest.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m2, Z,PrimitiveTypeBoxingTest.F<Z>, int,@559, kindname.class, PrimitiveTypeBoxingTest, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.Long,java.lang.Object)
2 errors
ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1<T>), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr
1 error
/*
* Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,16 +26,16 @@
* @bug 8003280
* @summary Add lambda tests
* stale state after speculative attribution round leads to missing classfiles
* @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java
*/
public class ErroneousLambdaExpr<T> {
public class LambdaExprLeadsToMissingClassFilesTest<T> {
static int assertionCount = 0;
static void assertTrue(boolean cond) {
assertionCount++;
if (!cond)
if (!cond) {
throw new AssertionError();
}
}
interface SAM1<X> {
......@@ -57,8 +57,8 @@ public class ErroneousLambdaExpr<T> {
void call(SAM3<T> s3) { assertTrue(false); }
public static void main(String[] args) {
ErroneousLambdaExpr<StringBuilder> test =
new ErroneousLambdaExpr<>();
LambdaExprLeadsToMissingClassFilesTest<StringBuilder> test =
new LambdaExprLeadsToMissingClassFilesTest<>();
test.call((builder, string) -> { builder.append(string); return builder; });
assertTrue(assertionCount == 1);
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8029725
* @summary Lambda reference to containing local class causes javac infinite recursion
* @author Robert Field
* @run main LambdaLocalTest
*/
public class LambdaLocalTest {
interface F {void f();}
static F f;
static StringBuffer sb = new StringBuffer();
static void assertEquals(Object val, Object expected) {
if (!val.equals(expected)) {
throw new AssertionError("expected '" + expected + "' got '" + val + "'");
}
}
public static void main(String[] args) {
class Local {
public Local() {
f = () -> new Local();
sb.append("+");
}
}
new Local();
f.f();
assertEquals(sb.toString(), "++");
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8036942
* @summary javac generates incorrect exception table for multi-catch statements inside a lambda
* @run main LambdaMultiCatchTest
*/
import java.io.IOException;
import java.util.function.Function;
public class LambdaMultiCatchTest {
public static void main(String[] args) {
Function<String,String> fi = x -> {
String result = "nada";
try {
switch (x) {
case "IO": throw new IOException();
case "Illegal": throw new IllegalArgumentException();
case "Run": throw new RuntimeException();
}
} catch (IOException|IllegalArgumentException ex) {
result = "IO/Illegal";
} catch (Exception ex) {
result = "Any";
};
return result;
};
String val = fi.apply("Run");
if (!val.equals("Any")) {
throw new AssertionError("Fail: Expected 'Any' but got '" + val + "'");
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8029725
* @summary Lambda reference to containing local class causes javac infinite recursion
* @author Robert Field
* @run main LambdaOuterLocalTest
*/
public class LambdaOuterLocalTest {
interface F {void f();}
static F f;
static StringBuffer sb = new StringBuffer();
static void assertEquals(Object val, Object expected) {
if (!val.equals(expected)) {
throw new AssertionError("expected '" + expected + "' got '" + val + "'");
}
}
public static void main(String[] args) {
class Local1 {
public Local1() {
class Local2 {
public Local2() {
f = () -> new Local1();
sb.append("2");
}
}
sb.append("1");
new Local2();
}
}
new Local1();
f.f();
assertEquals(sb.toString(), "1212");
}
}
/*
* @test /nodynamiccopyright/
* @bug 8029718
* @summary Should always use lambda body structure to disambiguate overload resolution
* @compile/fail/ref=MostSpecific09.out -XDrawDiagnostics -XDshouldStopPolicy=ATTR -XDverboseResolution=applicable,success MostSpecific09.java
*/
class MostSpecific09 {
interface I {
String xoo(String x);
}
interface J {
void xoo(int x);
}
static void foo(I i) {}
static void foo(J j) {}
static void moo(I i) {}
static void moo(J j) {}
void m() {
foo((x) -> { return x += 1; });
foo((x) -> { return ""; });
foo((x) -> { System.out.println(""); });
foo((x) -> { return ""; System.out.println(""); });
foo((x) -> { throw new RuntimeException(); });
foo((x) -> { while (true); });
foo((x) -> x += 1);
foo((x) -> "");
}
/* any return statement that is not in the body of the lambda but in an
* inner class or another lambda should be ignored for value void compatibility
* determination.
*/
void m1() {
boolean cond = true;
foo((x) -> {
if (cond) {
return "";
}
System.out.println("");
});
foo((x)->{
class Bar {
String m() {
return "from Bar.m()";
}
}
class Boo {
Bar b = new Bar (){
String m() {
return "from Bar$1.m()";
}
};
}
moo((y) -> { return ""; });
return;
});
foo((x)->{
class Bar {
void m() {}
}
class Boo {
Bar b = new Bar (){
void m() {
return;
}
};
}
moo((y) -> { System.out.println(""); });
return "";
});
}
}
MostSpecific09.java:25:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
MostSpecific09.java:26:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
MostSpecific09.java:27:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)}
MostSpecific09.java:27:32: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
MostSpecific09.java:28:13: compiler.err.lambda.body.neither.value.nor.void.compatible
MostSpecific09.java:28:9: compiler.err.cant.apply.symbols: kindname.method, foo, @680,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))}
MostSpecific09.java:28:43: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
MostSpecific09.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
MostSpecific09.java:29:28: compiler.note.verbose.resolve.multi: <init>, java.lang.RuntimeException, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, java.lang.RuntimeException(), null)}
MostSpecific09.java:30:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
MostSpecific09.java:32:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
MostSpecific09.java:33:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
MostSpecific09.java:42:13: compiler.err.lambda.body.neither.value.nor.void.compatible
MostSpecific09.java:42:9: compiler.err.cant.apply.symbols: kindname.method, foo, @1129,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))}
MostSpecific09.java:46:23: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
MostSpecific09.java:49:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)}
MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: <init>, Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)}
MostSpecific09.java:56:35: compiler.note.verbose.resolve.multi: <init>, Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)}
MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: <init>, compiler.misc.anonymous.class: MostSpecific09$1Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$1Boo$1(), null)}
MostSpecific09.java:62:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.I), null)}
MostSpecific09.java:66:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: <init>, Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)}
MostSpecific09.java:71:35: compiler.note.verbose.resolve.multi: <init>, Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)}
MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: <init>, compiler.misc.anonymous.class: MostSpecific09$2Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$2Boo$1(), null)}
MostSpecific09.java:77:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.J), null)}
MostSpecific09.java:77:36: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
7 errors
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8029852
* @summary Bad code generated (VerifyError) when lambda instantiates
* enclosing local class and has captured variables
*/
public class SingleLocalTest {
interface F {void f();}
static F f;
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
class Local1 {
public Local1() {
f = () -> new Local1();
sb.append("1");
}
}
new Local1();
f.f();
String s = sb.toString();
if (!s.equals("11")) {
throw new AssertionError("Expected '11' got '" + s + "'");
}
}
}
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -42,6 +42,10 @@ class TargetType01 {
static String M(F_S_S f){ return null; }
static {
M(x1 -> { return M( x2 -> { return x1 + x2; });}); //ambiguous
M(x1 -> {
return M( x2 -> {
return x1 + x2;
});
}); //ambiguous
}
}
TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
TargetType01.java:45:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
TargetType01.java:46:20: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
2 errors
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8003280
* @test /nodynamiccopyright/
* @bug 8003280 8029718
* @summary Add lambda tests
* check overload resolution and target type inference w.r.t. generic methods
* Should always use lambda body structure to disambiguate overload resolution
* @author Maurizio Cimadamore
* @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java
*/
......@@ -47,9 +25,18 @@ public class TargetType02 {
static <Z extends Number> void call3(S1<Z> s) { }
static <Z extends String> void call3(S2<Z> s) { }
static <Z extends Number> Z call4(S1<Z> s) { return null; }
static <Z extends String> Z call4(S2<Z> s) { return null; }
void test() {
call1(i -> { toString(); return i; });
call2(i -> { toString(); return i; });
call3(i -> { toString(); return i; });
call3(i -> {
toString();
return call4(j -> {
return j;
});
});
}
}
TargetType02.java:52:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String)
TargetType02.java:53:9: compiler.err.ref.ambiguous: call3, kindname.method, <Z>call3(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call3(TargetType02.S2<Z>), TargetType02
2 errors
TargetType02.java:33:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String)
TargetType02.java:34:9: compiler.err.ref.ambiguous: call3, kindname.method, <Z>call3(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call3(TargetType02.S2<Z>), TargetType02
TargetType02.java:35:9: compiler.err.ref.ambiguous: call3, kindname.method, <Z>call3(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call3(TargetType02.S2<Z>), TargetType02
TargetType02.java:37:20: compiler.err.ref.ambiguous: call4, kindname.method, <Z>call4(TargetType02.S1<Z>), TargetType02, kindname.method, <Z>call4(TargetType02.S2<Z>), TargetType02
4 errors
TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
TargetType21.java:33:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @946, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))
6 errors
TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM1, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))
TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, <R,A>call(TargetType21.SAM3<R,A>), TargetType21
4 errors
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -31,12 +31,18 @@
class TargetType42 {
interface SAM<X, Y> {
Y f(X x);
Y f(X x);
}
<Z> void m(SAM<String, SAM<Z, Object>> s, Z z) { }
void test(Object obj) {
m((x)->{ class Foo { }; return (x2)-> { new Foo(); return null; }; }, obj);
m((x)->{
class Foo { }
return (x2)-> {
new Foo();
return null;
};
}, obj);
}
}
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -33,7 +33,6 @@
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
public class LambdaTest1 {
......
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -209,7 +209,11 @@ public class SamConversionComboTest {
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
DiagnosticChecker dc = new DiagnosticChecker();
JavacTask ct = (JavacTask)tool.getTask(null, null, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
ct.analyze();
try {
ct.analyze();
} catch (Exception e) {
throw new AssertionError("failing SAM source file \n" + samSourceFile + "\n\n" + "failing client source file \n"+ clientSourceFile);
}
if (dc.errorFound == checkSamConversion()) {
throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile);
}
......
ErroneousAnnotations.java:8:2: compiler.err.cant.resolve: kindname.class, Undefined, ,
ErroneousAnnotations.java:10:6: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, ErroneousAnnotations, null)
2 errors
Results: []
......@@ -93,7 +93,8 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
roundEnvironment.
getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName()));
System.err.println("Results: " + resultsMeta);
if (!resultsMeta.isEmpty())
System.err.println("Results: " + resultsMeta);
if (resultsMeta.size() != annotatedElementInfo.expectedSize()) {
failed = true;
......
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8041663
*/
public class AmbiguityErrorTest {
public interface A { }
public interface B extends A { }
public interface C {
A m(B strategy);
}
public interface D {
A m(A strategy);
A m(B strategy);
}
public interface T1 extends C, D { }
public interface T2 extends D, C { }
int count;
class T1Impl implements T1, T2 {
public A m(B strategy) {
count++;
return null;
}
public A m(A strategy) {
throw new AssertionError("Should not get here.");
}
}
public static void main(String... args) {
new AmbiguityErrorTest().test();
}
void test() {
T1 t1 = new T1Impl();
T2 t2 = new T1Impl();
final B b = new B() { };
t1.m(b);
t2.m(b);
if (count != 2) {
throw new IllegalStateException("Did not call the methods properly");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册