This commit is contained in:
Lana Steuck 2015-03-19 16:13:40 -07:00
commit ff8f51808e
18 changed files with 507 additions and 151 deletions

View File

@ -31,10 +31,12 @@ import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import javax.lang.model.type.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Types.MapVisitor;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
import static com.sun.tools.javac.code.BoundKind.*;
@ -218,33 +220,81 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
/** An abstract class for mappings from types to types
*/
public static abstract class Mapping {
private String name;
public Mapping(String name) {
this.name = name;
public static abstract class TypeMapping<S> extends Types.MapVisitor<S> implements Function<Type, Type> {
@Override
public Type apply(Type type) {
return visit(type);
}
public abstract Type apply(Type t);
public String toString() {
return name;
List<Type> visit(List<Type> ts, S s) {
return ts.map(t -> visit(t, s));
}
@Override
public Type visitClassType(ClassType t, S s) {
Type outer = t.getEnclosingType();
Type outer1 = visit(outer, s);
List<Type> typarams = t.getTypeArguments();
List<Type> typarams1 = visit(typarams, s);
if (outer1 == outer && typarams1 == typarams) return t;
else return new ClassType(outer1, typarams1, t.tsym, t.metadata);
}
@Override
public Type visitWildcardType(WildcardType wt, S s) {
Type t = wt.type;
if (t != null)
t = visit(t, s);
if (t == wt.type)
return wt;
else
return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata);
}
@Override
public Type visitArrayType(ArrayType t, S s) {
Type elemtype = t.elemtype;
Type elemtype1 = visit(elemtype, s);
if (elemtype1 == elemtype) return t;
else return new ArrayType(elemtype1, t.tsym, t.metadata);
}
@Override
public Type visitMethodType(MethodType t, S s) {
List<Type> argtypes = t.argtypes;
Type restype = t.restype;
List<Type> thrown = t.thrown;
List<Type> argtypes1 = visit(argtypes, s);
Type restype1 = visit(restype, s);
List<Type> thrown1 = visit(thrown, s);
if (argtypes1 == argtypes &&
restype1 == restype &&
thrown1 == thrown) return t;
else return new MethodType(argtypes1, restype1, thrown1, t.tsym);
}
@Override
public Type visitCapturedType(CapturedType t, S s) {
return visitTypeVar(t, s);
}
@Override
public Type visitForAll(ForAll t, S s) {
return visit(t.qtype, s);
}
}
/** map a type function over all immediate descendants of this type
*/
public Type map(Mapping f) {
return this;
public <Z> Type map(TypeMapping<Z> mapping, Z arg) {
return mapping.visit(this, arg);
}
/** map a type function over a list of types
/** map a type function over all immediate descendants of this type (no arg version)
*/
public static List<Type> map(List<Type> ts, Mapping f) {
if (ts.nonEmpty()) {
List<Type> tail1 = map(ts.tail, f);
Type t = f.apply(ts.head);
if (tail1 != ts.tail || t != ts.head)
return tail1.prepend(t);
}
return ts;
public <Z> Type map(TypeMapping<Z> mapping) {
return mapping.visit(this, null);
}
/** Define a constant type, of the same kind as this type
@ -775,17 +825,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
return s.toString();
}
public Type map(Mapping f) {
//- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
Type t = type;
if (t != null)
t = f.apply(t);
if (t == type)
return this;
else
return new WildcardType(t, kind, tsym, bound, metadata);
}
@DefinedBy(Api.LANGUAGE_MODEL)
public Type getExtendsBound() {
if (kind == EXTENDS)
@ -1009,15 +1048,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
allparams().isEmpty();
}
public Type map(Mapping f) {
Type outer = getEnclosingType();
Type outer1 = f.apply(outer);
List<Type> typarams = getTypeArguments();
List<Type> typarams1 = map(typarams, f);
if (outer1 == outer && typarams1 == typarams) return this;
else return new ClassType(outer1, typarams1, tsym, metadata);
}
public boolean contains(Type elem) {
return
elem == this
@ -1248,12 +1278,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
};
}
public Type map(Mapping f) {
Type elemtype1 = f.apply(elemtype);
if (elemtype1 == elemtype) return this;
else return new ArrayType(elemtype1, tsym, metadata);
}
public boolean contains(Type elem) {
return elem == this || elemtype.contains(elem);
}
@ -1345,16 +1369,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
restype != null && restype.isErroneous();
}
public Type map(Mapping f) {
List<Type> argtypes1 = map(argtypes, f);
Type restype1 = f.apply(restype);
List<Type> thrown1 = map(thrown, f);
if (argtypes1 == argtypes &&
restype1 == restype &&
thrown1 == thrown) return this;
else return new MethodType(argtypes1, restype1, thrown1, tsym);
}
public boolean contains(Type elem) {
return elem == this || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
}
@ -1647,10 +1661,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
return qtype.isErroneous();
}
public Type map(Mapping f) {
return f.apply(qtype);
}
public boolean contains(Type elem) {
return qtype.contains(elem);
}
@ -1820,7 +1830,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
}
protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
Type bound2 = toTypeVarMap.apply(bound).baseType();
Type bound2 = bound.map(toTypeVarMap).baseType();
List<Type> prevBounds = bounds.get(ib);
for (Type b : prevBounds) {
//check for redundancy - use strict version of isSameType on tvars
@ -1831,15 +1841,10 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
notifyChange(EnumSet.of(ib));
}
//where
Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") {
TypeMapping<Void> toTypeVarMap = new TypeMapping<Void>() {
@Override
public Type apply(Type t) {
if (t.hasTag(UNDETVAR)) {
UndetVar uv = (UndetVar)t;
return uv.inst != null ? uv.inst : uv.qtype;
} else {
return t.map(this);
}
public Type visitUndetVar(UndetVar uv, Void _unused) {
return uv.inst != null ? uv.inst : uv.qtype;
}
};
@ -2110,7 +2115,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public Type getEnclosingType() { return this; }
public Type getReturnType() { return this; }
public Type asSub(Symbol sym) { return this; }
public Type map(Mapping f) { return this; }
public boolean isGenType(Type t) { return true; }
public boolean isErroneous() { return true; }

View File

@ -32,6 +32,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.BiPredicate;
import java.util.stream.Collector;
import javax.tools.JavaFileObject;
@ -1766,10 +1768,11 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="cvarLowerBounds">
public List<Type> cvarLowerBounds(List<Type> ts) {
return map(ts, cvarLowerBoundMapping);
return ts.map(cvarLowerBoundMapping);
}
private final Mapping cvarLowerBoundMapping = new Mapping("cvarLowerBound") {
public Type apply(Type t) {
private final TypeMapping<Void> cvarLowerBoundMapping = new TypeMapping<Void>() {
@Override
public Type visitCapturedType(CapturedType t, Void _unused) {
return cvarLowerBound(t);
}
};
@ -1879,9 +1882,15 @@ public class Types {
/**
* Mapping to take element type of an arraytype
*/
private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
public Type apply(Type t) {
return elemtype(skipTypeVars(t, false));
private TypeMapping<Void> elemTypeFun = new TypeMapping<Void>() {
@Override
public Type visitArrayType(ArrayType t, Void _unused) {
return t.elemtype;
}
@Override
public Type visitTypeVar(TypeVar t, Void _unused) {
return visit(skipTypeVars(t, false));
}
};
@ -2177,7 +2186,7 @@ public class Types {
}
}
// where
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
private TypeMapping<Boolean> erasure = new TypeMapping<Boolean>() {
private Type combineMetadata(final Type ty,
final TypeMetadata md) {
if (!md.isEmpty()) {
@ -2202,8 +2211,8 @@ public class Types {
if (t.isPrimitive())
return t; /*fast special case*/
else {
Type erased = t.map(recurse ? erasureRecFun : erasureFun);
return combineMetadata(erased, t.getMetadata());
//other cases already handled
return combineMetadata(t, t.getMetadata());
}
}
@ -2223,23 +2232,10 @@ public class Types {
Type erased = erasure(t.bound, recurse);
return combineMetadata(erased, t.getMetadata());
}
@Override
public Type visitErrorType(ErrorType t, Boolean recurse) {
return t;
}
};
private Mapping erasureFun = new Mapping ("erasure") {
public Type apply(Type t) { return erasure(t); }
};
private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
public Type apply(Type t) { return erasureRecursive(t); }
};
public List<Type> erasure(List<Type> ts) {
return Type.map(ts, erasureFun);
return erasure.visit(ts, false);
}
public Type erasureRecursive(Type t) {
@ -2247,7 +2243,7 @@ public class Types {
}
public List<Type> erasureRecursive(List<Type> ts) {
return Type.map(ts, erasureRecFun);
return erasure.visit(ts, true);
}
// </editor-fold>
@ -3177,15 +3173,18 @@ public class Types {
* changing all recursive bounds from old to new list.
*/
public List<Type> newInstances(List<Type> tvars) {
List<Type> tvars1 = Type.map(tvars, newInstanceFun);
List<Type> tvars1 = tvars.map(newInstanceFun);
for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
TypeVar tv = (TypeVar) l.head;
tv.bound = subst(tv.bound, tvars, tvars1);
}
return tvars1;
}
private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); }
private static final TypeMapping<Void> newInstanceFun = new TypeMapping<Void>() {
@Override
public TypeVar visitTypeVar(TypeVar t, Void _unused) {
return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata());
}
};
// </editor-fold>
@ -3408,42 +3407,87 @@ public class Types {
return cl;
}
/**
* Collect types into a new closure (using a @code{ClosureHolder})
*/
public Collector<Type, ClosureHolder, List<Type>> closureCollector(boolean minClosure, BiPredicate<Type, Type> shouldSkip) {
return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip),
ClosureHolder::add,
ClosureHolder::merge,
ClosureHolder::closure);
}
//where
class ClosureHolder {
List<Type> closure;
final boolean minClosure;
final BiPredicate<Type, Type> shouldSkip;
ClosureHolder(boolean minClosure, BiPredicate<Type, Type> shouldSkip) {
this.closure = List.nil();
this.minClosure = minClosure;
this.shouldSkip = shouldSkip;
}
void add(Type type) {
closure = insert(closure, type, shouldSkip);
}
ClosureHolder merge(ClosureHolder other) {
closure = union(closure, other.closure, shouldSkip);
return this;
}
List<Type> closure() {
return minClosure ? closureMin(closure) : closure;
}
}
BiPredicate<Type, Type> basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym;
/**
* Insert a type in a closure
*/
public List<Type> insert(List<Type> cl, Type t) {
public List<Type> insert(List<Type> cl, Type t, BiPredicate<Type, Type> shouldSkip) {
if (cl.isEmpty()) {
return cl.prepend(t);
} else if (t.tsym == cl.head.tsym) {
} else if (shouldSkip.test(t, cl.head)) {
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);
return insert(cl.tail, t, shouldSkip).prepend(cl.head);
}
}
public List<Type> insert(List<Type> cl, Type t) {
return insert(cl, t, basicClosureSkip);
}
/**
* Form the union of two closures
*/
public List<Type> union(List<Type> cl1, List<Type> cl2) {
public List<Type> union(List<Type> cl1, List<Type> cl2, BiPredicate<Type, Type> shouldSkip) {
if (cl1.isEmpty()) {
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 (shouldSkip.test(cl1.head, cl2.head)) {
return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head);
} else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
return union(cl1.tail, cl2).prepend(cl1.head);
return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head);
} else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
return union(cl1, cl2.tail).prepend(cl2.head);
return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head);
} else {
// unrelated types
return union(cl1.tail, cl2).prepend(cl1.head);
return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head);
}
}
public List<Type> union(List<Type> cl1, List<Type> cl2) {
return union(cl1, cl2, basicClosureSkip);
}
/**
* Intersect two closures
*/

