mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-01 05:58:29 +00:00
Merge
This commit is contained in:
commit
c7e591cc26
@ -1146,29 +1146,6 @@ public class Type implements PrimitiveType {
|
||||
return types.subst(qtype, tvars, actuals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kind of type-constraint derived during type inference
|
||||
*/
|
||||
public enum ConstraintKind {
|
||||
/**
|
||||
* upper bound constraint (a type variable must be instantiated
|
||||
* with a type T, where T is a subtype of all the types specified by
|
||||
* its EXTENDS constraints).
|
||||
*/
|
||||
EXTENDS,
|
||||
/**
|
||||
* lower bound constraint (a type variable must be instantiated
|
||||
* with a type T, where T is a supertype of all the types specified by
|
||||
* its SUPER constraints).
|
||||
*/
|
||||
SUPER,
|
||||
/**
|
||||
* equality constraint (a type variable must be instantiated to the type
|
||||
* specified by its EQUAL constraint.
|
||||
*/
|
||||
EQUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type-constraints of a given kind for a given type-variable of
|
||||
* this ForAll type. Subclasses should override in order to return more
|
||||
@ -1178,7 +1155,7 @@ public class Type implements PrimitiveType {
|
||||
* @param ck the constraint kind to be retrieved
|
||||
* @return the list of types specified by the selected constraint
|
||||
*/
|
||||
public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
public List<Type> undetvars() {
|
||||
return List.nil();
|
||||
}
|
||||
|
||||
@ -1220,6 +1197,7 @@ public class Type implements PrimitiveType {
|
||||
public static class UndetVar extends DelegatedType {
|
||||
public List<Type> lobounds = List.nil();
|
||||
public List<Type> hibounds = List.nil();
|
||||
public List<Type> eq = List.nil();
|
||||
public Type inst = null;
|
||||
|
||||
@Override
|
||||
|
||||
@ -326,11 +326,6 @@ public class Types {
|
||||
else if (t.tag == TYPEVAR) {
|
||||
return isSubtypeUnchecked(t.getUpperBound(), s, warn);
|
||||
}
|
||||
else if (s.tag == UNDETVAR) {
|
||||
UndetVar uv = (UndetVar)s;
|
||||
if (uv.inst != null)
|
||||
return isSubtypeUnchecked(t, uv.inst, warn);
|
||||
}
|
||||
else if (!s.isRaw()) {
|
||||
Type t2 = asSuper(t, s.tsym);
|
||||
if (t2 != null && t2.isRaw()) {
|
||||
@ -515,9 +510,6 @@ public class Types {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.inst != null)
|
||||
return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
|
||||
|
||||
t.hibounds = t.hibounds.prepend(s);
|
||||
return true;
|
||||
}
|
||||
@ -586,8 +578,6 @@ public class Types {
|
||||
undet.qtype == s ||
|
||||
s.tag == ERROR ||
|
||||
s.tag == BOT) return true;
|
||||
if (undet.inst != null)
|
||||
return isSubtype(s, undet.inst);
|
||||
undet.lobounds = undet.lobounds.prepend(s);
|
||||
return true;
|
||||
}
|
||||
@ -733,18 +723,8 @@ public class Types {
|
||||
if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
|
||||
return true;
|
||||
|
||||
if (t.inst != null)
|
||||
return visit(t.inst, s);
|
||||
t.eq = t.eq.prepend(s);
|
||||
|
||||
t.inst = fromUnknownFun.apply(s);
|
||||
for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
|
||||
if (!isSubtype(l.head, t.inst))
|
||||
return false;
|
||||
}
|
||||
for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
|
||||
if (!isSubtype(t.inst, l.head))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -779,23 +759,11 @@ public class Types {
|
||||
case UNBOUND: //similar to ? extends Object
|
||||
case EXTENDS: {
|
||||
Type bound = upperBound(s);
|
||||
// We should check the new upper bound against any of the
|
||||
// undetvar's lower bounds.
|
||||
for (Type t2 : undetvar.lobounds) {
|
||||
if (!isSubtype(t2, bound))
|
||||
return false;
|
||||
}
|
||||
undetvar.hibounds = undetvar.hibounds.prepend(bound);
|
||||
break;
|
||||
}
|
||||
case SUPER: {
|
||||
Type bound = lowerBound(s);
|
||||
// We should check the new lower bound against any of the
|
||||
// undetvar's lower bounds.
|
||||
for (Type t2 : undetvar.hibounds) {
|
||||
if (!isSubtype(bound, t2))
|
||||
return false;
|
||||
}
|
||||
undetvar.lobounds = undetvar.lobounds.prepend(bound);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -32,7 +32,6 @@ import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
|
||||
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
|
||||
@ -122,84 +121,21 @@ public class Infer {
|
||||
|
||||
/** A mapping that turns type variables into undetermined type variables.
|
||||
*/
|
||||
Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
|
||||
public Type apply(Type t) {
|
||||
if (t.tag == TYPEVAR) return new UndetVar(t);
|
||||
else return t.map(this);
|
||||
}
|
||||
};
|
||||
|
||||
/** A mapping that returns its type argument with every UndetVar replaced
|
||||
* by its `inst' field. Throws a NoInstanceException
|
||||
* if this not possible because an `inst' field is null.
|
||||
* Note: mutually referring undertvars will be left uninstantiated
|
||||
* (that is, they will be replaced by the underlying type-variable).
|
||||
*/
|
||||
|
||||
Mapping getInstFun = new Mapping("getInstFun") {
|
||||
public Type apply(Type t) {
|
||||
switch (t.tag) {
|
||||
case UNKNOWN:
|
||||
throw ambiguousNoInstanceException
|
||||
.setMessage("undetermined.type");
|
||||
case UNDETVAR:
|
||||
UndetVar that = (UndetVar) t;
|
||||
if (that.inst == null)
|
||||
throw ambiguousNoInstanceException
|
||||
.setMessage("type.variable.has.undetermined.type",
|
||||
that.qtype);
|
||||
return isConstraintCyclic(that) ?
|
||||
that.qtype :
|
||||
apply(that.inst);
|
||||
default:
|
||||
return t.map(this);
|
||||
List<Type> makeUndetvars(List<Type> tvars) {
|
||||
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
uv.hibounds = types.getBounds((TypeVar)uv.qtype);
|
||||
}
|
||||
return undetvars;
|
||||
}
|
||||
//where
|
||||
Mapping fromTypeVarFun = new Mapping("fromTypeVarFun") {
|
||||
public Type apply(Type t) {
|
||||
if (t.tag == TYPEVAR) return new UndetVar(t);
|
||||
else return t.map(this);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isConstraintCyclic(UndetVar uv) {
|
||||
Types.UnaryVisitor<Boolean> constraintScanner =
|
||||
new Types.UnaryVisitor<Boolean>() {
|
||||
|
||||
List<Type> seen = List.nil();
|
||||
|
||||
Boolean visit(List<Type> ts) {
|
||||
for (Type t : ts) {
|
||||
if (visit(t)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitType(Type t, Void ignored) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitClassType(ClassType t, Void ignored) {
|
||||
if (t.isCompound()) {
|
||||
return visit(types.supertype(t)) ||
|
||||
visit(types.interfaces(t));
|
||||
} else {
|
||||
return visit(t.getTypeArguments());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Boolean visitWildcardType(WildcardType t, Void ignored) {
|
||||
return visit(t.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitUndetVar(UndetVar t, Void ignored) {
|
||||
if (seen.contains(t)) {
|
||||
return true;
|
||||
} else {
|
||||
seen = seen.prepend(t);
|
||||
return visit(t.inst);
|
||||
}
|
||||
}
|
||||
};
|
||||
return constraintScanner.visit(uv);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Mini/Maximization of UndetVars
|
||||
@ -210,13 +146,15 @@ public class Infer {
|
||||
*/
|
||||
void maximizeInst(UndetVar that, Warner warn) throws NoInstanceException {
|
||||
List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
|
||||
if (that.inst == null) {
|
||||
if (that.eq.isEmpty()) {
|
||||
if (hibounds.isEmpty())
|
||||
that.inst = syms.objectType;
|
||||
else if (hibounds.tail.isEmpty())
|
||||
that.inst = hibounds.head;
|
||||
else
|
||||
that.inst = types.glb(hibounds);
|
||||
} else {
|
||||
that.inst = that.eq.head;
|
||||
}
|
||||
if (that.inst == null ||
|
||||
that.inst.isErroneous())
|
||||
@ -224,27 +162,6 @@ public class Infer {
|
||||
.setMessage("no.unique.maximal.instance.exists",
|
||||
that.qtype, hibounds);
|
||||
}
|
||||
//where
|
||||
private boolean isSubClass(Type t, final List<Type> ts) {
|
||||
t = t.baseType();
|
||||
if (t.tag == TYPEVAR) {
|
||||
List<Type> bounds = types.getBounds((TypeVar)t);
|
||||
for (Type s : ts) {
|
||||
if (!types.isSameType(t, s.baseType())) {
|
||||
for (Type bound : bounds) {
|
||||
if (!isSubClass(bound, List.of(s.baseType())))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Type s : ts) {
|
||||
if (!t.tsym.isSubClass(s.baseType().tsym, types))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Filter<Type> errorFilter = new Filter<Type>() {
|
||||
@Override
|
||||
@ -258,7 +175,7 @@ public class Infer {
|
||||
*/
|
||||
void minimizeInst(UndetVar that, Warner warn) throws NoInstanceException {
|
||||
List<Type> lobounds = Type.filter(that.lobounds, errorFilter);
|
||||
if (that.inst == null) {
|
||||
if (that.eq.isEmpty()) {
|
||||
if (lobounds.isEmpty())
|
||||
that.inst = syms.botType;
|
||||
else if (lobounds.tail.isEmpty())
|
||||
@ -270,21 +187,8 @@ public class Infer {
|
||||
throw ambiguousNoInstanceException
|
||||
.setMessage("no.unique.minimal.instance.exists",
|
||||
that.qtype, lobounds);
|
||||
// VGJ: sort of inlined maximizeInst() below. Adding
|
||||
// bounds can cause lobounds that are above hibounds.
|
||||
List<Type> hibounds = Type.filter(that.hibounds, errorFilter);
|
||||
Type hb = null;
|
||||
if (hibounds.isEmpty())
|
||||
hb = syms.objectType;
|
||||
else if (hibounds.tail.isEmpty())
|
||||
hb = hibounds.head;
|
||||
else
|
||||
hb = types.glb(hibounds);
|
||||
if (hb == null ||
|
||||
hb.isErroneous())
|
||||
throw ambiguousNoInstanceException
|
||||
.setMessage("incompatible.upper.bounds",
|
||||
that.qtype, hibounds);
|
||||
} else {
|
||||
that.inst = that.eq.head;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,21 +217,7 @@ public class Infer {
|
||||
public Type instantiateExpr(ForAll that,
|
||||
Type to,
|
||||
Warner warn) throws InferenceException {
|
||||
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
|
||||
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
|
||||
UndetVar uv = (UndetVar) l.head;
|
||||
TypeVar tv = (TypeVar)uv.qtype;
|
||||
ListBuffer<Type> hibounds = new ListBuffer<Type>();
|
||||
for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS)) {
|
||||
hibounds.append(types.subst(t, that.tvars, undetvars));
|
||||
}
|
||||
|
||||
List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL);
|
||||
if (inst.nonEmpty() && inst.head.tag != BOT) {
|
||||
uv.inst = inst.head;
|
||||
}
|
||||
uv.hibounds = hibounds.toList();
|
||||
}
|
||||
List<Type> undetvars = that.undetvars();
|
||||
Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
|
||||
if (!types.isSubtype(qtype1,
|
||||
qtype1.tag == UNDETVAR ? types.boxedTypeOrType(to) : to)) {
|
||||
@ -335,41 +225,72 @@ public class Infer {
|
||||
.setMessage("infer.no.conforming.instance.exists",
|
||||
that.tvars, that.qtype, to);
|
||||
}
|
||||
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail)
|
||||
maximizeInst((UndetVar) l.head, warn);
|
||||
// System.out.println(" = " + qtype1.map(getInstFun));//DEBUG
|
||||
|
||||
// check bounds
|
||||
List<Type> targs = Type.map(undetvars, getInstFun);
|
||||
if (Type.containsAny(targs, that.tvars)) {
|
||||
//replace uninferred type-vars
|
||||
targs = types.subst(targs,
|
||||
List<Type> insttypes;
|
||||
while (true) {
|
||||
boolean stuck = true;
|
||||
insttypes = List.nil();
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
if (uv.inst == null && (uv.eq.nonEmpty() || !Type.containsAny(uv.hibounds, that.tvars))) {
|
||||
maximizeInst((UndetVar)t, warn);
|
||||
stuck = false;
|
||||
}
|
||||
insttypes = insttypes.append(uv.inst == null ? uv.qtype : uv.inst);
|
||||
}
|
||||
if (!Type.containsAny(insttypes, that.tvars)) {
|
||||
//all variables have been instantiated - exit
|
||||
break;
|
||||
} else if (stuck) {
|
||||
//some variables could not be instantiated because of cycles in
|
||||
//upper bounds - provide a (possibly recursive) default instantiation
|
||||
insttypes = types.subst(insttypes,
|
||||
that.tvars,
|
||||
instantiateAsUninferredVars(undetvars, that.tvars));
|
||||
break;
|
||||
} else {
|
||||
//some variables have been instantiated - replace newly instantiated
|
||||
//variables in remaining upper bounds and continue
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
uv.hibounds = types.subst(uv.hibounds, that.tvars, insttypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return that.inst(targs, types);
|
||||
return that.inst(insttypes, types);
|
||||
}
|
||||
//where
|
||||
|
||||
/**
|
||||
* Infer cyclic inference variables as described in 15.12.2.8.
|
||||
*/
|
||||
private List<Type> instantiateAsUninferredVars(List<Type> undetvars, List<Type> tvars) {
|
||||
Assert.check(undetvars.length() == tvars.length());
|
||||
ListBuffer<Type> new_targs = ListBuffer.lb();
|
||||
//step 1 - create synthetic captured vars
|
||||
ListBuffer<Type> insttypes = ListBuffer.lb();
|
||||
ListBuffer<Type> todo = ListBuffer.lb();
|
||||
//step 1 - create fresh tvars
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
Type newArg = new CapturedType(t.tsym.name, t.tsym, uv.inst, syms.botType, null);
|
||||
new_targs = new_targs.append(newArg);
|
||||
if (uv.inst == null) {
|
||||
TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
|
||||
fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.hibounds), null);
|
||||
todo.append(uv);
|
||||
uv.inst = fresh_tvar.type;
|
||||
}
|
||||
insttypes.append(uv.inst);
|
||||
}
|
||||
//step 2 - replace synthetic vars in their bounds
|
||||
//step 2 - replace fresh tvars in their bounds
|
||||
List<Type> formals = tvars;
|
||||
for (Type t : new_targs.toList()) {
|
||||
CapturedType ct = (CapturedType)t;
|
||||
ct.bound = types.subst(ct.bound, tvars, new_targs.toList());
|
||||
WildcardType wt = new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass);
|
||||
wt.bound = (TypeVar)formals.head;
|
||||
ct.wildcard = wt;
|
||||
for (Type t : todo) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
TypeVar ct = (TypeVar)uv.inst;
|
||||
ct.bound = types.glb(types.subst(types.getBounds(ct), tvars, insttypes.toList()));
|
||||
if (ct.bound.isErroneous()) {
|
||||
//report inference error if glb fails
|
||||
reportBoundError(uv, BoundErrorKind.BAD_UPPER);
|
||||
}
|
||||
formals = formals.tail;
|
||||
}
|
||||
return new_targs.toList();
|
||||
return insttypes.toList();
|
||||
}
|
||||
|
||||
/** Instantiate method type `mt' by finding instantiations of
|
||||
@ -384,7 +305,7 @@ public class Infer {
|
||||
final boolean useVarargs,
|
||||
final Warner warn) throws InferenceException {
|
||||
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
||||
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
||||
final List<Type> undetvars = makeUndetvars(tvars);
|
||||
|
||||
final List<Type> capturedArgs =
|
||||
rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(),
|
||||
@ -419,7 +340,7 @@ public class Infer {
|
||||
undettypes.append(uv.inst);
|
||||
}
|
||||
}
|
||||
checkWithinBounds(tvars, undettypes.toList(), warn);
|
||||
checkWithinBounds(tvars, undetvars, insttypes.toList(), warn);
|
||||
|
||||
mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
|
||||
|
||||
@ -430,18 +351,8 @@ public class Infer {
|
||||
final List<Type> all_tvars = tvars; //this is the wrong tvars
|
||||
return new UninferredMethodType(env.tree.pos(), msym, mt, restvars.toList()) {
|
||||
@Override
|
||||
List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
for (Type t : restundet.toList()) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
if (uv.qtype == tv) {
|
||||
switch (ck) {
|
||||
case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes));
|
||||
case SUPER: return uv.lobounds;
|
||||
case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
|
||||
}
|
||||
}
|
||||
}
|
||||
return List.nil();
|
||||
List<Type> undetvars() {
|
||||
return restundet.toList();
|
||||
}
|
||||
@Override
|
||||
void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
|
||||
@ -453,7 +364,7 @@ public class Infer {
|
||||
warn.clear();
|
||||
checkArgumentsAcceptable(env, capturedArgs, owntype.getParameterTypes(), allowBoxing, useVarargs, warn);
|
||||
// check that inferred bounds conform to their bounds
|
||||
checkWithinBounds(all_tvars,
|
||||
checkWithinBounds(all_tvars, undetvars,
|
||||
types.subst(inferredTypes, tvars, inferred), warn);
|
||||
qtype = chk.checkMethod(owntype, msym, env, TreeInfo.args(env.tree), capturedArgs, useVarargs, warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED));
|
||||
}
|
||||
@ -525,7 +436,7 @@ public class Infer {
|
||||
|
||||
abstract void instantiateReturnType(Type restype, List<Type> inferred, Types types);
|
||||
|
||||
abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
|
||||
abstract List<Type> undetvars();
|
||||
|
||||
class UninferredReturnType extends ForAll {
|
||||
public UninferredReturnType(List<Type> tvars, Type restype) {
|
||||
@ -541,8 +452,8 @@ public class Infer {
|
||||
return UninferredMethodType.this.qtype.getReturnType();
|
||||
}
|
||||
@Override
|
||||
public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
|
||||
return UninferredMethodType.this.getConstraints(tv, ck);
|
||||
public List<Type> undetvars() {
|
||||
return UninferredMethodType.this.undetvars();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -559,45 +470,96 @@ public class Infer {
|
||||
}
|
||||
}
|
||||
|
||||
/** Try to instantiate argument type `that' to given type `to'.
|
||||
* If this fails, try to insantiate `that' to `to' where
|
||||
* every occurrence of a type variable in `tvars' is replaced
|
||||
* by an unknown type.
|
||||
*/
|
||||
private Type instantiateArg(ForAll that,
|
||||
Type to,
|
||||
List<Type> tvars,
|
||||
Warner warn) throws InferenceException {
|
||||
List<Type> targs;
|
||||
try {
|
||||
return instantiateExpr(that, to, warn);
|
||||
} catch (NoInstanceException ex) {
|
||||
Type to1 = to;
|
||||
for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
|
||||
to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
|
||||
return instantiateExpr(that, to1, warn);
|
||||
}
|
||||
}
|
||||
|
||||
/** check that type parameters are within their bounds.
|
||||
*/
|
||||
void checkWithinBounds(List<Type> tvars,
|
||||
List<Type> arguments,
|
||||
Warner warn)
|
||||
List<Type> undetvars,
|
||||
List<Type> arguments,
|
||||
Warner warn)
|
||||
throws InvalidInstanceException {
|
||||
for (List<Type> tvs = tvars, args = arguments;
|
||||
tvs.nonEmpty();
|
||||
tvs = tvs.tail, args = args.tail) {
|
||||
if (args.head instanceof UndetVar ||
|
||||
tvars.head.getUpperBound().isErroneous()) continue;
|
||||
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
|
||||
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
|
||||
throw invalidInstanceException
|
||||
.setMessage("inferred.do.not.conform.to.bounds",
|
||||
args.head, bounds);
|
||||
List<Type> args = arguments;
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
uv.hibounds = types.subst(uv.hibounds, tvars, arguments);
|
||||
uv.lobounds = types.subst(uv.lobounds, tvars, arguments);
|
||||
uv.eq = types.subst(uv.eq, tvars, arguments);
|
||||
checkCompatibleUpperBounds(uv, tvars);
|
||||
if (args.head.tag != TYPEVAR || !args.head.containsAny(tvars)) {
|
||||
Type inst = args.head;
|
||||
for (Type u : uv.hibounds) {
|
||||
if (!types.isSubtypeUnchecked(inst, types.subst(u, tvars, undetvars), warn)) {
|
||||
reportBoundError(uv, BoundErrorKind.UPPER);
|
||||
}
|
||||
}
|
||||
for (Type l : uv.lobounds) {
|
||||
if (!types.isSubtypeUnchecked(types.subst(l, tvars, undetvars), inst, warn)) {
|
||||
reportBoundError(uv, BoundErrorKind.LOWER);
|
||||
}
|
||||
}
|
||||
for (Type e : uv.eq) {
|
||||
if (!types.isSameType(inst, types.subst(e, tvars, undetvars))) {
|
||||
reportBoundError(uv, BoundErrorKind.EQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
args = args.tail;
|
||||
}
|
||||
}
|
||||
|
||||
void checkCompatibleUpperBounds(UndetVar uv, List<Type> tvars) {
|
||||
// VGJ: sort of inlined maximizeInst() below. Adding
|
||||
// bounds can cause lobounds that are above hibounds.
|
||||
ListBuffer<Type> hiboundsNoVars = ListBuffer.lb();
|
||||
for (Type t : Type.filter(uv.hibounds, errorFilter)) {
|
||||
if (!t.containsAny(tvars)) {
|
||||
hiboundsNoVars.append(t);
|
||||
}
|
||||
}
|
||||
List<Type> hibounds = hiboundsNoVars.toList();
|
||||
Type hb = null;
|
||||
if (hibounds.isEmpty())
|
||||
hb = syms.objectType;
|
||||
else if (hibounds.tail.isEmpty())
|
||||
hb = hibounds.head;
|
||||
else
|
||||
hb = types.glb(hibounds);
|
||||
if (hb == null || hb.isErroneous())
|
||||
reportBoundError(uv, BoundErrorKind.BAD_UPPER);
|
||||
}
|
||||
|
||||
enum BoundErrorKind {
|
||||
BAD_UPPER() {
|
||||
@Override
|
||||
InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
|
||||
return ex.setMessage("incompatible.upper.bounds", uv.qtype, uv.hibounds);
|
||||
}
|
||||
},
|
||||
UPPER() {
|
||||
@Override
|
||||
InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
|
||||
return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst, uv.hibounds);
|
||||
}
|
||||
},
|
||||
LOWER() {
|
||||
@Override
|
||||
InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
|
||||
return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst, uv.lobounds);
|
||||
}
|
||||
},
|
||||
EQ() {
|
||||
@Override
|
||||
InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
|
||||
return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst, uv.eq);
|
||||
}
|
||||
};
|
||||
|
||||
abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
|
||||
}
|
||||
//where
|
||||
void reportBoundError(UndetVar uv, BoundErrorKind bk) {
|
||||
throw bk.setMessage(uv.inst == null ? ambiguousNoInstanceException : invalidInstanceException, uv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a synthetic method type corresponding to the requested polymorphic
|
||||
* method signature. The target return type is computed from the immediately
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2012, 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
|
||||
@ -1798,92 +1798,126 @@ public class JavacParser implements Parser {
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
List<JCStatement> blockStatements() {
|
||||
//todo: skip to anchor on error(?)
|
||||
int lastErrPos = -1;
|
||||
//todo: skip to anchor on error(?)
|
||||
ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
|
||||
while (true) {
|
||||
int pos = token.pos;
|
||||
switch (token.kind) {
|
||||
case RBRACE: case CASE: case DEFAULT: case EOF:
|
||||
List<JCStatement> stat = blockStatement();
|
||||
if (stat.isEmpty()) {
|
||||
return stats.toList();
|
||||
case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
|
||||
case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
|
||||
case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
|
||||
stats.append(parseStatement());
|
||||
break;
|
||||
case MONKEYS_AT:
|
||||
case FINAL: {
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
JCModifiers mods = modifiersOpt();
|
||||
if (token.kind == INTERFACE ||
|
||||
token.kind == CLASS ||
|
||||
allowEnums && token.kind == ENUM) {
|
||||
stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
|
||||
} else {
|
||||
JCExpression t = parseType();
|
||||
stats.appendList(variableDeclarators(mods, t,
|
||||
new ListBuffer<JCStatement>()));
|
||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
||||
storeEnd(stats.elems.last(), token.endPos);
|
||||
accept(SEMI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ABSTRACT: case STRICTFP: {
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
JCModifiers mods = modifiersOpt();
|
||||
stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
|
||||
break;
|
||||
}
|
||||
case INTERFACE:
|
||||
case CLASS:
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
||||
break;
|
||||
case ENUM:
|
||||
case ASSERT:
|
||||
if (allowEnums && token.kind == ENUM) {
|
||||
error(token.pos, "local.enum");
|
||||
dc = token.comment(CommentStyle.JAVADOC);
|
||||
stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
||||
break;
|
||||
} else if (allowAsserts && token.kind == ASSERT) {
|
||||
stats.append(parseStatement());
|
||||
break;
|
||||
}
|
||||
/* fall through to default */
|
||||
default:
|
||||
Token prevToken = token;
|
||||
JCExpression t = term(EXPR | TYPE);
|
||||
if (token.kind == COLON && t.hasTag(IDENT)) {
|
||||
nextToken();
|
||||
JCStatement stat = parseStatement();
|
||||
stats.append(F.at(pos).Labelled(prevToken.name(), stat));
|
||||
} else if ((lastmode & TYPE) != 0 &&
|
||||
(token.kind == IDENTIFIER ||
|
||||
token.kind == ASSERT ||
|
||||
token.kind == ENUM)) {
|
||||
pos = token.pos;
|
||||
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
|
||||
F.at(pos);
|
||||
stats.appendList(variableDeclarators(mods, t,
|
||||
new ListBuffer<JCStatement>()));
|
||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
||||
storeEnd(stats.elems.last(), token.endPos);
|
||||
accept(SEMI);
|
||||
} else {
|
||||
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
|
||||
stats.append(to(F.at(pos).Exec(checkExprStat(t))));
|
||||
accept(SEMI);
|
||||
} else {
|
||||
if (token.pos <= endPosTable.errorEndPos) {
|
||||
skip(false, true, true, true);
|
||||
}
|
||||
stats.addAll(stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// error recovery
|
||||
if (token.pos == lastErrPos)
|
||||
/*
|
||||
* This method parses a statement treating it as a block, relaxing the
|
||||
* JLS restrictions, allows us to parse more faulty code, doing so
|
||||
* enables us to provide better and accurate diagnostics to the user.
|
||||
*/
|
||||
JCStatement parseStatementAsBlock() {
|
||||
int pos = token.pos;
|
||||
List<JCStatement> stats = blockStatement();
|
||||
if (stats.isEmpty()) {
|
||||
JCErroneous e = F.at(pos).Erroneous();
|
||||
error(e, "illegal.start.of.stmt");
|
||||
return F.at(pos).Exec(e);
|
||||
} else {
|
||||
JCStatement first = stats.head;
|
||||
String error = null;
|
||||
switch (first.getTag()) {
|
||||
case CLASSDEF:
|
||||
error = "class.not.allowed";
|
||||
break;
|
||||
case VARDEF:
|
||||
error = "variable.not.allowed";
|
||||
break;
|
||||
}
|
||||
if (error != null) {
|
||||
error(first, error);
|
||||
List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
|
||||
return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
|
||||
}
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
List<JCStatement> blockStatement() {
|
||||
//todo: skip to anchor on error(?)
|
||||
int pos = token.pos;
|
||||
switch (token.kind) {
|
||||
case RBRACE: case CASE: case DEFAULT: case EOF:
|
||||
return List.nil();
|
||||
case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
|
||||
case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
|
||||
case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
|
||||
return List.of(parseStatement());
|
||||
case MONKEYS_AT:
|
||||
case FINAL: {
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
JCModifiers mods = modifiersOpt();
|
||||
if (token.kind == INTERFACE ||
|
||||
token.kind == CLASS ||
|
||||
allowEnums && token.kind == ENUM) {
|
||||
return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
|
||||
} else {
|
||||
JCExpression t = parseType();
|
||||
ListBuffer<JCStatement> stats =
|
||||
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
|
||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
||||
storeEnd(stats.elems.last(), token.endPos);
|
||||
accept(SEMI);
|
||||
return stats.toList();
|
||||
if (token.pos <= endPosTable.errorEndPos) {
|
||||
skip(false, true, true, true);
|
||||
lastErrPos = token.pos;
|
||||
}
|
||||
}
|
||||
case ABSTRACT: case STRICTFP: {
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
JCModifiers mods = modifiersOpt();
|
||||
return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
|
||||
}
|
||||
case INTERFACE:
|
||||
case CLASS:
|
||||
String dc = token.comment(CommentStyle.JAVADOC);
|
||||
return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
||||
case ENUM:
|
||||
case ASSERT:
|
||||
if (allowEnums && token.kind == ENUM) {
|
||||
error(token.pos, "local.enum");
|
||||
dc = token.comment(CommentStyle.JAVADOC);
|
||||
return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
|
||||
} else if (allowAsserts && token.kind == ASSERT) {
|
||||
return List.of(parseStatement());
|
||||
}
|
||||
/* fall through to default */
|
||||
default:
|
||||
Token prevToken = token;
|
||||
JCExpression t = term(EXPR | TYPE);
|
||||
if (token.kind == COLON && t.hasTag(IDENT)) {
|
||||
nextToken();
|
||||
JCStatement stat = parseStatement();
|
||||
return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
|
||||
} else if ((lastmode & TYPE) != 0 &&
|
||||
(token.kind == IDENTIFIER ||
|
||||
token.kind == ASSERT ||
|
||||
token.kind == ENUM)) {
|
||||
pos = token.pos;
|
||||
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
|
||||
F.at(pos);
|
||||
ListBuffer<JCStatement> stats =
|
||||
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
|
||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
||||
storeEnd(stats.elems.last(), token.endPos);
|
||||
accept(SEMI);
|
||||
return stats.toList();
|
||||
} else {
|
||||
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
|
||||
JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
|
||||
accept(SEMI);
|
||||
return List.<JCStatement>of(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1917,11 +1951,11 @@ public class JavacParser implements Parser {
|
||||
case IF: {
|
||||
nextToken();
|
||||
JCExpression cond = parExpression();
|
||||
JCStatement thenpart = parseStatement();
|
||||
JCStatement thenpart = parseStatementAsBlock();
|
||||
JCStatement elsepart = null;
|
||||
if (token.kind == ELSE) {
|
||||
nextToken();
|
||||
elsepart = parseStatement();
|
||||
elsepart = parseStatementAsBlock();
|
||||
}
|
||||
return F.at(pos).If(cond, thenpart, elsepart);
|
||||
}
|
||||
@ -1938,7 +1972,7 @@ public class JavacParser implements Parser {
|
||||
accept(COLON);
|
||||
JCExpression expr = parseExpression();
|
||||
accept(RPAREN);
|
||||
JCStatement body = parseStatement();
|
||||
JCStatement body = parseStatementAsBlock();
|
||||
return F.at(pos).ForeachLoop(var, expr, body);
|
||||
} else {
|
||||
accept(SEMI);
|
||||
@ -1946,19 +1980,19 @@ public class JavacParser implements Parser {
|
||||
accept(SEMI);
|
||||
List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
|
||||
accept(RPAREN);
|
||||
JCStatement body = parseStatement();
|
||||
JCStatement body = parseStatementAsBlock();
|
||||
return F.at(pos).ForLoop(inits, cond, steps, body);
|
||||
}
|
||||
}
|
||||
case WHILE: {
|
||||
nextToken();
|
||||
JCExpression cond = parExpression();
|
||||
JCStatement body = parseStatement();
|
||||
JCStatement body = parseStatementAsBlock();
|
||||
return F.at(pos).WhileLoop(cond, body);
|
||||
}
|
||||
case DO: {
|
||||
nextToken();
|
||||
JCStatement body = parseStatement();
|
||||
JCStatement body = parseStatementAsBlock();
|
||||
accept(WHILE);
|
||||
JCExpression cond = parExpression();
|
||||
JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
|
||||
|
||||
@ -196,6 +196,9 @@ compiler.err.catch.without.try=\
|
||||
compiler.err.clash.with.pkg.of.same.name=\
|
||||
{0} {1} clashes with package of same name
|
||||
|
||||
compiler.err.class.not.allowed=\
|
||||
class, interface or enum declaration not allowed here
|
||||
|
||||
compiler.err.const.expr.req=\
|
||||
constant expression required
|
||||
|
||||
@ -385,6 +388,9 @@ compiler.err.illegal.qual.not.icls=\
|
||||
compiler.err.illegal.start.of.expr=\
|
||||
illegal start of expression
|
||||
|
||||
compiler.err.illegal.start.of.stmt=\
|
||||
illegal start of statement
|
||||
|
||||
compiler.err.illegal.start.of.type=\
|
||||
illegal start of type
|
||||
|
||||
@ -446,6 +452,9 @@ compiler.err.invalid.meth.decl.ret.type.req=\
|
||||
compiler.err.varargs.and.old.array.syntax=\
|
||||
legacy array notation not allowed on variable-arity parameter
|
||||
|
||||
compiler.err.variable.not.allowed=\
|
||||
variable declaration not allowed here
|
||||
|
||||
# 0: name
|
||||
compiler.err.label.already.in.use=\
|
||||
label {0} already in use
|
||||
@ -1574,9 +1583,6 @@ compiler.misc.undetermined.type=\
|
||||
cannot infer type arguments for {0}\n\
|
||||
reason: {1}
|
||||
|
||||
compiler.misc.type.variable.has.undetermined.type=\
|
||||
type variable {0} has undetermined type
|
||||
|
||||
# 0: type, 1: list of type
|
||||
compiler.misc.no.unique.maximal.instance.exists=\
|
||||
no unique maximal instance exists for type variable {0} with upper bounds {1}
|
||||
@ -1604,10 +1610,22 @@ compiler.misc.infer.varargs.argument.mismatch=\
|
||||
no instance(s) of type variable(s) {0} exist so that argument type {1} conforms to vararg element type {2}
|
||||
|
||||
# 0: type, 1: list of type
|
||||
compiler.misc.inferred.do.not.conform.to.bounds=\
|
||||
inferred type does not conform to declared bound(s)\n\
|
||||
compiler.misc.inferred.do.not.conform.to.upper.bounds=\
|
||||
inferred type does not conform to upper bound(s)\n\
|
||||
inferred: {0}\n\
|
||||
bound(s): {1}
|
||||
upper bound(s): {1}
|
||||
|
||||
# 0: type, 1: list of type
|
||||
compiler.misc.inferred.do.not.conform.to.lower.bounds=\
|
||||
inferred type does not conform to lower bound(s)\n\
|
||||
inferred: {0}\n\
|
||||
lower bound(s): {1}
|
||||
|
||||
# 0: type, 1: list of type
|
||||
compiler.misc.inferred.do.not.conform.to.eq.bounds=\
|
||||
inferred type does not conform to equality constraint(s)\n\
|
||||
inferred: {0}\n\
|
||||
equality constraints(s): {1}
|
||||
|
||||
# 0: symbol
|
||||
compiler.misc.diamond=\
|
||||
@ -2033,9 +2051,16 @@ compiler.misc.where.typevar=\
|
||||
|
||||
# compact where clause for type variable: contains the kindname ({2}) and location ({3})
|
||||
# in which the typevar has been declared
|
||||
# 0: type, 1: list of type, 2: symbol kind, 3: symbol
|
||||
compiler.misc.where.typevar.1=\
|
||||
{0} declared in {2} {3}
|
||||
|
||||
# where clause for fresh type variable: contains upper bound(s) ('extends {1}').
|
||||
# Since a fresh type-variable is synthetic - there's no location/kindname here.
|
||||
# 0: type, 1: list of type
|
||||
compiler.misc.where.fresh.typevar=\
|
||||
{0} extends {1}
|
||||
|
||||
# where clause for type variable: contains all the upper bound(s) ('extends {1}')
|
||||
# of this intersection type
|
||||
# 0: type, 1: list of type
|
||||
|
||||
@ -540,13 +540,22 @@ public class RichDiagnosticFormatter extends
|
||||
bounds.head.tag == NONE ||
|
||||
bounds.head.tag == ERROR;
|
||||
|
||||
|
||||
JCDiagnostic d = diags.fragment("where.typevar" +
|
||||
if ((t.tsym.flags() & SYNTHETIC) == 0) {
|
||||
//this is a true typevar
|
||||
JCDiagnostic d = diags.fragment("where.typevar" +
|
||||
(boundErroneous ? ".1" : ""), t, bounds,
|
||||
Kinds.kindName(t.tsym.location()), t.tsym.location());
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
symbolPreprocessor.visit(t.tsym.location(), null);
|
||||
visit(bounds);
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
symbolPreprocessor.visit(t.tsym.location(), null);
|
||||
visit(bounds);
|
||||
} else {
|
||||
Assert.check(!boundErroneous);
|
||||
//this is a fresh (synthetic) tvar
|
||||
JCDiagnostic d = diags.fragment("where.fresh.typevar", t, bounds);
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
visit(bounds);
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.type.captureof: 2, ? extends T6722234b>, List<T>)
|
||||
T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ? extends T6722234b, compiler.misc.type.captureof: 2, ? extends T6722234b,compiler.misc.type.captureof: 1, ? extends T6722234b)
|
||||
1 error
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, (compiler.misc.infer.no.conforming.assignment.exists: T, List<compiler.misc.captured.type: 2>, List<T>)
|
||||
T6722234b.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.captured.type: 2, compiler.misc.captured.type: 2,compiler.misc.captured.type: 1)
|
||||
- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, <T>m(List<T>,List<T>))}
|
||||
- compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)}
|
||||
1 error
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
|
||||
T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
|
||||
T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.no.conforming.assignment.exists: T, T6799605<compiler.misc.type.captureof: 2, ?>, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
|
||||
T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
|
||||
T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
|
||||
T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch))}
|
||||
3 errors
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
T7123100a.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), compiler.misc.type.captureof: 1, ?, Z
|
||||
T7123100a.java:14:19: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), E, Z
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
1 warning
|
||||
|
||||
149
langtools/test/tools/javac/classfiles/ClassVersionChecker.java
Normal file
149
langtools/test/tools/javac/classfiles/ClassVersionChecker.java
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 7157626
|
||||
* @summary Test major version for all legal combinations for -source and -target
|
||||
* @author sgoel
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
public class ClassVersionChecker {
|
||||
|
||||
int errors;
|
||||
String[] jdk = {"","1.2","1.3","1.4","1.5","1.6","1.7","1.8"};
|
||||
File javaFile = null;
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
new ClassVersionChecker().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
writeTestFile();
|
||||
/* Rules applicable for -source and -target combinations
|
||||
* 1. If both empty, version num is for 1.7
|
||||
* 2. If source is not empty and target is empty, version is based on source
|
||||
* 3. If both non-empty, version is based on target
|
||||
*/
|
||||
|
||||
/* -source (0=>empty,1=>1.2,...) X -target (0=>empty,1=>1.2,...)
|
||||
* ver[0][0] => no -source or -target was given
|
||||
* -1 => invalid combinations
|
||||
*/
|
||||
int[][] ver =
|
||||
{{51, -1, -1, -1, -1, -1, -1, -1},
|
||||
{48, 46, 47, 48, 49, 50, 51, 51},
|
||||
{48, 46, 47, 48, 49, 50, 51, 51},
|
||||
{48, -1, -1, 48, 49, 50, 51, 51},
|
||||
{51, -1, -1, -1, 49, 50, 51, 51},
|
||||
{51, -1, -1, -1, -1, 50, 51, 51},
|
||||
{51, -1, -1, -1, -1, -1, 51, 51},
|
||||
{51, -1, -1, -1, -1, -1, -1, 51}};
|
||||
|
||||
// Loop to run all possible combinations of source/target values
|
||||
for (int i = 0; i< ver.length; i++) {
|
||||
for (int j = 0 ; j< ver[i].length; j++) {
|
||||
if(ver[i][j] != -1) {
|
||||
logMsg("Index values for i = " + i + " j = " + j);
|
||||
logMsg("Running for src = " + jdk[i] + " target = "+jdk[j] +" expected = " + ver[i][j]);
|
||||
test(i,j, ver[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void test (int i, int j, int expected) {
|
||||
File classFile = compileTestFile(i, j, javaFile);
|
||||
short majorVer = getMajorVersion(classFile);
|
||||
checkVersion(majorVer, expected);
|
||||
}
|
||||
|
||||
void writeTestFile() throws IOException {
|
||||
javaFile = new File("Test.java");
|
||||
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(javaFile)));) {
|
||||
out.println("class Test { ");
|
||||
out.println(" public void foo() { }");
|
||||
out.println("}");
|
||||
} catch (IOException ioe) {
|
||||
error("IOException while creating Test.java" + ioe);
|
||||
}
|
||||
}
|
||||
|
||||
File compileTestFile(int i , int j, File f) {
|
||||
int rc = -1;
|
||||
// Src and target are empty
|
||||
if (i == 0 && j == 0 ) {
|
||||
rc = compile("-g", f.getPath());
|
||||
} else if( j == 0 ) { // target is empty
|
||||
rc = compile("-source", jdk[i], "-g", f.getPath());
|
||||
} else {
|
||||
rc = compile("-source", jdk[i], "-target", jdk[j], "-g", f.getPath());
|
||||
}
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
int compile(String... args) {
|
||||
return com.sun.tools.javac.Main.compile(args);
|
||||
}
|
||||
|
||||
void logMsg (String str) {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
short getMajorVersion(File f) {
|
||||
List<String> args = new ArrayList<String>();
|
||||
short majorVer = 0;
|
||||
try(DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));) {
|
||||
in.readInt();
|
||||
in.readShort();
|
||||
majorVer = in.readShort();
|
||||
System.out.println("major version:" + majorVer);
|
||||
} catch (IOException e) {
|
||||
error("IOException while reading Test.class" + e);
|
||||
}
|
||||
return majorVer;
|
||||
}
|
||||
|
||||
void checkVersion(short majorVer, int expected) {
|
||||
if (majorVer != expected ) {
|
||||
error("versions did not match, Expected: " + expected + "Got: " + majorVer);
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.out.println("error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,6 @@ compiler.misc.type.captureof
|
||||
compiler.misc.type.captureof.1
|
||||
compiler.misc.type.none
|
||||
compiler.misc.type.req.exact
|
||||
compiler.misc.type.variable.has.undetermined.type
|
||||
compiler.misc.unable.to.access.file # ClassFile
|
||||
compiler.misc.undecl.type.var # ClassReader
|
||||
compiler.misc.unicode.str.not.supported # ClassReader
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
// key: compiler.err.prob.found.req.1
|
||||
// key: compiler.misc.cant.apply.diamond.1
|
||||
// key: compiler.misc.infer.no.conforming.instance.exists
|
||||
// key: compiler.misc.no.conforming.assignment.exists
|
||||
// key: compiler.misc.diamond
|
||||
|
||||
class CantApplyDiamond1<X> {
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.illegal.start.of.stmt
|
||||
// key: compiler.err.expected3
|
||||
|
||||
class IllegalStartOfStmt {
|
||||
void m() {
|
||||
if (true) }
|
||||
}
|
||||
}
|
||||
@ -25,9 +25,9 @@
|
||||
// key: compiler.err.prob.found.req.1
|
||||
|
||||
class IncompatibleTypes1<V> {
|
||||
<T extends Integer & Runnable> IncompatibleTypes1<T> m() {
|
||||
<T> IncompatibleTypes1<Integer> m() {
|
||||
return null;
|
||||
}
|
||||
|
||||
IncompatibleTypes1<? super String> o = m();
|
||||
IncompatibleTypes1<? extends String> o = m();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -21,15 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
// key: compiler.misc.inferred.do.not.conform.to.bounds
|
||||
// key: compiler.err.cant.apply.diamond.1
|
||||
// key: compiler.misc.diamond
|
||||
// key: compiler.err.cant.apply.symbol.1
|
||||
// key: compiler.misc.infer.no.conforming.assignment.exists
|
||||
|
||||
class InferredDoNotConformToBounds {
|
||||
static class SuperFoo<X> {}
|
||||
static class Foo<X extends Number> extends SuperFoo<X> {
|
||||
Foo(X x) {}
|
||||
}
|
||||
import java.util.*;
|
||||
|
||||
SuperFoo<String> sf1 = new Foo<>("");
|
||||
class InferNoConformingAssignment {
|
||||
<X extends Number> List<X> m(String s) { return null; }
|
||||
{ this.m(1); }
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.cant.apply.symbol.1
|
||||
// key: compiler.misc.inferred.do.not.conform.to.eq.bounds
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class InferredDoNotConformToEq {
|
||||
<X> void m(List<X> lx1, List<X> lx2) {}
|
||||
{ this.m(Arrays.asList(""), Arrays.asList(1)); }
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.misc.invalid.inferred.types
|
||||
// key: compiler.err.prob.found.req.1
|
||||
// key: compiler.misc.inferred.do.not.conform.to.lower.bounds
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class InferredDoNotConformToLower {
|
||||
<X extends Number> List<X> m() { return null; }
|
||||
{ List<? super String> lss = this.m(); }
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.cant.apply.symbol.1
|
||||
// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class InferredDoNotConformToUpper {
|
||||
<X> void m(X x, List<? super X> lx) {}
|
||||
{ this.m("", Arrays.asList(1)); }
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2012, 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
|
||||
@ -23,17 +23,15 @@
|
||||
|
||||
// key: compiler.err.prob.found.req.1
|
||||
// key: compiler.misc.invalid.inferred.types
|
||||
// key: compiler.misc.inferred.do.not.conform.to.bounds
|
||||
// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class InvalidInferredTypes {
|
||||
|
||||
<T extends List<? super T>> T makeList() {
|
||||
return null;
|
||||
}
|
||||
<S extends String> List<S> m() { return null; }
|
||||
|
||||
public void test() {
|
||||
List<? super String> l = makeList();
|
||||
void test() {
|
||||
List<Integer> li = m();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.class.not.allowed
|
||||
|
||||
class NotAllowedClass {
|
||||
void t1() {
|
||||
if (true)
|
||||
class X {}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.variable.not.allowed
|
||||
|
||||
class NotAllowedVariable {
|
||||
void t1() {
|
||||
if (true)
|
||||
int x = 0;
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@
|
||||
// key: compiler.misc.where.description.typevar
|
||||
// key: compiler.misc.where.typevar
|
||||
// key: compiler.err.cant.apply.symbol.1
|
||||
// key: compiler.misc.infer.no.conforming.assignment.exists
|
||||
// key: compiler.misc.inferred.do.not.conform.to.eq.bounds
|
||||
// key: compiler.misc.captured.type
|
||||
// options: -XDdiags=where,simpleNames
|
||||
// run: simple
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
// key: compiler.misc.where.description.typevar
|
||||
// key: compiler.misc.where.typevar
|
||||
// key: compiler.err.cant.apply.symbol.1
|
||||
// key: compiler.misc.infer.no.conforming.assignment.exists
|
||||
// key: compiler.misc.inferred.do.not.conform.to.eq.bounds
|
||||
// key: compiler.misc.captured.type
|
||||
// key: compiler.misc.type.null
|
||||
// options: -XDdiags=where,simpleNames
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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.misc.where.fresh.typevar
|
||||
// key: compiler.misc.where.description.typevar.1
|
||||
// key: compiler.misc.where.typevar
|
||||
// key: compiler.misc.invalid.inferred.types
|
||||
// key: compiler.err.prob.found.req.1
|
||||
// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
|
||||
// options: -XDdiags=where,simpleNames
|
||||
// run: simple
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class WhereFreshTvar {
|
||||
<T extends List<T>> T m() {}
|
||||
|
||||
{ List<String> ls = m(); }
|
||||
}
|
||||
@ -1,2 +1,2 @@
|
||||
Neg06.java:16:37: compiler.err.prob.found.req.1: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.infer.no.conforming.instance.exists: X, Neg06.CFoo<X>, Neg06.CSuperFoo<java.lang.String>))
|
||||
Neg06.java:16:37: compiler.err.prob.found.req.1: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
Neg07.java:17:27: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg07.Foo), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.String, java.lang.Number)
|
||||
Neg07.java:17:27: compiler.err.cant.apply.diamond.1: (compiler.misc.diamond: Neg07.Foo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number)
|
||||
1 error
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
T6315770.java:16:42: compiler.err.prob.found.req.1: (compiler.misc.undetermined.type: <T>T6315770<T>, (compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable))
|
||||
T6315770.java:17:40: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T6315770<T>, T6315770<? super java.lang.String>)
|
||||
T6315770.java:17:40: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer&java.lang.Runnable, java.lang.String))
|
||||
2 errors
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S))}
|
||||
T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch))}
|
||||
T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
|
||||
T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.bounds: java.lang.Integer, S)
|
||||
T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))}
|
||||
T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch))}
|
||||
T6611449.java:20:9: compiler.err.cant.apply.symbol.1: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
|
||||
T6611449.java:21:9: compiler.err.cant.apply.symbol.1: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
|
||||
4 errors
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6638712b.java:14:21: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: T, T, java.lang.String)
|
||||
T6638712b.java:14:21: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String,java.lang.Object))
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.no.conforming.assignment.exists: int, java.lang.String)
|
||||
T6638712d.java:16:9: compiler.err.cant.apply.symbol.1: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.String, java.lang.Integer)
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6638712e.java:17:27: compiler.err.prob.found.req.1: (compiler.misc.infer.no.conforming.instance.exists: X, T6638712e.Foo<X,java.lang.String>, T6638712e.Foo<java.lang.Object,java.lang.String>)
|
||||
T6638712e.java:17:27: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: X, (compiler.misc.no.conforming.assignment.exists: T6638712e.Foo<java.lang.Boolean,java.lang.Boolean>, T6638712e.Foo<? super java.lang.Object,? extends java.lang.Boolean>))
|
||||
1 error
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
T6650759m.java:43:36: compiler.err.prob.found.req: java.util.List<? super java.lang.Integer>, java.util.List<? super java.lang.String>
|
||||
T6650759m.java:43:36: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: Z, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String))
|
||||
1 error
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String))}
|
||||
T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String))}
|
||||
T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String))}
|
||||
T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String))}
|
||||
T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
|
||||
T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
|
||||
T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
|
||||
T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
|
||||
4 errors
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 7154127
|
||||
* @summary Inference cleanup: remove bound check analysis from visitors in Types.java
|
||||
* @compile/fail/ref=T7154127.out -XDrawDiagnostics T7154127.java
|
||||
*/
|
||||
class T7154127 {
|
||||
|
||||
static class B<V> {}
|
||||
|
||||
static class D extends B<E> {}
|
||||
static class E extends B<D> {}
|
||||
|
||||
static class Triple<U,V,W> { }
|
||||
|
||||
static <T, Y extends B<U>, U extends B<Y>> Triple<T, Y, U> m() { return null; }
|
||||
|
||||
void test() {
|
||||
Triple<B, ? extends D, ? extends E> t = m();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
T7154127.java:19:49: compiler.err.prob.found.req.1: (compiler.misc.invalid.inferred.types: T,Y,U, (compiler.misc.inferred.do.not.conform.to.upper.bounds: Y, T7154127.D,T7154127.B<U>))
|
||||
1 error
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2012, 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
|
||||
@ -596,8 +596,8 @@ public class JavacParserTest extends TestCase {
|
||||
public void testVariableInIfThen3() throws IOException {
|
||||
|
||||
String code = "package t; class Test { "+
|
||||
"private static void t(String name) { " +
|
||||
"if (name != null) abstract } }";
|
||||
"private static void t() { " +
|
||||
"if (true) abstract class F {} }}";
|
||||
DiagnosticCollector<JavaFileObject> coll =
|
||||
new DiagnosticCollector<JavaFileObject>();
|
||||
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||
@ -612,7 +612,51 @@ public class JavacParserTest extends TestCase {
|
||||
}
|
||||
|
||||
assertEquals("testVariableInIfThen3",
|
||||
Arrays.<String>asList("compiler.err.illegal.start.of.expr"),
|
||||
Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
|
||||
}
|
||||
|
||||
public void testVariableInIfThen4() throws IOException {
|
||||
|
||||
String code = "package t; class Test { "+
|
||||
"private static void t(String name) { " +
|
||||
"if (name != null) interface X {} } }";
|
||||
DiagnosticCollector<JavaFileObject> coll =
|
||||
new DiagnosticCollector<JavaFileObject>();
|
||||
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||
null, Arrays.asList(new MyFileObject(code)));
|
||||
|
||||
ct.parse();
|
||||
|
||||
List<String> codes = new LinkedList<String>();
|
||||
|
||||
for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
|
||||
codes.add(d.getCode());
|
||||
}
|
||||
|
||||
assertEquals("testVariableInIfThen4",
|
||||
Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
|
||||
}
|
||||
|
||||
public void testVariableInIfThen5() throws IOException {
|
||||
|
||||
String code = "package t; class Test { "+
|
||||
"private static void t() { " +
|
||||
"if (true) } }";
|
||||
DiagnosticCollector<JavaFileObject> coll =
|
||||
new DiagnosticCollector<JavaFileObject>();
|
||||
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
|
||||
null, Arrays.asList(new MyFileObject(code)));
|
||||
|
||||
ct.parse();
|
||||
|
||||
List<String> codes = new LinkedList<String>();
|
||||
|
||||
for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
|
||||
codes.add(d.getCode());
|
||||
}
|
||||
|
||||
assertEquals("testVariableInIfThen5",
|
||||
Arrays.<String>asList("compiler.err.illegal.start.of.stmt"),
|
||||
codes);
|
||||
}
|
||||
|
||||
@ -808,8 +852,6 @@ public class JavacParserTest extends TestCase {
|
||||
testPositionBrokenSource126732b();
|
||||
|
||||
// Fails, these tests yet to be addressed
|
||||
testVariableInIfThen1();
|
||||
testVariableInIfThen2();
|
||||
testPositionForEnumModifiers();
|
||||
testStartPositionEnumConstantInit();
|
||||
}
|
||||
@ -821,7 +863,11 @@ public class JavacParserTest extends TestCase {
|
||||
testPreferredPositionForBinaryOp();
|
||||
testStartPositionForMethodWithoutModifiers();
|
||||
testVarPos();
|
||||
testVariableInIfThen1();
|
||||
testVariableInIfThen2();
|
||||
testVariableInIfThen3();
|
||||
testVariableInIfThen4();
|
||||
testVariableInIfThen5();
|
||||
testMissingExponent();
|
||||
testTryResourcePos();
|
||||
testOperatorMissingError();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user