View File

@ -40,11 +40,13 @@ import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
import com.sun.tools.javac.comp.Check.CheckContext;
import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Infer.FreeTypeListener;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
@ -2871,6 +2873,16 @@ public class Attr extends JCTree.Visitor {
names.empty, List.of(fExpr.targets.head), ABSTRACT);
if (csym != null) {
chk.checkImplementations(env.tree, csym, csym);
try {
//perform an additional functional interface check on the synthetic class,
//as there may be spurious errors for raw targets - because of existing issues
//with membership and inheritance (see JDK-8074570).
csym.flags_field |= INTERFACE;
types.findDescriptorType(csym.type);
} catch (FunctionDescriptorLookupError err) {
resultInfo.checkContext.report(fExpr,
diags.fragment(Fragments.NoSuitableFunctionalIntfInst(fExpr.targets.head)));
}
}
} catch (Types.FunctionDescriptorLookupError ex) {
JCDiagnostic cause = ex.getDiagnostic();
@ -2942,7 +2954,7 @@ public class Attr extends JCTree.Visitor {
public void visitBinary(JCBinary tree) {
// Attribute arguments.
Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env));
Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));
// Find operator.
Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
Type owntype = types.createErrorType(tree.type);
@ -3722,7 +3734,7 @@ public class Attr extends JCTree.Visitor {
DeferredAttr.DeferredTypeMap checkDeferredMap =
deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
argtypes = Type.map(argtypes, checkDeferredMap);
argtypes = argtypes.map(checkDeferredMap);
if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
chk.warnUnchecked(env.tree.pos(),
@ -3730,7 +3742,7 @@ public class Attr extends JCTree.Visitor {
kindName(sym),
sym.name,
rs.methodArguments(sym.type.getParameterTypes()),
rs.methodArguments(Type.map(argtypes, checkDeferredMap)),
rs.methodArguments(argtypes.map(checkDeferredMap)),
kindName(sym.location()),
sym.location());
owntype = new MethodType(owntype.getParameterTypes(),
@ -3754,7 +3766,7 @@ public class Attr extends JCTree.Visitor {
return new Pair<>(sym, diag);
}
};
List<Type> argtypes2 = Type.map(argtypes,
List<Type> argtypes2 = argtypes.map(
rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
env.tree, sym, site, sym.name, argtypes2, typeargtypes);

View File

@ -27,6 +27,7 @@ package com.sun.tools.javac.comp;
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.TypeMapping;
import com.sun.tools.javac.comp.Resolve.ResolveError;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
@ -44,7 +45,6 @@ import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -300,13 +300,6 @@ public class DeferredAttr extends JCTree.Visitor {
}
};
DeferredTypeCompleter dummyCompleter = new DeferredTypeCompleter() {
public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
Assert.check(deferredAttrContext.mode == AttrMode.CHECK);
return dt.tree.type = Type.stuckType;
}
};
/**
* Policy for detecting stuck expressions. Different criteria might cause
* an expression to be judged as stuck, depending on whether the check
@ -849,33 +842,24 @@ public class DeferredAttr extends JCTree.Visitor {
/** an empty deferred attribution context - all methods throw exceptions */
final DeferredAttrContext emptyDeferredAttrContext;
/** The AttrMode to descriptive name mapping */
private static final EnumMap<AttrMode, String> deferredTypeMapDescriptions;
static {
deferredTypeMapDescriptions = new EnumMap<>(AttrMode.class);
deferredTypeMapDescriptions.put(AttrMode.CHECK, "deferredTypeMap[CHECK]");
deferredTypeMapDescriptions.put(AttrMode.SPECULATIVE, "deferredTypeMap[SPECULATIVE]");
}
/**
* Map a list of types possibly containing one or more deferred types
* into a list of ordinary types. Each deferred type D is mapped into a type T,
* where T is computed by retrieving the type that has already been
* computed for D during a previous deferred attribution round of the given kind.
*/
class DeferredTypeMap extends Type.Mapping {
class DeferredTypeMap extends TypeMapping<Void> {
DeferredAttrContext deferredAttrContext;
protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
super(deferredTypeMapDescriptions.get(mode));
this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase,
infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
}
@Override
public Type apply(Type t) {
public Type visitType(Type t, Void _unused) {
if (!t.hasTag(DEFERRED)) {
return t.map(this);
return super.visitType(t, null);
} else {
DeferredType dt = (DeferredType)t;
return typeOf(dt);
@ -928,7 +912,7 @@ public class DeferredAttr extends JCTree.Visitor {
return chk.checkNonVoid(pos, super.check(pos, found));
}
});
return super.apply(dt);
return super.visit(dt);
}
}

View File

@ -25,6 +25,7 @@
package com.sun.tools.javac.comp;
import com.sun.tools.javac.code.Type.TypeMapping;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
import com.sun.tools.javac.tree.TreeInfo;
@ -477,7 +478,7 @@ public class Infer {
restype = syms.objectType;
}
List<Type> paramtypes = Type.map(argtypes, new ImplicitArgType(spMethod, resolveContext.step));
List<Type> paramtypes = argtypes.map(new ImplicitArgType(spMethod, resolveContext.step));
List<Type> exType = spMethod != null ?
spMethod.getThrownTypes() :
List.of(syms.throwableType); // make it throw all exceptions
@ -495,9 +496,16 @@ public class Infer {
(rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase);
}
public Type apply(Type t) {
t = types.erasure(super.apply(t));
if (t.hasTag(BOT))
@Override
public Type visitClassType(ClassType t, Void aVoid) {
return types.erasure(t);
}
@Override
public Type visitType(Type t, Void _unused) {
if (t.hasTag(DEFERRED)) {
return visit(super.visitType(t, null));
} else if (t.hasTag(BOT))
// nulls type as the marker type Null (which has no instances)
// infer as java.lang.Void for now
t = types.boxedClass(syms.voidType).type;
@ -865,7 +873,8 @@ public class Infer {
@Override
public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
Infer infer = inferenceContext.infer();
List<Type> boundList = uv.getBounds(InferenceBound.UPPER);
List<Type> boundList = uv.getBounds(InferenceBound.UPPER).stream()
.collect(infer.types.closureCollector(true, infer.types::isSameType));
List<Type> boundListTail = boundList.tail;
while (boundList.nonEmpty()) {
List<Type> tmpTail = boundListTail;
@ -2046,23 +2055,19 @@ public class Infer {
List<FreeTypeListener> freetypeListeners = List.nil();
public InferenceContext(List<Type> inferencevars) {
this.undetvars = Type.map(inferencevars, fromTypeVarFun);
this.undetvars = inferencevars.map(fromTypeVarFun);
this.inferencevars = inferencevars;
}
//where
Mapping fromTypeVarFun = new Mapping("fromTypeVarFunWithBounds") {
// mapping that turns inference variables into undet vars
public Type apply(Type t) {
if (t.hasTag(TYPEVAR)) {
TypeVar tv = (TypeVar)t;
if (tv.isCaptured()) {
return new CapturedUndetVar((CapturedType)tv, types);
} else {
return new UndetVar(tv, types);
}
} else {
return t.map(this);
}
TypeMapping<Void> fromTypeVarFun = new TypeMapping<Void>() {
@Override
public Type visitTypeVar(TypeVar tv, Void aVoid) {
return new UndetVar(tv, types);
}
@Override
public Type visitCapturedType(CapturedType t, Void aVoid) {
return new CapturedUndetVar(t, types);
}
};

View File

@ -232,8 +232,7 @@ public class Resolve {
}
}
String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
List<Type> argtypes2 = Type.map(argtypes,
deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
site.tsym, mostSpecificPos, currentResolutionContext.step,
methodArguments(argtypes2),
@ -2259,7 +2258,7 @@ public class Resolve {
(typeargtypes == null || !Type.isErroneous(typeargtypes));
}
public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
return Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
}
};

View File

@ -56,6 +56,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
import static com.sun.tools.javac.jvm.ClassFile.*;
@ -2006,6 +2007,15 @@ public class ClassReader {
}
if (saveParameterNames)
setParameterNames(m, type);
if ((flags & VARARGS) != 0) {
final Type last = type.getParameterTypes().last();
if (last == null || !last.hasTag(ARRAY)) {
m.flags_field &= ~VARARGS;
throw badClassFile("malformed.vararg.method", m);
}
}
return m;
}

View File

@ -1847,6 +1847,9 @@ compiler.misc.unicode.str.not.supported=\
compiler.misc.undecl.type.var=\
undeclared type variable: {0}
compiler.misc.malformed.vararg.method=\
class file contains malformed variable arity method: {0}
compiler.misc.wrong.version=\
class file has wrong version {0}.{1}, should be {2}.{3}

View File

@ -33,6 +33,7 @@ import java.util.Iterator;
import java.util.AbstractCollection;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.function.Function;
import java.util.stream.Collector;
/** A class for generic linked lists. Links are supposed to be
@ -416,6 +417,17 @@ public class List<A> extends AbstractCollection<A> implements java.util.List<A>
return last;
}
@SuppressWarnings("unchecked")
public <Z> List<Z> map(Function<A, Z> mapper) {
if (nonEmpty()) {
List<Z> tail1 = tail.map(mapper);
Z head1 = mapper.apply(head);
if (tail1 != tail || head1 != head)
return tail1.prepend(head1);
}
return (List<Z>)this;
}
@SuppressWarnings("unchecked")
public static <T> List<T> convert(Class<T> klass, List<?> list) {
if (list == null)

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2015, 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 8071847
* @summary Verify proper termination when instance initialization method uses invalid flags
* @compile T8071847.java
* @run main T8071847
*/
import java.io.*;
import java.util.*;
public class T8071847 {
String testclass="invalidFlags.class";
String testclassHexString =
"CAFEBABE00000031000D0A0003000A07000B07000C0100063C696E69743E0100" +
"03282956010004436F646501000F4C696E654E756D6265725461626C6501000A" +
"536F7572636546696C65010009546573742E6A6176610C0004000501000C696E" +
"76616C6964466C6167730100106A6176612F6C616E672F4F626A656374002000" +
"02000300000000000100A000040005000100060000001D00010001000000052A" +
"B70001B10000000100070000000600010000000100010008000000020009";
String testJavaFile = "testInvalidFlags.java";
String testJavaSource ="public class testInvalidFlags extends invalidFlags {" +
"invalidFlags c = null;" +
"public testInvalidFlags() { c = new invalidFlags(); }" +
"public static void main(String... args) { " +
"new testInvalidFlags();}}";
public static void main(String[] args) throws Exception {
new T8071847().run();
}
public void run() throws IOException {
writeHexFile(testclass,testclassHexString);
writeTestFile(testJavaFile, testJavaSource);
javac(testJavaFile);
}
File writeTestFile(String fname, String source) throws IOException {
File f = new File(fname);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println(source);
out.close();
return f;
}
byte[] hexToByte(String str) {
char[] CA = str.toCharArray();
byte[] byteArry = new byte[str.length()/2];
int bi = 0;
for (int i = 0; i<CA.length ; i+=2) {
char c1 = CA[i], c2=CA[i+1];
byteArry[bi++] = (byte)((Character.digit((int)c1,16)<<4) +
Character.digit((int)c2,16));
}
return byteArry;
}
File writeHexFile(String classFileName, String hexString) throws IOException {
File f = new File(classFileName);
FileOutputStream output = new FileOutputStream(f);
output.write(hexToByte(hexString));
output.close();
return f;
}
String javac(String className) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = 0;
List<String> javacArgs = new ArrayList<>();
javacArgs.addAll(Arrays.asList("-XDrawDiagnostics", "-cp", ".", "-d", ".", className));
rc = com.sun.tools.javac.Main.compile(
javacArgs.toArray(new String[javacArgs.size()]),out);
out.close();
if (rc > 1) {
System.out.println(sw.toString());
throw new Error("javac " + className + " failed. rc=" + rc);
}
if (rc != 1 || !sw.toString().contains("compiler.misc.malformed.vararg.method"))
throw new RuntimeException("Unexpected output" + sw.toString());
return sw.toString();
}
}

View File

@ -87,6 +87,7 @@ compiler.misc.type.req.exact
compiler.misc.unable.to.access.file # ClassFile
compiler.misc.undecl.type.var # ClassReader
compiler.misc.unicode.str.not.supported # ClassReader
compiler.misc.malformed.vararg.method # ClassReader
compiler.misc.verbose.retro # UNUSED
compiler.misc.verbose.retro.with # UNUSED
compiler.misc.verbose.retro.with.list # UNUSED

View File

@ -0,0 +1,14 @@
/*
* @test /nodynamiccopyright/
* @bug 8074148
* @summary Attr.visitBinary flags error at wrong position
*
* @compile/fail/ref=BinopVoidTest.out -XDrawDiagnostics BinopVoidTest.java
*/
class BinopVoidTest {
void foo() {}
int x = 10 + foo();
int y = foo() + 10;
int z = foo() + foo();
}

View File

@ -0,0 +1,5 @@
BinopVoidTest.java:11:21: compiler.err.void.not.allowed.here
BinopVoidTest.java:12:16: compiler.err.void.not.allowed.here
BinopVoidTest.java:13:16: compiler.err.void.not.allowed.here
BinopVoidTest.java:13:24: compiler.err.void.not.allowed.here
4 errors

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2015, 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 8048838
* @summary type inference performance regression
* @compile T8048838.java
*/
class T8048838 {
<T1 extends T2, T2 extends T3, T3 extends T4, T4 extends T5, T5 extends T6, T6 extends T7,
T7 extends T8, T8 extends T9, T9 extends T10, T10 extends T11, T11 extends T12,
T12 extends T13, T13 extends T14, T14 extends T15, T15 extends T16, T16 extends T17,
T17 extends T18, T18 extends T19, T19 extends T20, T20 extends T21, T21 extends T22,
T22 extends T23, T23 extends T24, T24 extends T25, T25 extends T26, T26 extends T27,
T27 extends T28, T28 extends T29, T29 extends T30, T30 extends T31, T31 extends T32,
T32 extends T33, T33 extends T34, T34 extends T35, T35 extends T36, T36 extends T37,
T37 extends T38, T38 extends T39, T39 extends T40, T40 extends T41, T41 extends T42,
T42 extends T43, T43 extends T44, T44 extends T45, T45 extends T46, T46 extends T47,
T47 extends T48, T48 extends T49, T49 extends T50, T50 extends T51, T51 extends T52,
T52 extends T53, T53 extends T54, T54 extends T55, T55 extends T56, T56 extends T57,
T57 extends T58, T58 extends T59, T59 extends T60, T60 extends T61, T61 extends T62,
T62 extends T63, T63 extends T64, T64 extends T65, T65 extends T66, T66 extends T67,
T67 extends T68, T68 extends T69, T69 extends T70, T70 extends T71, T71 extends T72,
T72 extends T73, T73 extends T74, T74 extends T75, T75 extends T76, T76 extends T77,
T77 extends T78, T78 extends T79, T79 extends T80, T80 extends T81, T81 extends T82,
T82 extends T83, T83 extends T84, T84 extends T85, T85 extends T86, T86 extends T87,
T87 extends T88, T88 extends T89, T89 extends T90, T90 extends T91, T91 extends T92,
T92 extends T93, T93 extends T94, T94 extends T95, T95 extends T96, T96 extends T97,
T97 extends T98, T98 extends T99, T99 extends T100, T100 extends Integer>
T1 foo(T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8, T9 x9, T10 x10, T11 x11, T12 x12,
T13 x13, T14 x14, T15 x15, T16 x16, T17 x17, T18 x18, T19 x19, T20 x20, T21 x21, T22 x22,
T23 x23, T24 x24, T25 x25, T26 x26, T27 x27, T28 x28, T29 x29, T30 x30, T31 x31, T32 x32,
T33 x33, T34 x34, T35 x35, T36 x36, T37 x37, T38 x38, T39 x39, T40 x40, T41 x41, T42 x42,
T43 x43, T44 x44, T45 x45, T46 x46, T47 x47, T48 x48, T49 x49, T50 x50, T51 x51, T52 x52,
T53 x53, T54 x54, T55 x55, T56 x56, T57 x57, T58 x58, T59 x59, T60 x60, T61 x61, T62 x62,
T63 x63, T64 x64, T65 x65, T66 x66, T67 x67, T68 x68, T69 x69, T70 x70, T71 x71, T72 x72,
T73 x73, T74 x74, T75 x75, T76 x76, T77 x77, T78 x78, T79 x79, T80 x80, T81 x81, T82 x82,
T83 x83, T84 x84, T85 x85, T86 x86, T87 x87, T88 x88, T89 x89, T90 x90, T91 x91, T92 x92,
T93 x93, T94 x94, T95 x95, T96 x96, T97 x97, T98 x98, T99 x99, T100 x100) { return null; }
Object test() {
return foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100); // type inference expected
}
}

View File

@ -0,0 +1,33 @@
/*
* @test /nodynamiccopyright/
* @bug 8074381
* @summary java.lang.AssertionError during compiling
* @compile/fail/ref=T8074381a.out -XDrawDiagnostics T8074381a.java
*/
class T8074381a {
interface Sup<X> {
boolean m(X x);
}
interface Sub<X> extends Sup<String> {
boolean m(String s);
}
void testRaw() {
Sub s1 = c -> true;
Sub s2 = Boolean::new;
Sub s3 = new Sub() {
@Override
public boolean m(String o) { return true; }
};
}
void testNonRaw() {
Sub<Integer> s1 = c -> true;
Sub<Integer> s2 = Boolean::new;
Sub<Integer> s3 = new Sub<Integer>() {
@Override
public boolean m(String o) { return true; }
};
}
}

View File

@ -0,0 +1,4 @@
T8074381a.java:17:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
T8074381a.java:18:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub)
T8074381a.java:19:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup
3 errors

View File

@ -0,0 +1,44 @@
/*
* @test /nodynamiccopyright/
* @bug 8074381
* @summary java.lang.AssertionError during compiling
* @compile/fail/ref=T8074381b.out -XDrawDiagnostics T8074381b.java
*/
import java.util.function.BiConsumer;
import java.util.function.Consumer;
class T8074381b {
@SuppressWarnings("unchecked")
public Invocation resolve(Handler handler) {
return new Invocation((t) -> handler.handle((String) t));
}
public static class Handler {
public void handle(String s) {
System.out.println(s);
}
}
public static class Invocation<T> {
public final ThrowingConsumer<T> consumer;
public Invocation(final ThrowingConsumer<T> consumer) {
this.consumer = consumer;
}
}
@FunctionalInterface
public interface ThrowingConsumer<T> extends BiConsumer<T,Consumer<Throwable>> {
@Override
default void accept(final T elem, final Consumer<Throwable> errorHandler) {
try {
acceptThrows(elem);
} catch (final Throwable e) {
errorHandler.accept(e);
}
}
void acceptThrows(T elem) throws Throwable;
}
}

View File

@ -0,0 +1,2 @@
T8074381b.java:14:16: compiler.err.cant.apply.symbol: kindname.constructor, Invocation, T8074381b.ThrowingConsumer, @383, kindname.class, T8074381b.Invocation<T>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: T8074381b.ThrowingConsumer))
1 error