Merge
This commit is contained in:
commit
524a340ac9
langtools
src/share/classes/com/sun/tools
doclets/internal/toolkit
doclint
javac
code
comp
util
javadoc
javah
javap
test/tools
doclint
javac
Diagnostics/compressed
T6356530
SerializableAbstractClassWithNonAbstractMethodsTest.javaSerializableAbstractClassWithNonAbstractMethodsTest.out
conditional
generics
6723444
7015430
7034511
8016640
inference
lambda
8019480
8020147
BadNestedLambda.javaBadNestedLambda.outMethodReference68.javaMethodReference68.outMethodReference69.javaMethodReference69.outMethodReference70.javaMethodReference70.outMethodReference71.javaMethodReference71.outMethodReference72.javaMethodReference72.outNestedCapture01.javaNestedCapture02.javaNestedCapture03.javaTargetType36.javaTargetType36.outTargetType60.outTargetType63.javaTargetType63.outTargetType75.javaTargetType76.javameth
warnings/6594914
javap/8007907
@ -467,7 +467,7 @@ public abstract class Configuration {
|
||||
nodeprecated = true;
|
||||
} else if (opt.equals("-sourcepath")) {
|
||||
sourcepath = os[1];
|
||||
} else if (opt.equals("-classpath") &&
|
||||
} else if ((opt.equals("-classpath") || opt.equals("-cp")) &&
|
||||
sourcepath.length() == 0) {
|
||||
sourcepath = os[1];
|
||||
} else if (opt.equals("-excludedocfilessubdir")) {
|
||||
|
@ -187,6 +187,8 @@ public class DocLint implements Plugin {
|
||||
javacBootClassPath = splitPath(args[++i]);
|
||||
} else if (arg.equals("-classpath") && i + 1 < args.length) {
|
||||
javacClassPath = splitPath(args[++i]);
|
||||
} else if (arg.equals("-cp") && i + 1 < args.length) {
|
||||
javacClassPath = splitPath(args[++i]);
|
||||
} else if (arg.equals("-sourcepath") && i + 1 < args.length) {
|
||||
javacSourcePath = splitPath(args[++i]);
|
||||
} else if (arg.equals(XMSGS_OPTION)) {
|
||||
@ -325,6 +327,14 @@ public class DocLint implements Plugin {
|
||||
static abstract class DeclScanner extends TreePathScanner<Void, Void> {
|
||||
abstract void visitDecl(Tree tree, Name name);
|
||||
|
||||
@Override
|
||||
public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {
|
||||
if (tree.getPackageName() != null) {
|
||||
visitDecl(tree, null);
|
||||
}
|
||||
return super.visitCompilationUnit(tree, ignore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClass(ClassTree tree, Void ignore) {
|
||||
visitDecl(tree, tree.getSimpleName());
|
||||
|
@ -142,7 +142,7 @@ public class Env {
|
||||
currElement = trees.getElement(currPath);
|
||||
currOverriddenMethods = ((JavacTypes) types).getOverriddenMethods(currElement);
|
||||
|
||||
AccessKind ak = null;
|
||||
AccessKind ak = AccessKind.PUBLIC;
|
||||
for (TreePath p = path; p != null; p = p.getParentPath()) {
|
||||
Element e = trees.getElement(p);
|
||||
if (e != null && e.getKind() != ElementKind.PACKAGE) {
|
||||
|
@ -109,7 +109,7 @@ Options:\n\
|
||||
\ Show this message.\n\
|
||||
\n\
|
||||
The following javac options are also supported\n\
|
||||
\ -bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\
|
||||
\ -bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\
|
||||
\n\
|
||||
To run doclint on part of a project, put the compiled classes for your\n\
|
||||
project on the classpath (or bootclasspath), then specify the source files\n\
|
||||
|
@ -261,6 +261,11 @@ public class Flags {
|
||||
*/
|
||||
public static final long SIGNATURE_POLYMORPHIC = 1L<<46;
|
||||
|
||||
/**
|
||||
* Flag that marks inference variables used in a 'throws' clause
|
||||
*/
|
||||
public static final long THROWS = 1L<<47;
|
||||
|
||||
/** Modifier masks.
|
||||
*/
|
||||
public static final int
|
||||
@ -365,7 +370,9 @@ public class Flags {
|
||||
CLASH(Flags.CLASH),
|
||||
AUXILIARY(Flags.AUXILIARY),
|
||||
NOT_IN_PROFILE(Flags.NOT_IN_PROFILE),
|
||||
BAD_OVERRIDE(Flags.BAD_OVERRIDE);
|
||||
BAD_OVERRIDE(Flags.BAD_OVERRIDE),
|
||||
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
|
||||
THROWS(Flags.THROWS);
|
||||
|
||||
Flag(long flag) {
|
||||
this.value = flag;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -316,6 +316,7 @@ public class Scope {
|
||||
public Entry lookup(Name name) {
|
||||
return lookup(name, noFilter);
|
||||
}
|
||||
|
||||
public Entry lookup(Name name, Filter<Symbol> sf) {
|
||||
Entry e = table[getIndex(name)];
|
||||
if (e == null || e == sentinel)
|
||||
@ -361,6 +362,10 @@ public class Scope {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean anyMatch(Filter<Symbol> sf) {
|
||||
return getElements(sf).iterator().hasNext();
|
||||
}
|
||||
|
||||
public Iterable<Symbol> getElements() {
|
||||
return getElements(noFilter);
|
||||
}
|
||||
|
@ -78,6 +78,9 @@ public abstract class Type implements TypeMirror {
|
||||
/** Constant type: special type to be used during recovery of deferred expressions. */
|
||||
public static final JCNoType recoveryType = new JCNoType();
|
||||
|
||||
/** Constant type: special type to be used for marking stuck trees. */
|
||||
public static final JCNoType stuckType = new JCNoType();
|
||||
|
||||
/** If this switch is turned on, the names of type variables
|
||||
* and anonymous classes are printed with hashcodes appended.
|
||||
*/
|
||||
@ -1449,7 +1452,7 @@ public abstract class Type implements TypeMirror {
|
||||
}
|
||||
|
||||
/** inference variable bounds */
|
||||
private Map<InferenceBound, List<Type>> bounds;
|
||||
protected Map<InferenceBound, List<Type>> bounds;
|
||||
|
||||
/** inference variable's inferred type (set from Infer.java) */
|
||||
public Type inst = null;
|
||||
@ -1511,8 +1514,17 @@ public abstract class Type implements TypeMirror {
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/** internal method used to override an undetvar bounds */
|
||||
public void setBounds(InferenceBound ib, List<Type> newBounds) {
|
||||
bounds.put(ib, newBounds);
|
||||
}
|
||||
|
||||
/** add a bound of a given kind - this might trigger listener notification */
|
||||
public void addBound(InferenceBound ib, Type bound, Types types) {
|
||||
public final void addBound(InferenceBound ib, Type bound, Types types) {
|
||||
addBound(ib, bound, types, false);
|
||||
}
|
||||
|
||||
protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
|
||||
Type bound2 = toTypeVarMap.apply(bound);
|
||||
List<Type> prevBounds = bounds.get(ib);
|
||||
for (Type b : prevBounds) {
|
||||
@ -1529,7 +1541,7 @@ public abstract class Type implements TypeMirror {
|
||||
public Type apply(Type t) {
|
||||
if (t.hasTag(UNDETVAR)) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
return uv.qtype;
|
||||
return uv.inst != null ? uv.inst : uv.qtype;
|
||||
} else {
|
||||
return t.map(this);
|
||||
}
|
||||
@ -1567,7 +1579,7 @@ public abstract class Type implements TypeMirror {
|
||||
bounds.put(ib, newBounds.toList());
|
||||
//step 3 - for each dependency, add new replaced bound
|
||||
for (Type dep : deps) {
|
||||
addBound(ib, types.subst(dep, from, to), types);
|
||||
addBound(ib, types.subst(dep, from, to), types, true);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@ -1583,6 +1595,39 @@ public abstract class Type implements TypeMirror {
|
||||
listener.varChanged(this, ibs);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCaptured() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used to represent synthetic captured inference variables
|
||||
* that can be generated during nested generic method calls. The only difference
|
||||
* between these inference variables and ordinary ones is that captured inference
|
||||
* variables cannot get new bounds through incorporation.
|
||||
*/
|
||||
public static class CapturedUndetVar extends UndetVar {
|
||||
|
||||
public CapturedUndetVar(CapturedType origin, Types types) {
|
||||
super(origin, types);
|
||||
if (!origin.lower.hasTag(BOT)) {
|
||||
bounds.put(InferenceBound.LOWER, List.of(origin.lower));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
|
||||
if (update) {
|
||||
//only change bounds if request comes from substBounds
|
||||
super.addBound(ib, bound, types, update);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptured() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Represents NONE.
|
||||
|
@ -2330,7 +2330,7 @@ public class Types {
|
||||
|
||||
@Override
|
||||
public Type visitErrorType(ErrorType t, Void ignored) {
|
||||
return t;
|
||||
return Type.noType;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
@ -2950,7 +2950,7 @@ public class Types {
|
||||
if (elemtype == t.elemtype)
|
||||
return t;
|
||||
else
|
||||
return new ArrayType(upperBound(elemtype), t.tsym);
|
||||
return new ArrayType(elemtype, t.tsym);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -481,31 +481,7 @@ public class Attr extends JCTree.Visitor {
|
||||
static final long serialVersionUID = -6924771130405446405L;
|
||||
private Env<AttrContext> env;
|
||||
private BreakAttr(Env<AttrContext> env) {
|
||||
this.env = copyEnv(env);
|
||||
}
|
||||
|
||||
private Env<AttrContext> copyEnv(Env<AttrContext> env) {
|
||||
Env<AttrContext> newEnv =
|
||||
env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
|
||||
if (newEnv.outer != null) {
|
||||
newEnv.outer = copyEnv(newEnv.outer);
|
||||
}
|
||||
return newEnv;
|
||||
}
|
||||
|
||||
private Scope copyScope(Scope sc) {
|
||||
Scope newScope = new Scope(sc.owner);
|
||||
List<Symbol> elemsList = List.nil();
|
||||
while (sc != null) {
|
||||
for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
|
||||
elemsList = elemsList.prepend(e.sym);
|
||||
}
|
||||
sc = sc.next;
|
||||
}
|
||||
for (Symbol s : elemsList) {
|
||||
newScope.enter(s);
|
||||
}
|
||||
return newScope;
|
||||
this.env = env;
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,11 +531,6 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Type check(DiagnosticPosition pos, Type found) {
|
||||
return chk.checkNonVoid(pos, super.check(pos, found));
|
||||
}
|
||||
}
|
||||
|
||||
final ResultInfo statInfo;
|
||||
@ -610,7 +581,7 @@ public class Attr extends JCTree.Visitor {
|
||||
tree.accept(this);
|
||||
if (tree == breakTree &&
|
||||
resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
|
||||
throw new BreakAttr(env);
|
||||
throw new BreakAttr(copyEnv(env));
|
||||
}
|
||||
return result;
|
||||
} catch (CompletionFailure ex) {
|
||||
@ -622,6 +593,30 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
Env<AttrContext> copyEnv(Env<AttrContext> env) {
|
||||
Env<AttrContext> newEnv =
|
||||
env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
|
||||
if (newEnv.outer != null) {
|
||||
newEnv.outer = copyEnv(newEnv.outer);
|
||||
}
|
||||
return newEnv;
|
||||
}
|
||||
|
||||
Scope copyScope(Scope sc) {
|
||||
Scope newScope = new Scope(sc.owner);
|
||||
List<Symbol> elemsList = List.nil();
|
||||
while (sc != null) {
|
||||
for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
|
||||
elemsList = elemsList.prepend(e.sym);
|
||||
}
|
||||
sc = sc.next;
|
||||
}
|
||||
for (Symbol s : elemsList) {
|
||||
newScope.enter(s);
|
||||
}
|
||||
return newScope;
|
||||
}
|
||||
|
||||
/** Derived visitor method: attribute an expression tree.
|
||||
*/
|
||||
public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
|
||||
@ -1697,7 +1692,8 @@ public class Attr extends JCTree.Visitor {
|
||||
diags.fragment("unexpected.ret.val"));
|
||||
}
|
||||
attribTree(tree.expr, env, env.info.returnResult);
|
||||
} else if (!env.info.returnResult.pt.hasTag(VOID)) {
|
||||
} else if (!env.info.returnResult.pt.hasTag(VOID) &&
|
||||
!env.info.returnResult.pt.hasTag(NONE)) {
|
||||
env.info.returnResult.checkContext.report(tree.pos(),
|
||||
diags.fragment("missing.ret.val"));
|
||||
}
|
||||
@ -2395,7 +2391,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ?
|
||||
recoveryInfo :
|
||||
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
|
||||
new LambdaResultInfo(lambdaType.getReturnType(), funcContext);
|
||||
localEnv.info.returnResult = bodyResultInfo;
|
||||
|
||||
Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
|
||||
@ -2434,7 +2430,7 @@ public class Attr extends JCTree.Visitor {
|
||||
boolean isSpeculativeRound =
|
||||
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
|
||||
|
||||
postAttr(that);
|
||||
preFlow(that);
|
||||
flow.analyzeLambda(env, that, make, isSpeculativeRound);
|
||||
|
||||
checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
|
||||
@ -2456,6 +2452,21 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
//where
|
||||
void preFlow(JCLambda tree) {
|
||||
new PostAttrAnalyzer() {
|
||||
@Override
|
||||
public void scan(JCTree tree) {
|
||||
if (tree == null ||
|
||||
(tree.type != null &&
|
||||
tree.type == Type.stuckType)) {
|
||||
//don't touch stuck expressions!
|
||||
return;
|
||||
}
|
||||
super.scan(tree);
|
||||
}
|
||||
}.scan(tree);
|
||||
}
|
||||
|
||||
Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
|
||||
|
||||
@Override
|
||||
@ -2587,6 +2598,28 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
class LambdaResultInfo extends ResultInfo {
|
||||
|
||||
LambdaResultInfo(Type pt, CheckContext checkContext) {
|
||||
super(VAL, pt, checkContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Type check(DiagnosticPosition pos, Type found) {
|
||||
return super.check(pos, found.baseType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResultInfo dup(CheckContext newContext) {
|
||||
return new LambdaResultInfo(pt, newContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResultInfo dup(Type newPt) {
|
||||
return new LambdaResultInfo(newPt, checkContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lambda compatibility. Check that given return types, thrown types, parameter types
|
||||
* are compatible with the expected functional interface descriptor. This means that:
|
||||
@ -2688,10 +2721,21 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext);
|
||||
List<Type> argtypes = desc.getParameterTypes();
|
||||
Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck;
|
||||
|
||||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult =
|
||||
rs.resolveMemberReference(that.pos(), localEnv, that,
|
||||
that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck);
|
||||
if (resultInfo.checkContext.inferenceContext().free(argtypes)) {
|
||||
referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
|
||||
}
|
||||
|
||||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
|
||||
List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save();
|
||||
try {
|
||||
refResult = rs.resolveMemberReference(that.pos(), localEnv, that, that.expr.type,
|
||||
that.name, argtypes, typeargtypes, true, referenceCheck,
|
||||
resultInfo.checkContext.inferenceContext());
|
||||
} finally {
|
||||
resultInfo.checkContext.inferenceContext().rollback(saved_undet);
|
||||
}
|
||||
|
||||
Symbol refSym = refResult.fst;
|
||||
Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
|
||||
@ -2803,17 +2847,24 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
|
||||
that.sym = refSym.baseSymbol();
|
||||
that.kind = lookupHelper.referenceKind(that.sym);
|
||||
|
||||
ResultInfo checkInfo =
|
||||
resultInfo.dup(newMethodTemplate(
|
||||
desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
|
||||
lookupHelper.argtypes,
|
||||
typeargtypes));
|
||||
that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes));
|
||||
|
||||
Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
|
||||
|
||||
if (that.kind.isUnbound() &&
|
||||
resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
|
||||
//re-generate inference constraints for unbound receiver
|
||||
if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asFree(argtypes.head), exprType)) {
|
||||
//cannot happen as this has already been checked - we just need
|
||||
//to regenerate the inference constraints, as that has been lost
|
||||
//as a result of the call to inferenceContext.save()
|
||||
Assert.error("Can't get here");
|
||||
}
|
||||
}
|
||||
|
||||
if (!refType.isErroneous()) {
|
||||
refType = types.createMethodTypeWithReturn(refType,
|
||||
adjustMethodReturnType(lookupHelper.site, that.name, checkInfo.pt.getParameterTypes(), refType.getReturnType()));
|
||||
@ -4305,7 +4356,7 @@ public class Attr extends JCTree.Visitor {
|
||||
if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
|
||||
isSerializable(c) &&
|
||||
(c.flags() & Flags.ENUM) == 0 &&
|
||||
(c.flags() & ABSTRACT) == 0) {
|
||||
checkForSerial(c)) {
|
||||
checkSerialVersionUID(tree, c);
|
||||
}
|
||||
if (allowTypeAnnos) {
|
||||
@ -4317,6 +4368,22 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
// where
|
||||
boolean checkForSerial(ClassSymbol c) {
|
||||
if ((c.flags() & ABSTRACT) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return c.members().anyMatch(anyNonAbstractOrDefaultMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Filter<Symbol> anyNonAbstractOrDefaultMethod = new Filter<Symbol>() {
|
||||
@Override
|
||||
public boolean accepts(Symbol s) {
|
||||
return s.kind == Kinds.MTH &&
|
||||
(s.flags() & (DEFAULT | ABSTRACT)) != ABSTRACT;
|
||||
}
|
||||
};
|
||||
|
||||
/** get a diagnostic position for an attribute of Type t, or null if attribute missing */
|
||||
private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
|
||||
for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
|
||||
@ -4369,9 +4436,7 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
private Type capture(Type type) {
|
||||
//do not capture free types
|
||||
return resultInfo.checkContext.inferenceContext().free(type) ?
|
||||
type : types.capture(type);
|
||||
return types.capture(type);
|
||||
}
|
||||
|
||||
private void validateTypeAnnotations(JCTree tree) {
|
||||
|
@ -897,7 +897,8 @@ public class Check {
|
||||
assertConvertible(arg, arg.type, varArg, warn);
|
||||
args = args.tail;
|
||||
}
|
||||
} else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
|
||||
} else if ((sym.flags() & (VARARGS | SIGNATURE_POLYMORPHIC)) == VARARGS &&
|
||||
allowVarargs) {
|
||||
// non-varargs call to varargs method
|
||||
Type varParam = owntype.getParameterTypes().last();
|
||||
Type lastArg = argtypes.last();
|
||||
|
@ -34,15 +34,14 @@ import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.comp.Attr.ResultInfo;
|
||||
import com.sun.tools.javac.comp.Infer.InferenceContext;
|
||||
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
|
||||
import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
@ -95,7 +94,18 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
make = TreeMaker.instance(context);
|
||||
types = Types.instance(context);
|
||||
Names names = Names.instance(context);
|
||||
stuckTree = make.Ident(names.empty).setType(Type.noType);
|
||||
stuckTree = make.Ident(names.empty).setType(Type.stuckType);
|
||||
emptyDeferredAttrContext =
|
||||
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
|
||||
@Override
|
||||
void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
|
||||
Assert.error("Empty deferred context!");
|
||||
}
|
||||
@Override
|
||||
void complete() {
|
||||
Assert.error("Empty deferred context!");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** shared tree for stuck expressions */
|
||||
@ -117,7 +127,7 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
DeferredType(JCExpression tree, Env<AttrContext> env) {
|
||||
super(null);
|
||||
this.tree = tree;
|
||||
this.env = env.dup(tree, env.info.dup());
|
||||
this.env = attr.copyEnv(env);
|
||||
this.speculativeCache = new SpeculativeCache();
|
||||
}
|
||||
|
||||
@ -253,7 +263,7 @@ 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.noType;
|
||||
return dt.tree.type = Type.stuckType;
|
||||
}
|
||||
};
|
||||
|
||||
@ -479,12 +489,10 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
|
||||
ResultInfo resultInfo;
|
||||
InferenceContext inferenceContext;
|
||||
Env<AttrContext> env;
|
||||
|
||||
public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
|
||||
this.resultInfo = resultInfo;
|
||||
this.inferenceContext = deferredAttrContext.inferenceContext;
|
||||
this.env = dt.env.dup(dt.tree, dt.env.info.dup());
|
||||
dt.tree.accept(this);
|
||||
dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
|
||||
return Type.noType;
|
||||
@ -533,18 +541,7 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
} catch (Types.FunctionDescriptorLookupError ex) {
|
||||
checkContext.report(null, ex.getDiagnostic());
|
||||
}
|
||||
JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), env,
|
||||
attr.memberReferenceQualifierResult(tree));
|
||||
ListBuffer<Type> argtypes = ListBuffer.lb();
|
||||
for (Type t : types.findDescriptorType(pt).getParameterTypes()) {
|
||||
argtypes.append(Type.noType);
|
||||
}
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ?> lookupRes =
|
||||
rs.resolveMemberReference(tree, env, mref2, exprTree.type,
|
||||
tree.name, argtypes.toList(), null, true, rs.arityMethodCheck);
|
||||
switch (lookupRes.fst.kind) {
|
||||
switch (tree.sym.kind) {
|
||||
//note: as argtypes are erroneous types, type-errors must
|
||||
//have been caused by arity mismatch
|
||||
case Kinds.ABSENT_MTH:
|
||||
@ -560,17 +557,7 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
}
|
||||
|
||||
/** an empty deferred attribution context - all methods throw exceptions */
|
||||
final DeferredAttrContext emptyDeferredAttrContext =
|
||||
new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null, null, null) {
|
||||
@Override
|
||||
void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
|
||||
Assert.error("Empty deferred context!");
|
||||
}
|
||||
@Override
|
||||
void complete() {
|
||||
Assert.error("Empty deferred context!");
|
||||
}
|
||||
};
|
||||
final DeferredAttrContext emptyDeferredAttrContext;
|
||||
|
||||
/**
|
||||
* Map a list of types possibly containing one or more deferred types
|
||||
@ -649,7 +636,12 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
* a default expected type (j.l.Object).
|
||||
*/
|
||||
private Type recover(DeferredType dt) {
|
||||
dt.check(attr.new RecoveryInfo(deferredAttrContext));
|
||||
dt.check(attr.new RecoveryInfo(deferredAttrContext) {
|
||||
@Override
|
||||
protected Type check(DiagnosticPosition pos, Type found) {
|
||||
return chk.checkNonVoid(pos, super.check(pos, found));
|
||||
}
|
||||
});
|
||||
return super.apply(dt);
|
||||
}
|
||||
}
|
||||
@ -663,12 +655,12 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
|
||||
return List.nil();
|
||||
} else {
|
||||
return stuckVarsInternal(tree, resultInfo.pt, resultInfo.checkContext.inferenceContext());
|
||||
return stuckVarsInternal(tree, resultInfo.pt, env, resultInfo.checkContext.inferenceContext());
|
||||
}
|
||||
}
|
||||
//where
|
||||
private List<Type> stuckVarsInternal(JCTree tree, Type pt, Infer.InferenceContext inferenceContext) {
|
||||
StuckChecker sc = new StuckChecker(pt, inferenceContext);
|
||||
private List<Type> stuckVarsInternal(JCTree tree, Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
|
||||
StuckChecker sc = new StuckChecker(pt, env, inferenceContext);
|
||||
sc.scan(tree);
|
||||
return List.from(sc.stuckVars);
|
||||
}
|
||||
@ -748,11 +740,13 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
class StuckChecker extends PolyScanner {
|
||||
|
||||
Type pt;
|
||||
Env<AttrContext> env;
|
||||
Infer.InferenceContext inferenceContext;
|
||||
Set<Type> stuckVars = new LinkedHashSet<Type>();
|
||||
|
||||
StuckChecker(Type pt, Infer.InferenceContext inferenceContext) {
|
||||
StuckChecker(Type pt, Env<AttrContext> env, Infer.InferenceContext inferenceContext) {
|
||||
this.pt = pt;
|
||||
this.env = env;
|
||||
this.inferenceContext = inferenceContext;
|
||||
}
|
||||
|
||||
@ -786,18 +780,41 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
|
||||
Type descType = types.findDescriptorType(pt);
|
||||
List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
|
||||
stuckVars.addAll(freeArgVars);
|
||||
Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
|
||||
if (freeArgVars.nonEmpty()) {
|
||||
//perform arity-based check
|
||||
JCExpression exprTree = (JCExpression)attribSpeculative(tree.getQualifierExpression(), localEnv,
|
||||
attr.memberReferenceQualifierResult(tree));
|
||||
ListBuffer<Type> argtypes = ListBuffer.lb();
|
||||
for (Type t : descType.getParameterTypes()) {
|
||||
argtypes.append(Type.noType);
|
||||
}
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ReferenceLookupHelper> lookupRes =
|
||||
rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
|
||||
tree.name, argtypes.toList(), null, true, rs.arityMethodCheck,
|
||||
inferenceContext);
|
||||
Symbol res = tree.sym = lookupRes.fst;
|
||||
if (res.kind >= Kinds.ERRONEOUS ||
|
||||
res.type.hasTag(FORALL) ||
|
||||
(res.flags() & Flags.VARARGS) != 0 ||
|
||||
(TreeInfo.isStaticSelector(exprTree, tree.name.table.names) &&
|
||||
exprTree.type.isRaw())) {
|
||||
stuckVars.addAll(freeArgVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scanLambdaBody(JCLambda lambda, final Type pt) {
|
||||
if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
|
||||
stuckVars.addAll(stuckVarsInternal(lambda.body, pt, inferenceContext));
|
||||
stuckVars.addAll(stuckVarsInternal(lambda.body, pt, env, inferenceContext));
|
||||
} else {
|
||||
LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() {
|
||||
@Override
|
||||
public void visitReturn(JCReturn tree) {
|
||||
if (tree.expr != null) {
|
||||
stuckVars.addAll(stuckVarsInternal(tree.expr, pt, inferenceContext));
|
||||
stuckVars.addAll(stuckVarsInternal(tree.expr, pt, env, inferenceContext));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -941,12 +958,13 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
attribSpeculative(rec, env, attr.unknownTypeExprInfo).type :
|
||||
env.enclClass.sym.type;
|
||||
|
||||
ListBuffer<Type> args = ListBuffer.lb();
|
||||
for (int i = 0; i < tree.args.length(); i ++) {
|
||||
args.append(Type.noType);
|
||||
while (site.hasTag(TYPEVAR)) {
|
||||
site = site.getUpperBound();
|
||||
}
|
||||
|
||||
Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args.toList(), List.<Type>nil(), MethodResolutionPhase.VARARITY) {
|
||||
List<Type> args = rs.dummyArgs(tree.args.length());
|
||||
|
||||
Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.<Type>nil(), MethodResolutionPhase.VARARITY) {
|
||||
@Override
|
||||
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
|
||||
return rec == null ?
|
||||
|
@ -373,6 +373,15 @@ public class Flow {
|
||||
boolean resolveBreaks(JCTree tree, ListBuffer<P> oldPendingExits) {
|
||||
return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scan(JCTree tree) {
|
||||
if (tree != null && (
|
||||
tree.type == null ||
|
||||
tree.type != Type.stuckType)) {
|
||||
super.scan(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,9 +41,11 @@ import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
|
||||
import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
|
||||
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -149,7 +151,7 @@ public class Infer {
|
||||
inferenceException.clear();
|
||||
try {
|
||||
DeferredAttr.DeferredAttrContext deferredAttrContext =
|
||||
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
|
||||
resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
|
||||
|
||||
resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext,
|
||||
argtypes, mt.getParameterTypes(), warn);
|
||||
@ -159,7 +161,8 @@ public class Infer {
|
||||
!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
|
||||
//inject return constraints earlier
|
||||
checkWithinBounds(inferenceContext, warn); //propagation
|
||||
generateReturnConstraints(resultInfo, mt, inferenceContext);
|
||||
Type newRestype = generateReturnConstraints(resultInfo, mt, inferenceContext);
|
||||
mt = (MethodType)types.createMethodTypeWithReturn(mt, newRestype);
|
||||
//propagate outwards if needed
|
||||
if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
|
||||
//propagate inference context outwards and exit
|
||||
@ -209,9 +212,20 @@ public class Infer {
|
||||
* call occurs in a context where a type T is expected, use the expected
|
||||
* type to derive more constraints on the generic method inference variables.
|
||||
*/
|
||||
void generateReturnConstraints(Attr.ResultInfo resultInfo,
|
||||
Type generateReturnConstraints(Attr.ResultInfo resultInfo,
|
||||
MethodType mt, InferenceContext inferenceContext) {
|
||||
Type qtype1 = inferenceContext.asFree(mt.getReturnType());
|
||||
Type from = mt.getReturnType();
|
||||
if (mt.getReturnType().containsAny(inferenceContext.inferencevars) &&
|
||||
resultInfo.checkContext.inferenceContext() != emptyContext) {
|
||||
from = types.capture(from);
|
||||
//add synthetic captured ivars
|
||||
for (Type t : from.getTypeArguments()) {
|
||||
if (t.hasTag(TYPEVAR) && ((TypeVar)t).isCaptured()) {
|
||||
inferenceContext.addVar((TypeVar)t);
|
||||
}
|
||||
}
|
||||
}
|
||||
Type qtype1 = inferenceContext.asFree(from);
|
||||
Type to = returnConstraintTarget(qtype1, resultInfo.pt);
|
||||
Assert.check(allowGraphInference || !resultInfo.checkContext.inferenceContext().free(to),
|
||||
"legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
|
||||
@ -224,33 +238,34 @@ public class Infer {
|
||||
.setMessage("infer.no.conforming.instance.exists",
|
||||
inferenceContext.restvars(), mt.getReturnType(), to);
|
||||
}
|
||||
return from;
|
||||
}
|
||||
//where
|
||||
private Type returnConstraintTarget(Type from, Type to) {
|
||||
if (from.hasTag(VOID)) {
|
||||
return syms.voidType;
|
||||
} else if (to.hasTag(NONE)) {
|
||||
return from.isPrimitive() ? from : syms.objectType;
|
||||
} else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
|
||||
if (!allowGraphInference) {
|
||||
//if legacy, just return boxed type
|
||||
return types.boxedClass(to).type;
|
||||
}
|
||||
//if graph inference we need to skip conflicting boxed bounds...
|
||||
UndetVar uv = (UndetVar)from;
|
||||
for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
|
||||
Type boundAsPrimitive = types.unboxedType(t);
|
||||
if (boundAsPrimitive == null) continue;
|
||||
if (types.isConvertible(boundAsPrimitive, to)) {
|
||||
//effectively skip return-type constraint generation (compatibility)
|
||||
return syms.objectType;
|
||||
}
|
||||
}
|
||||
|
||||
Type returnConstraintTarget(Type from, Type to) {
|
||||
if (from.hasTag(VOID)) {
|
||||
return syms.voidType;
|
||||
} else if (to.hasTag(NONE)) {
|
||||
return from.isPrimitive() ? from : syms.objectType;
|
||||
} else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
|
||||
if (!allowGraphInference) {
|
||||
//if legacy, just return boxed type
|
||||
return types.boxedClass(to).type;
|
||||
} else {
|
||||
return to;
|
||||
}
|
||||
//if graph inference we need to skip conflicting boxed bounds...
|
||||
UndetVar uv = (UndetVar)from;
|
||||
for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
|
||||
Type boundAsPrimitive = types.unboxedType(t);
|
||||
if (boundAsPrimitive == null) continue;
|
||||
if (types.isConvertible(boundAsPrimitive, to)) {
|
||||
//effectively skip return-type constraint generation (compatibility)
|
||||
return syms.objectType;
|
||||
}
|
||||
}
|
||||
return types.boxedClass(to).type;
|
||||
} else {
|
||||
return to;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Infer cyclic inference variables as described in 15.12.2.8.
|
||||
@ -418,6 +433,7 @@ public class Infer {
|
||||
void checkWithinBounds(InferenceContext inferenceContext,
|
||||
Warner warn) throws InferenceException {
|
||||
MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
|
||||
List<Type> saved_undet = inferenceContext.save();
|
||||
try {
|
||||
while (true) {
|
||||
mlistener.reset();
|
||||
@ -435,7 +451,9 @@ public class Infer {
|
||||
EnumSet<IncorporationStep> incorporationSteps = allowGraphInference ?
|
||||
incorporationStepsGraph : incorporationStepsLegacy;
|
||||
for (IncorporationStep is : incorporationSteps) {
|
||||
is.apply(uv, inferenceContext, warn);
|
||||
if (is.accepts(uv, inferenceContext)) {
|
||||
is.apply(uv, inferenceContext, warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!mlistener.changed || !allowGraphInference) break;
|
||||
@ -443,6 +461,10 @@ public class Infer {
|
||||
}
|
||||
finally {
|
||||
mlistener.detach();
|
||||
if (incorporationCache.size() == MAX_INCORPORATION_STEPS) {
|
||||
inferenceContext.rollback(saved_undet);
|
||||
}
|
||||
incorporationCache.clear();
|
||||
}
|
||||
}
|
||||
//where
|
||||
@ -454,7 +476,6 @@ public class Infer {
|
||||
*/
|
||||
class MultiUndetVarListener implements UndetVar.UndetVarListener {
|
||||
|
||||
int rounds;
|
||||
boolean changed;
|
||||
List<Type> undetvars;
|
||||
|
||||
@ -468,13 +489,12 @@ public class Infer {
|
||||
|
||||
public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
|
||||
//avoid non-termination
|
||||
if (rounds < MAX_INCORPORATION_STEPS) {
|
||||
if (incorporationCache.size() < MAX_INCORPORATION_STEPS) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
rounds++;
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@ -507,22 +527,27 @@ public class Infer {
|
||||
if (uv.inst != null) {
|
||||
Type inst = uv.inst;
|
||||
for (Type u : uv.getBounds(InferenceBound.UPPER)) {
|
||||
if (!infer.types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) {
|
||||
if (!isSubtype(inst, inferenceContext.asFree(u), warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.UPPER);
|
||||
}
|
||||
}
|
||||
for (Type l : uv.getBounds(InferenceBound.LOWER)) {
|
||||
if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), inst, warn)) {
|
||||
if (!isSubtype(inferenceContext.asFree(l), inst, warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.LOWER);
|
||||
}
|
||||
}
|
||||
for (Type e : uv.getBounds(InferenceBound.EQ)) {
|
||||
if (!infer.types.isSameType(inst, inferenceContext.asFree(e))) {
|
||||
if (!isSameType(inst, inferenceContext.asFree(e), infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.EQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
boolean accepts(UndetVar uv, InferenceContext inferenceContext) {
|
||||
//applies to all undetvars
|
||||
return true;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Check consistency of equality constraints. This is a slightly more aggressive
|
||||
@ -535,19 +560,19 @@ public class Infer {
|
||||
Type eq = null;
|
||||
for (Type e : uv.getBounds(InferenceBound.EQ)) {
|
||||
Assert.check(!inferenceContext.free(e));
|
||||
if (eq != null && !infer.types.isSameType(e, eq)) {
|
||||
if (eq != null && !isSameType(e, eq, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.EQ);
|
||||
}
|
||||
eq = e;
|
||||
for (Type l : uv.getBounds(InferenceBound.LOWER)) {
|
||||
Assert.check(!inferenceContext.free(l));
|
||||
if (!infer.types.isSubtypeUnchecked(l, e, warn)) {
|
||||
if (!isSubtype(l, e, warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
|
||||
}
|
||||
}
|
||||
for (Type u : uv.getBounds(InferenceBound.UPPER)) {
|
||||
if (inferenceContext.free(u)) continue;
|
||||
if (!infer.types.isSubtypeUnchecked(e, u, warn)) {
|
||||
if (!isSubtype(e, u, warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
|
||||
}
|
||||
}
|
||||
@ -563,12 +588,12 @@ public class Infer {
|
||||
for (Type e : uv.getBounds(InferenceBound.EQ)) {
|
||||
if (e.containsAny(inferenceContext.inferenceVars())) continue;
|
||||
for (Type u : uv.getBounds(InferenceBound.UPPER)) {
|
||||
if (!infer.types.isSubtypeUnchecked(e, inferenceContext.asFree(u), warn)) {
|
||||
if (!isSubtype(e, inferenceContext.asFree(u), warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
|
||||
}
|
||||
}
|
||||
for (Type l : uv.getBounds(InferenceBound.LOWER)) {
|
||||
if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), e, warn)) {
|
||||
if (!isSubtype(inferenceContext.asFree(l), e, warn, infer)) {
|
||||
infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
|
||||
}
|
||||
}
|
||||
@ -584,7 +609,7 @@ public class Infer {
|
||||
Infer infer = inferenceContext.infer();
|
||||
for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
|
||||
for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
|
||||
infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
|
||||
isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn , infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -598,7 +623,7 @@ public class Infer {
|
||||
Infer infer = inferenceContext.infer();
|
||||
for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
|
||||
for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
|
||||
infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
|
||||
isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,7 +637,7 @@ public class Infer {
|
||||
Infer infer = inferenceContext.infer();
|
||||
for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
|
||||
for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
|
||||
infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
|
||||
isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -627,7 +652,7 @@ public class Infer {
|
||||
for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
|
||||
for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
|
||||
if (b1 != b2) {
|
||||
infer.types.isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
|
||||
isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1), infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -643,16 +668,17 @@ public class Infer {
|
||||
for (Type b : uv.getBounds(InferenceBound.UPPER)) {
|
||||
if (inferenceContext.inferenceVars().contains(b)) {
|
||||
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
|
||||
if (uv2.isCaptured()) continue;
|
||||
//alpha <: beta
|
||||
//0. set beta :> alpha
|
||||
uv2.addBound(InferenceBound.LOWER, uv.qtype, infer.types);
|
||||
addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(uv.qtype), infer);
|
||||
//1. copy alpha's lower to beta's
|
||||
for (Type l : uv.getBounds(InferenceBound.LOWER)) {
|
||||
uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
|
||||
addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(l), infer);
|
||||
}
|
||||
//2. copy beta's upper to alpha's
|
||||
for (Type u : uv2.getBounds(InferenceBound.UPPER)) {
|
||||
uv.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
|
||||
addBound(InferenceBound.UPPER, uv, inferenceContext.asInstType(u), infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -668,16 +694,17 @@ public class Infer {
|
||||
for (Type b : uv.getBounds(InferenceBound.LOWER)) {
|
||||
if (inferenceContext.inferenceVars().contains(b)) {
|
||||
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
|
||||
if (uv2.isCaptured()) continue;
|
||||
//alpha :> beta
|
||||
//0. set beta <: alpha
|
||||
uv2.addBound(InferenceBound.UPPER, uv.qtype, infer.types);
|
||||
addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(uv.qtype), infer);
|
||||
//1. copy alpha's upper to beta's
|
||||
for (Type u : uv.getBounds(InferenceBound.UPPER)) {
|
||||
uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
|
||||
addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(u), infer);
|
||||
}
|
||||
//2. copy beta's lower to alpha's
|
||||
for (Type l : uv2.getBounds(InferenceBound.LOWER)) {
|
||||
uv.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
|
||||
addBound(InferenceBound.LOWER, uv, inferenceContext.asInstType(l), infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -693,14 +720,15 @@ public class Infer {
|
||||
for (Type b : uv.getBounds(InferenceBound.EQ)) {
|
||||
if (inferenceContext.inferenceVars().contains(b)) {
|
||||
UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
|
||||
if (uv2.isCaptured()) continue;
|
||||
//alpha == beta
|
||||
//0. set beta == alpha
|
||||
uv2.addBound(InferenceBound.EQ, uv.qtype, infer.types);
|
||||
addBound(InferenceBound.EQ, uv2, inferenceContext.asInstType(uv.qtype), infer);
|
||||
//1. copy all alpha's bounds to beta's
|
||||
for (InferenceBound ib : InferenceBound.values()) {
|
||||
for (Type b2 : uv.getBounds(ib)) {
|
||||
if (b2 != uv2) {
|
||||
uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types);
|
||||
addBound(ib, uv2, inferenceContext.asInstType(b2), infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -708,7 +736,7 @@ public class Infer {
|
||||
for (InferenceBound ib : InferenceBound.values()) {
|
||||
for (Type b2 : uv2.getBounds(ib)) {
|
||||
if (b2 != uv) {
|
||||
uv.addBound(ib, inferenceContext.asInstType(b2), infer.types);
|
||||
addBound(ib, uv, inferenceContext.asInstType(b2), infer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -718,6 +746,45 @@ public class Infer {
|
||||
};
|
||||
|
||||
abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn);
|
||||
|
||||
boolean accepts(UndetVar uv, InferenceContext inferenceContext) {
|
||||
return !uv.isCaptured();
|
||||
}
|
||||
|
||||
boolean isSubtype(Type s, Type t, Warner warn, Infer infer) {
|
||||
return doIncorporationOp(IncorporationBinaryOpKind.IS_SUBTYPE, s, t, warn, infer);
|
||||
}
|
||||
|
||||
boolean isSameType(Type s, Type t, Infer infer) {
|
||||
return doIncorporationOp(IncorporationBinaryOpKind.IS_SAME_TYPE, s, t, null, infer);
|
||||
}
|
||||
|
||||
void addBound(InferenceBound ib, UndetVar uv, Type b, Infer infer) {
|
||||
doIncorporationOp(opFor(ib), uv, b, null, infer);
|
||||
}
|
||||
|
||||
IncorporationBinaryOpKind opFor(InferenceBound boundKind) {
|
||||
switch (boundKind) {
|
||||
case EQ:
|
||||
return IncorporationBinaryOpKind.ADD_EQ_BOUND;
|
||||
case LOWER:
|
||||
return IncorporationBinaryOpKind.ADD_LOWER_BOUND;
|
||||
case UPPER:
|
||||
return IncorporationBinaryOpKind.ADD_UPPER_BOUND;
|
||||
default:
|
||||
Assert.error("Can't get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean doIncorporationOp(IncorporationBinaryOpKind opKind, Type op1, Type op2, Warner warn, Infer infer) {
|
||||
IncorporationBinaryOp newOp = infer.new IncorporationBinaryOp(opKind, op1, op2);
|
||||
Boolean res = infer.incorporationCache.get(newOp);
|
||||
if (res == null) {
|
||||
infer.incorporationCache.put(newOp, res = newOp.apply(warn));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/** incorporation steps to be executed when running in legacy mode */
|
||||
@ -727,6 +794,102 @@ public class Infer {
|
||||
EnumSet<IncorporationStep> incorporationStepsGraph =
|
||||
EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY));
|
||||
|
||||
/**
|
||||
* Three kinds of basic operation are supported as part of an incorporation step:
|
||||
* (i) subtype check, (ii) same type check and (iii) bound addition (either
|
||||
* upper/lower/eq bound).
|
||||
*/
|
||||
enum IncorporationBinaryOpKind {
|
||||
IS_SUBTYPE() {
|
||||
@Override
|
||||
boolean apply(Type op1, Type op2, Warner warn, Types types) {
|
||||
return types.isSubtypeUnchecked(op1, op2, warn);
|
||||
}
|
||||
},
|
||||
IS_SAME_TYPE() {
|
||||
@Override
|
||||
boolean apply(Type op1, Type op2, Warner warn, Types types) {
|
||||
return types.isSameType(op1, op2);
|
||||
}
|
||||
},
|
||||
ADD_UPPER_BOUND() {
|
||||
@Override
|
||||
boolean apply(Type op1, Type op2, Warner warn, Types types) {
|
||||
UndetVar uv = (UndetVar)op1;
|
||||
uv.addBound(InferenceBound.UPPER, op2, types);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
ADD_LOWER_BOUND() {
|
||||
@Override
|
||||
boolean apply(Type op1, Type op2, Warner warn, Types types) {
|
||||
UndetVar uv = (UndetVar)op1;
|
||||
uv.addBound(InferenceBound.LOWER, op2, types);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
ADD_EQ_BOUND() {
|
||||
@Override
|
||||
boolean apply(Type op1, Type op2, Warner warn, Types types) {
|
||||
UndetVar uv = (UndetVar)op1;
|
||||
uv.addBound(InferenceBound.EQ, op2, types);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
abstract boolean apply(Type op1, Type op2, Warner warn, Types types);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class encapsulates a basic incorporation operation; incorporation
|
||||
* operations takes two type operands and a kind. Each operation performed
|
||||
* during an incorporation round is stored in a cache, so that operations
|
||||
* are not executed unnecessarily (which would potentially lead to adding
|
||||
* same bounds over and over).
|
||||
*/
|
||||
class IncorporationBinaryOp {
|
||||
|
||||
IncorporationBinaryOpKind opKind;
|
||||
Type op1;
|
||||
Type op2;
|
||||
|
||||
IncorporationBinaryOp(IncorporationBinaryOpKind opKind, Type op1, Type op2) {
|
||||
this.opKind = opKind;
|
||||
this.op1 = op1;
|
||||
this.op2 = op2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof IncorporationBinaryOp)) {
|
||||
return false;
|
||||
} else {
|
||||
IncorporationBinaryOp that = (IncorporationBinaryOp)o;
|
||||
return opKind == that.opKind &&
|
||||
types.isSameType(op1, that.op1, true) &&
|
||||
types.isSameType(op2, that.op2, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = opKind.hashCode();
|
||||
result *= 127;
|
||||
result += types.hashCode(op1);
|
||||
result *= 127;
|
||||
result += types.hashCode(op2);
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean apply(Warner warn) {
|
||||
return opKind.apply(op1, op2, warn, types);
|
||||
}
|
||||
}
|
||||
|
||||
/** an incorporation cache keeps track of all executed incorporation-related operations */
|
||||
Map<IncorporationBinaryOp, Boolean> incorporationCache =
|
||||
new HashMap<IncorporationBinaryOp, Boolean>();
|
||||
|
||||
/**
|
||||
* Make sure that the upper bounds we got so far lead to a solvable inference
|
||||
* variable by making sure that a glb exists.
|
||||
@ -862,6 +1025,41 @@ public class Infer {
|
||||
Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
|
||||
return g.nodes.get(0);
|
||||
}
|
||||
|
||||
boolean isSubtype(Type s, Type t, Warner warn, Infer infer) {
|
||||
return doIncorporationOp(IncorporationBinaryOpKind.IS_SUBTYPE, s, t, warn, infer);
|
||||
}
|
||||
|
||||
boolean isSameType(Type s, Type t, Infer infer) {
|
||||
return doIncorporationOp(IncorporationBinaryOpKind.IS_SAME_TYPE, s, t, null, infer);
|
||||
}
|
||||
|
||||
void addBound(InferenceBound ib, UndetVar uv, Type b, Infer infer) {
|
||||
doIncorporationOp(opFor(ib), uv, b, null, infer);
|
||||
}
|
||||
|
||||
IncorporationBinaryOpKind opFor(InferenceBound boundKind) {
|
||||
switch (boundKind) {
|
||||
case EQ:
|
||||
return IncorporationBinaryOpKind.ADD_EQ_BOUND;
|
||||
case LOWER:
|
||||
return IncorporationBinaryOpKind.ADD_LOWER_BOUND;
|
||||
case UPPER:
|
||||
return IncorporationBinaryOpKind.ADD_UPPER_BOUND;
|
||||
default:
|
||||
Assert.error("Can't get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean doIncorporationOp(IncorporationBinaryOpKind opKind, Type op1, Type op2, Warner warn, Infer infer) {
|
||||
IncorporationBinaryOp newOp = infer.new IncorporationBinaryOp(opKind, op1, op2);
|
||||
Boolean res = infer.incorporationCache.get(newOp);
|
||||
if (res == null) {
|
||||
infer.incorporationCache.put(newOp, res = newOp.apply(warn));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -878,27 +1076,32 @@ public class Infer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cost associated with a given node; the cost is computed
|
||||
* as the total number of type-variables that should be eagerly instantiated
|
||||
* in order to get to some of the variables in {@code varsToSolve} from
|
||||
* a given node
|
||||
* Computes the minimum path that goes from a given node to any of the nodes
|
||||
* containing a variable in {@code varsToSolve}. For any given path, the cost
|
||||
* is computed as the total number of type-variables that should be eagerly
|
||||
* instantiated across that path.
|
||||
*/
|
||||
void computeCostIfNeeded(Node n, Map<Node, Integer> costMap) {
|
||||
if (costMap.containsKey(n)) {
|
||||
return;
|
||||
} else if (!Collections.disjoint(n.data, varsToSolve)) {
|
||||
costMap.put(n, n.data.size());
|
||||
int computeMinPath(InferenceGraph g, Node n) {
|
||||
return computeMinPath(g, n, List.<Node>nil(), 0);
|
||||
}
|
||||
|
||||
int computeMinPath(InferenceGraph g, Node n, List<Node> path, int cost) {
|
||||
if (path.contains(n)) return Integer.MAX_VALUE;
|
||||
List<Node> path2 = path.prepend(n);
|
||||
int cost2 = cost + n.data.size();
|
||||
if (!Collections.disjoint(n.data, varsToSolve)) {
|
||||
return cost2;
|
||||
} else {
|
||||
int subcost = Integer.MAX_VALUE;
|
||||
costMap.put(n, subcost); //avoid loops
|
||||
for (Node n2 : n.getDependencies()) {
|
||||
computeCostIfNeeded(n2, costMap);
|
||||
subcost = Math.min(costMap.get(n2), subcost);
|
||||
int bestPath = Integer.MAX_VALUE;
|
||||
for (Node n2 : g.nodes) {
|
||||
if (n2.deps.contains(n)) {
|
||||
int res = computeMinPath(g, n2, path2, cost2);
|
||||
if (res < bestPath) {
|
||||
bestPath = res;
|
||||
}
|
||||
}
|
||||
}
|
||||
//update cost map to reflect real cost
|
||||
costMap.put(n, subcost == Integer.MAX_VALUE ?
|
||||
Integer.MAX_VALUE :
|
||||
n.data.size() + subcost);
|
||||
return bestPath;
|
||||
}
|
||||
}
|
||||
|
||||
@ -907,21 +1110,20 @@ public class Infer {
|
||||
*/
|
||||
@Override
|
||||
public Node pickNode(final InferenceGraph g) {
|
||||
final Map<Node, Integer> costMap = new HashMap<Node, Integer>();
|
||||
ArrayList<Node> leaves = new ArrayList<Node>();
|
||||
final Map<Node, Integer> leavesMap = new HashMap<Node, Integer>();
|
||||
for (Node n : g.nodes) {
|
||||
computeCostIfNeeded(n, costMap);
|
||||
if (n.isLeaf(n)) {
|
||||
leaves.add(n);
|
||||
leavesMap.put(n, computeMinPath(g, n));
|
||||
}
|
||||
}
|
||||
Assert.check(!leaves.isEmpty(), "No nodes to solve!");
|
||||
Collections.sort(leaves, new java.util.Comparator<Node>() {
|
||||
Assert.check(!leavesMap.isEmpty(), "No nodes to solve!");
|
||||
TreeSet<Node> orderedLeaves = new TreeSet<Node>(new Comparator<Node>() {
|
||||
public int compare(Node n1, Node n2) {
|
||||
return costMap.get(n1) - costMap.get(n2);
|
||||
return leavesMap.get(n1) - leavesMap.get(n2);
|
||||
}
|
||||
});
|
||||
return leaves.get(0);
|
||||
orderedLeaves.addAll(leavesMap.keySet());
|
||||
return orderedLeaves.first();
|
||||
}
|
||||
}
|
||||
|
||||
@ -963,6 +1165,39 @@ public class Infer {
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Infer uninstantiated/unbound inference variables occurring in 'throws'
|
||||
* clause as RuntimeException
|
||||
*/
|
||||
THROWS(InferenceBound.UPPER) {
|
||||
@Override
|
||||
public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
|
||||
if ((t.qtype.tsym.flags() & Flags.THROWS) == 0) {
|
||||
//not a throws undet var
|
||||
return false;
|
||||
}
|
||||
if (t.getBounds(InferenceBound.EQ, InferenceBound.LOWER, InferenceBound.UPPER)
|
||||
.diff(t.getDeclaredBounds()).nonEmpty()) {
|
||||
//not an unbounded undet var
|
||||
return false;
|
||||
}
|
||||
Infer infer = inferenceContext.infer();
|
||||
for (Type db : t.getDeclaredBounds()) {
|
||||
if (t.isInterface()) continue;
|
||||
if (infer.types.asSuper(infer.syms.runtimeExceptionType, db.tsym) != null) {
|
||||
//declared bound is a supertype of RuntimeException
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//declared bound is more specific then RuntimeException - give up
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
Type solve(UndetVar uv, InferenceContext inferenceContext) {
|
||||
return inferenceContext.infer().syms.runtimeExceptionType;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Instantiate an inference variables using its (ground) upper bounds. Such
|
||||
* bounds are merged together using glb().
|
||||
@ -990,13 +1225,36 @@ public class Infer {
|
||||
UPPER_LEGACY(InferenceBound.UPPER) {
|
||||
@Override
|
||||
public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
|
||||
return !inferenceContext.free(t.getBounds(ib));
|
||||
return !inferenceContext.free(t.getBounds(ib)) && !t.isCaptured();
|
||||
}
|
||||
|
||||
@Override
|
||||
Type solve(UndetVar uv, InferenceContext inferenceContext) {
|
||||
return UPPER.solve(uv, inferenceContext);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Like the former; the only difference is that this step can only be applied
|
||||
* if all upper/lower bounds are ground.
|
||||
*/
|
||||
CAPTURED(InferenceBound.UPPER) {
|
||||
@Override
|
||||
public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
|
||||
return !inferenceContext.free(t.getBounds(InferenceBound.UPPER, InferenceBound.LOWER));
|
||||
}
|
||||
|
||||
@Override
|
||||
Type solve(UndetVar uv, InferenceContext inferenceContext) {
|
||||
Infer infer = inferenceContext.infer();
|
||||
Type upper = UPPER.filterBounds(uv, inferenceContext).nonEmpty() ?
|
||||
UPPER.solve(uv, inferenceContext) :
|
||||
infer.syms.objectType;
|
||||
Type lower = LOWER.filterBounds(uv, inferenceContext).nonEmpty() ?
|
||||
LOWER.solve(uv, inferenceContext) :
|
||||
infer.syms.botType;
|
||||
CapturedType prevCaptured = (CapturedType)uv.qtype;
|
||||
return new CapturedType(prevCaptured.tsym.name, prevCaptured.tsym.owner, upper, lower, prevCaptured.wildcard);
|
||||
}
|
||||
};
|
||||
|
||||
final InferenceBound ib;
|
||||
@ -1015,7 +1273,7 @@ public class Infer {
|
||||
* Can the inference variable be instantiated using this step?
|
||||
*/
|
||||
public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
|
||||
return filterBounds(t, inferenceContext).nonEmpty();
|
||||
return filterBounds(t, inferenceContext).nonEmpty() && !t.isCaptured();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1052,7 +1310,7 @@ public class Infer {
|
||||
|
||||
EQ(EnumSet.of(InferenceStep.EQ)),
|
||||
EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
|
||||
EQ_LOWER_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER));
|
||||
EQ_LOWER_THROWS_UPPER_CAPTURED(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER, InferenceStep.THROWS, InferenceStep.CAPTURED));
|
||||
|
||||
final EnumSet<InferenceStep> steps;
|
||||
|
||||
@ -1090,7 +1348,7 @@ public class Infer {
|
||||
while (!sstrategy.done()) {
|
||||
InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
|
||||
List<Type> varsToSolve = List.from(nodeToSolve.data);
|
||||
inferenceContext.save();
|
||||
List<Type> saved_undet = inferenceContext.save();
|
||||
try {
|
||||
//repeat until all variables are solved
|
||||
outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
|
||||
@ -1107,7 +1365,7 @@ public class Infer {
|
||||
}
|
||||
catch (InferenceException ex) {
|
||||
//did we fail because of interdependent ivars?
|
||||
inferenceContext.rollback();
|
||||
inferenceContext.rollback(saved_undet);
|
||||
instantiateAsUninferredVars(varsToSolve, inferenceContext);
|
||||
checkWithinBounds(inferenceContext, warn);
|
||||
}
|
||||
@ -1300,9 +1558,6 @@ public class Infer {
|
||||
/** list of inference vars in this context */
|
||||
List<Type> inferencevars;
|
||||
|
||||
/** backed up inference variables */
|
||||
List<Type> saved_undet;
|
||||
|
||||
java.util.Map<FreeTypeListener, List<Type>> freeTypeListeners =
|
||||
new java.util.HashMap<FreeTypeListener, List<Type>>();
|
||||
|
||||
@ -1316,11 +1571,25 @@ public class Infer {
|
||||
Mapping fromTypeVarFun = new Mapping("fromTypeVarFunWithBounds") {
|
||||
// mapping that turns inference variables into undet vars
|
||||
public Type apply(Type t) {
|
||||
if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types);
|
||||
else return t.map(this);
|
||||
if (t.hasTag(TYPEVAR)) {
|
||||
TypeVar tv = (TypeVar)t;
|
||||
return tv.isCaptured() ?
|
||||
new CapturedUndetVar((CapturedType)tv, types) :
|
||||
new UndetVar(tv, types);
|
||||
} else {
|
||||
return t.map(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* add a new inference var to this inference context
|
||||
*/
|
||||
void addVar(TypeVar t) {
|
||||
this.undetvars = this.undetvars.prepend(fromTypeVarFun.apply(t));
|
||||
this.inferencevars = this.inferencevars.prepend(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the list of free variables (as type-variables) in this
|
||||
* inference context
|
||||
@ -1502,7 +1771,7 @@ public class Infer {
|
||||
/**
|
||||
* Save the state of this inference context
|
||||
*/
|
||||
void save() {
|
||||
List<Type> save() {
|
||||
ListBuffer<Type> buf = ListBuffer.lb();
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
@ -1515,16 +1784,24 @@ public class Infer {
|
||||
uv2.inst = uv.inst;
|
||||
buf.add(uv2);
|
||||
}
|
||||
saved_undet = buf.toList();
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the state of this inference context to the previous known checkpoint
|
||||
*/
|
||||
void rollback() {
|
||||
Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
|
||||
undetvars = saved_undet;
|
||||
saved_undet = null;
|
||||
void rollback(List<Type> saved_undet) {
|
||||
Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
|
||||
//restore bounds (note: we need to preserve the old instances)
|
||||
for (Type t : undetvars) {
|
||||
UndetVar uv = (UndetVar)t;
|
||||
UndetVar uv_saved = (UndetVar)saved_undet.head;
|
||||
for (InferenceBound ib : InferenceBound.values()) {
|
||||
uv.setBounds(ib, uv_saved.getBounds(ib));
|
||||
}
|
||||
uv.inst = uv_saved.inst;
|
||||
saved_undet = saved_undet.tail;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,7 +358,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
* @param thrown The method's thrown exceptions.
|
||||
* @param env The method's (local) environment.
|
||||
*/
|
||||
Type signature(List<JCTypeParameter> typarams,
|
||||
Type signature(MethodSymbol msym,
|
||||
List<JCTypeParameter> typarams,
|
||||
List<JCVariableDecl> params,
|
||||
JCTree res,
|
||||
JCVariableDecl recvparam,
|
||||
@ -392,8 +393,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
|
||||
for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
|
||||
Type exc = attr.attribType(l.head, env);
|
||||
if (!exc.hasTag(TYPEVAR))
|
||||
if (!exc.hasTag(TYPEVAR)) {
|
||||
exc = chk.checkClassType(l.head.pos(), exc);
|
||||
} else if (exc.tsym.owner == msym) {
|
||||
//mark inference variables in 'throws' clause
|
||||
exc.tsym.flags_field |= THROWS;
|
||||
}
|
||||
thrownbuf.append(exc);
|
||||
}
|
||||
MethodType mtype = new MethodType(argbuf.toList(),
|
||||
@ -503,11 +508,17 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
// process package annotations
|
||||
annotateLater(tree.packageAnnotations, env, tree.packge);
|
||||
|
||||
// Import-on-demand java.lang.
|
||||
importAll(tree.pos, reader.enterPackage(names.java_lang), env);
|
||||
DeferredLintHandler prevLintHandler = chk.setDeferredLintHandler(DeferredLintHandler.immediateHandler);
|
||||
|
||||
// Process all import clauses.
|
||||
memberEnter(tree.defs, env);
|
||||
try {
|
||||
// Import-on-demand java.lang.
|
||||
importAll(tree.pos, reader.enterPackage(names.java_lang), env);
|
||||
|
||||
// Process all import clauses.
|
||||
memberEnter(tree.defs, env);
|
||||
} finally {
|
||||
chk.setDeferredLintHandler(prevLintHandler);
|
||||
}
|
||||
}
|
||||
|
||||
// process the non-static imports and the static imports of types.
|
||||
@ -557,7 +568,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
|
||||
try {
|
||||
// Compute the method type
|
||||
m.type = signature(tree.typarams, tree.params,
|
||||
m.type = signature(m, tree.typarams, tree.params,
|
||||
tree.restype, tree.recvparam,
|
||||
tree.thrown,
|
||||
localEnv);
|
||||
|
@ -345,7 +345,7 @@ public class Resolve {
|
||||
|
||||
boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
|
||||
return (t.hasTag(ARRAY))
|
||||
? isAccessible(env, types.elemtype(t))
|
||||
? isAccessible(env, types.upperBound(types.elemtype(t)))
|
||||
: isAccessible(env, t.tsym, checkInner);
|
||||
}
|
||||
|
||||
@ -584,6 +584,13 @@ public class Resolve {
|
||||
try {
|
||||
currentResolutionContext = new MethodResolutionContext();
|
||||
currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
|
||||
if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
|
||||
//method/constructor references need special check class
|
||||
//to handle inference variables in 'argtypes' (might happen
|
||||
//during an unsticking round)
|
||||
currentResolutionContext.methodCheck =
|
||||
new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
|
||||
}
|
||||
MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
|
||||
return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
|
||||
step.isBoxingRequired(), step.isVarargsRequired(), warn);
|
||||
@ -773,6 +780,14 @@ public class Resolve {
|
||||
}
|
||||
};
|
||||
|
||||
List<Type> dummyArgs(int length) {
|
||||
ListBuffer<Type> buf = ListBuffer.lb();
|
||||
for (int i = 0 ; i < length ; i++) {
|
||||
buf.append(Type.noType);
|
||||
}
|
||||
return buf.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method applicability routine. Given a list of actual types A,
|
||||
* a list of formal types F, determines whether the types in A are
|
||||
@ -850,6 +865,47 @@ public class Resolve {
|
||||
}
|
||||
};
|
||||
|
||||
class MethodReferenceCheck extends AbstractMethodCheck {
|
||||
|
||||
InferenceContext pendingInferenceContext;
|
||||
|
||||
MethodReferenceCheck(InferenceContext pendingInferenceContext) {
|
||||
this.pendingInferenceContext = pendingInferenceContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
|
||||
ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
|
||||
mresult.check(pos, actual);
|
||||
}
|
||||
|
||||
private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
|
||||
final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
|
||||
CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
|
||||
MethodCheckDiag methodDiag = varargsCheck ?
|
||||
MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
|
||||
|
||||
@Override
|
||||
public boolean compatible(Type found, Type req, Warner warn) {
|
||||
found = pendingInferenceContext.asFree(found);
|
||||
req = infer.returnConstraintTarget(found, req);
|
||||
return super.compatible(found, req, warn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(DiagnosticPosition pos, JCDiagnostic details) {
|
||||
reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
|
||||
}
|
||||
};
|
||||
return new MethodResultInfo(to, checkContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
|
||||
return new MostSpecificCheck(strict, actuals);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check context to be used during method applicability checks. A method check
|
||||
* context might contain inference variables.
|
||||
@ -905,10 +961,23 @@ public class Resolve {
|
||||
DeferredType dt = (DeferredType)found;
|
||||
return dt.check(this);
|
||||
} else {
|
||||
return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
|
||||
return super.check(pos, chk.checkNonVoid(pos, types.capture(U(found.baseType()))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javac has a long-standing 'simplification' (see 6391995):
|
||||
* given an actual argument type, the method check is performed
|
||||
* on its upper bound. This leads to inconsistencies when an
|
||||
* argument type is checked against itself. For example, given
|
||||
* a type-variable T, it is not true that {@code U(T) <: T},
|
||||
* so we need to guard against that.
|
||||
*/
|
||||
private Type U(Type found) {
|
||||
return found == pt ?
|
||||
found : types.upperBound(found);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MethodResultInfo dup(Type newPt) {
|
||||
return new MethodResultInfo(newPt, checkContext);
|
||||
@ -2421,7 +2490,7 @@ public class Resolve {
|
||||
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
|
||||
if (sym.kind >= AMBIGUOUS) {
|
||||
final JCDiagnostic details = sym.kind == WRONG_MTH ?
|
||||
((InapplicableSymbolError)sym).errCandidate().details :
|
||||
((InapplicableSymbolError)sym).errCandidate().snd :
|
||||
null;
|
||||
sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
|
||||
@Override
|
||||
@ -2576,7 +2645,8 @@ public class Resolve {
|
||||
Name name, List<Type> argtypes,
|
||||
List<Type> typeargtypes,
|
||||
boolean boxingAllowed,
|
||||
MethodCheck methodCheck) {
|
||||
MethodCheck methodCheck,
|
||||
InferenceContext inferenceContext) {
|
||||
MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
|
||||
|
||||
ReferenceLookupHelper boundLookupHelper;
|
||||
@ -2599,7 +2669,7 @@ public class Resolve {
|
||||
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
|
||||
|
||||
//step 2 - unbound lookup
|
||||
ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
|
||||
ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
|
||||
Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
|
||||
|
||||
@ -2739,11 +2809,11 @@ public class Resolve {
|
||||
* Returns an unbound version of this lookup helper. By default, this
|
||||
* method returns an dummy lookup helper.
|
||||
*/
|
||||
ReferenceLookupHelper unboundLookup() {
|
||||
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
|
||||
//dummy loopkup helper that always return 'methodNotFound'
|
||||
return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
|
||||
@Override
|
||||
ReferenceLookupHelper unboundLookup() {
|
||||
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
@ -2793,14 +2863,15 @@ public class Resolve {
|
||||
}
|
||||
|
||||
@Override
|
||||
ReferenceLookupHelper unboundLookup() {
|
||||
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
|
||||
if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
|
||||
argtypes.nonEmpty() &&
|
||||
(argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) {
|
||||
(argtypes.head.hasTag(NONE) ||
|
||||
types.isSubtypeUnchecked(inferenceContext.asFree(argtypes.head), site))) {
|
||||
return new UnboundMethodReferenceLookupHelper(referenceTree, name,
|
||||
site, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
return super.unboundLookup();
|
||||
return super.unboundLookup(inferenceContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2836,7 +2907,7 @@ public class Resolve {
|
||||
}
|
||||
|
||||
@Override
|
||||
ReferenceLookupHelper unboundLookup() {
|
||||
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -3371,20 +3442,20 @@ public class Resolve {
|
||||
key, name, first, second);
|
||||
}
|
||||
else {
|
||||
Candidate c = errCandidate();
|
||||
Pair<Symbol, JCDiagnostic> c = errCandidate();
|
||||
if (compactMethodDiags) {
|
||||
for (Map.Entry<Template, DiagnosticRewriter> _entry :
|
||||
MethodResolutionDiagHelper.rewriters.entrySet()) {
|
||||
if (_entry.getKey().matches(c.details)) {
|
||||
if (_entry.getKey().matches(c.snd)) {
|
||||
JCDiagnostic simpleDiag =
|
||||
_entry.getValue().rewriteDiagnostic(diags, pos,
|
||||
log.currentSource(), dkind, c.details);
|
||||
log.currentSource(), dkind, c.snd);
|
||||
simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
|
||||
return simpleDiag;
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol ws = c.sym.asMemberOf(site, types);
|
||||
Symbol ws = c.fst.asMemberOf(site, types);
|
||||
return diags.create(dkind, log.currentSource(), pos,
|
||||
"cant.apply.symbol",
|
||||
kindName(ws),
|
||||
@ -3393,7 +3464,7 @@ public class Resolve {
|
||||
methodArguments(argtypes),
|
||||
kindName(ws.owner),
|
||||
ws.owner.type,
|
||||
c.details);
|
||||
c.snd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3402,14 +3473,14 @@ public class Resolve {
|
||||
return types.createErrorType(name, location, syms.errSymbol.type).tsym;
|
||||
}
|
||||
|
||||
private Candidate errCandidate() {
|
||||
protected Pair<Symbol, JCDiagnostic> errCandidate() {
|
||||
Candidate bestSoFar = null;
|
||||
for (Candidate c : resolveContext.candidates) {
|
||||
if (c.isApplicable()) continue;
|
||||
bestSoFar = c;
|
||||
}
|
||||
Assert.checkNonNull(bestSoFar);
|
||||
return bestSoFar;
|
||||
return new Pair<Symbol, JCDiagnostic>(bestSoFar.sym, bestSoFar.details);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3452,7 +3523,15 @@ public class Resolve {
|
||||
methodArguments(argtypes));
|
||||
return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
|
||||
} else if (filteredCandidates.size() == 1) {
|
||||
JCDiagnostic d = new InapplicableSymbolError(resolveContext).getDiagnostic(dkind, pos,
|
||||
Map.Entry<Symbol, JCDiagnostic> _e =
|
||||
filteredCandidates.entrySet().iterator().next();
|
||||
final Pair<Symbol, JCDiagnostic> p = new Pair<Symbol, JCDiagnostic>(_e.getKey(), _e.getValue());
|
||||
JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
|
||||
@Override
|
||||
protected Pair<Symbol, JCDiagnostic> errCandidate() {
|
||||
return p;
|
||||
}
|
||||
}.getDiagnostic(dkind, pos,
|
||||
location, site, name, argtypes, typeargtypes);
|
||||
if (truncatedDiag) {
|
||||
d.setFlag(DiagnosticFlag.COMPRESSED);
|
||||
|
@ -303,8 +303,9 @@ public class RichDiagnosticFormatter extends
|
||||
conflicts.contains(s))) {
|
||||
List<Name> l = List.nil();
|
||||
Symbol s2 = s;
|
||||
while (s2.type.getEnclosingType().hasTag(CLASS)
|
||||
&& s2.owner.kind == Kinds.TYP) {
|
||||
while (s2.type.hasTag(CLASS) &&
|
||||
s2.type.getEnclosingType().hasTag(CLASS) &&
|
||||
s2.owner.kind == Kinds.TYP) {
|
||||
l = l.prepend(s2.getSimpleName());
|
||||
s2 = s2.owner;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.ClassType;
|
||||
import com.sun.tools.javac.code.TypeTag;
|
||||
import com.sun.tools.javac.comp.AttrContext;
|
||||
import com.sun.tools.javac.comp.Env;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
@ -516,7 +517,7 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
return null;
|
||||
Type sup = env.types.supertype(type);
|
||||
return TypeMaker.getType(env,
|
||||
(sup != type) ? sup : env.syms.objectType);
|
||||
(sup.hasTag(TypeTag.NONE)) ? env.syms.objectType : sup);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,6 +56,13 @@ public enum ToolOption {
|
||||
}
|
||||
},
|
||||
|
||||
CP("-cp", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
}
|
||||
},
|
||||
|
||||
EXTDIRS("-extdirs", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
|
@ -39,6 +39,7 @@ main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
|
||||
\ -docletpath <path> Specify where to find doclet class files\n\
|
||||
\ -sourcepath <pathlist> Specify where to find source files\n\
|
||||
\ -classpath <pathlist> Specify where to find user class files\n\
|
||||
\ -cp <pathlist> Specify where to find user class files\n\
|
||||
\ -exclude <pkglist> Specify a list of packages to exclude\n\
|
||||
\ -subpackages <subpkglist> Specify subpackages to recursively load\n\
|
||||
\ -breakiterator Compute first sentence with BreakIterator\n\
|
||||
|
@ -531,7 +531,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
|
||||
String name = o.aliases[0].substring(1); // there must always be at least one name
|
||||
log.println(getMessage("main.opt." + name));
|
||||
}
|
||||
String[] fmOptions = { "-classpath", "-bootclasspath" };
|
||||
String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
|
||||
for (String o: fmOptions) {
|
||||
if (fileManager.isSupportedOption(o) == -1)
|
||||
continue;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -77,6 +77,7 @@ where [options] include:\n\
|
||||
\n\t\
|
||||
-help Print this help message and exit\n\t\
|
||||
-classpath <path> Path from which to load classes\n\t\
|
||||
-cp <path> Path from which to load classes\n\t\
|
||||
-bootclasspath <path> Path from which to load bootstrap classes\n\t\
|
||||
-d <dir> Output directory\n\t\
|
||||
-o <file> Output file (only one of -d or -o may be used)\n\t\
|
||||
@ -108,6 +109,8 @@ main.opt.force=\
|
||||
\ -force Always write output files
|
||||
main.opt.classpath=\
|
||||
\ -classpath <path> Path from which to load classes
|
||||
main.opt.cp=\
|
||||
\ -cp <path> Path from which to load classes
|
||||
main.opt.bootclasspath=\
|
||||
\ -bootclasspath <path> Path from which to load bootstrap classes
|
||||
main.usage.foot=\
|
||||
|
@ -885,7 +885,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
continue;
|
||||
log.println(getMessage("main.opt." + name));
|
||||
}
|
||||
String[] fmOptions = { "-classpath", "-bootclasspath" };
|
||||
String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
|
||||
for (String o: fmOptions) {
|
||||
if (fileManager.isSupportedOption(o) == -1)
|
||||
continue;
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
err.prefix=Error:
|
||||
err.prefix=Error:
|
||||
|
||||
err.bad.constant.pool=error while reading constant pool for {0}: {1}
|
||||
err.class.not.found=class not found: {0}
|
||||
@ -73,6 +73,9 @@ main.opt.s=\
|
||||
main.opt.classpath=\
|
||||
\ -classpath <path> Specify where to find user class files
|
||||
|
||||
main.opt.cp=\
|
||||
\ -cp <path> Specify where to find user class files
|
||||
|
||||
main.opt.bootclasspath=\
|
||||
\ -bootclasspath <path> Override location of bootstrap class files
|
||||
|
||||
|
13
langtools/test/tools/doclint/BadPackageCommentTest.java
Normal file
13
langtools/test/tools/doclint/BadPackageCommentTest.java
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8020278
|
||||
* @summary NPE in javadoc (bad handling of bad tag in package-info.java)
|
||||
* @build DocLintTester
|
||||
* @run main DocLintTester -ref BadPackageCommentTest.out BadPackageCommentTest.java
|
||||
*/
|
||||
|
||||
/**
|
||||
* abc.
|
||||
* @@@
|
||||
*/
|
||||
package p;
|
10
langtools/test/tools/doclint/BadPackageCommentTest.out
Normal file
10
langtools/test/tools/doclint/BadPackageCommentTest.out
Normal file
@ -0,0 +1,10 @@
|
||||
BadPackageCommentTest.java:11: error: no tag name after @
|
||||
* @@@
|
||||
^
|
||||
BadPackageCommentTest.java:11: error: no tag name after @
|
||||
* @@@
|
||||
^
|
||||
BadPackageCommentTest.java:11: error: no tag name after @
|
||||
* @@@
|
||||
^
|
||||
3 errors
|
@ -36,7 +36,7 @@ Options:
|
||||
Show this message.
|
||||
|
||||
The following javac options are also supported
|
||||
-bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns
|
||||
-bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns
|
||||
|
||||
To run doclint on part of a project, put the compiled classes for your
|
||||
project on the classpath (or bootclasspath), then specify the source files
|
||||
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8020286
|
||||
* @summary Wrong diagnostic after compaction
|
||||
* @compile/fail/ref=T8020286.out -XDrawDiagnostics -Xdiags:compact T8020286.java
|
||||
*/
|
||||
|
||||
class T8020286 {
|
||||
void m(String s) { }
|
||||
void m(Integer i, String s) { }
|
||||
void test() {
|
||||
m(1, 1);
|
||||
m(1);
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
T8020286.java:12:13: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
|
||||
T8020286.java:13:10: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
|
||||
- compiler.note.compressed.diags
|
||||
2 errors
|
48
langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java
Normal file
48
langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6356530
|
||||
* @summary -Xlint:serial does not flag abstract classes with concrete methods/members
|
||||
* @compile/fail/ref=SerializableAbstractClassWithNonAbstractMethodsTest.out -XDrawDiagnostics -Werror -Xlint:serial SerializableAbstractClassWithNonAbstractMethodsTest.java
|
||||
*/
|
||||
|
||||
abstract class SerializableAbstractClassWithNonAbstractMethodsTest implements java.io.Serializable {
|
||||
void m1() {}
|
||||
abstract void m2();
|
||||
|
||||
abstract class AWithUID implements java.io.Serializable {
|
||||
private static final long serialVersionUID = 0;
|
||||
void m(){}
|
||||
}
|
||||
|
||||
interface IDefault extends java.io.Serializable {
|
||||
default int m() { return 1; }
|
||||
}
|
||||
|
||||
interface IDefaultAndUID extends java.io.Serializable {
|
||||
static final long serialVersionUID = 0;
|
||||
default int m() { return 1; }
|
||||
}
|
||||
}
|
5
langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out
Normal file
5
langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out
Normal file
@ -0,0 +1,5 @@
|
||||
SerializableAbstractClassWithNonAbstractMethodsTest.java:40:5: compiler.warn.missing.SVUID: SerializableAbstractClassWithNonAbstractMethodsTest.IDefault
|
||||
SerializableAbstractClassWithNonAbstractMethodsTest.java:31:10: compiler.warn.missing.SVUID: SerializableAbstractClassWithNonAbstractMethodsTest
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
2 warnings
|
66
langtools/test/tools/javac/conditional/T8016702.java
Normal file
66
langtools/test/tools/javac/conditional/T8016702.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8016702
|
||||
* @summary use of ternary operator in lambda expression gives incorrect results
|
||||
*/
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class T8016702 {
|
||||
|
||||
static int assertionCount;
|
||||
|
||||
static void assertTrue(boolean b, String msg) {
|
||||
assertionCount++;
|
||||
if (!b) {
|
||||
throw new AssertionError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
interface IntFunction<Y> {
|
||||
Y m(int x);
|
||||
}
|
||||
|
||||
void test(List<Integer> li) {
|
||||
map(i -> (i % 2 == 0) ? "" : "i="+i, li);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<R> void map(IntFunction<R> mapper, List<Integer> li) {
|
||||
for (int i : li) {
|
||||
String res = (String)mapper.m(i);
|
||||
assertTrue((i % 2 == 0) ? res.isEmpty() : res.contains("" + i),
|
||||
"i = " + i + " res = " + res);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
T8016702 tester = new T8016702();
|
||||
tester.test(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
assertTrue(assertionCount == 10, "wrong assertion count: " + assertionCount);
|
||||
}
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
*
|
||||
* @summary javac fails to substitute type variables into a constructor's throws clause
|
||||
* @author Mark Mahieu
|
||||
* @compile/fail/ref=T6723444.out -XDrawDiagnostics T6723444.java
|
||||
* @compile/fail/ref=T6723444_1.out -Xlint:-options -source 7 -XDrawDiagnostics T6723444.java
|
||||
* @compile/fail/ref=T6723444_2.out -XDrawDiagnostics T6723444.java
|
||||
*
|
||||
*/
|
||||
public class T6723444 {
|
||||
|
@ -1,8 +1,7 @@
|
||||
T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:45:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:46:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:48:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:44:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:46:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:47:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:49:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:50:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:51:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
@ -10,4 +9,5 @@ T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: ja
|
||||
T6723444.java:53:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:54:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:55:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:56:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
12 errors
|
11
langtools/test/tools/javac/generics/6723444/T6723444_2.out
Normal file
11
langtools/test/tools/javac/generics/6723444/T6723444_2.out
Normal file
@ -0,0 +1,11 @@
|
||||
T6723444.java:46:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:47:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:49:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:50:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:51:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:52:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:53:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:54:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:55:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
T6723444.java:56:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
|
||||
10 errors
|
@ -4,7 +4,8 @@
|
||||
*
|
||||
* @summary Incorrect thrown type determined for unchecked invocations
|
||||
* @author Daniel Smith
|
||||
* @compile/fail/ref=T7015430.out -Xlint:unchecked -XDrawDiagnostics T7015430.java
|
||||
* @compile/fail/ref=T7015430_1.out -source 7 -Xlint:-options,unchecked -XDrawDiagnostics T7015430.java
|
||||
* @compile/fail/ref=T7015430_2.out -Xlint:unchecked -XDrawDiagnostics T7015430.java
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
|
||||
T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
|
||||
T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
|
||||
T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:95:15: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:113:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:129:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
5 errors
|
||||
12 warnings
|
19
langtools/test/tools/javac/generics/7015430/T7015430_1.out
Normal file
19
langtools/test/tools/javac/generics/7015430/T7015430_1.out
Normal file
@ -0,0 +1,19 @@
|
||||
T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:69:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:114:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
|
||||
T7015430.java:42:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:69:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:96:15: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:114:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
5 errors
|
||||
12 warnings
|
15
langtools/test/tools/javac/generics/7015430/T7015430_2.out
Normal file
15
langtools/test/tools/javac/generics/7015430/T7015430_2.out
Normal file
@ -0,0 +1,15 @@
|
||||
T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:42:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:51:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:69:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:78:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:105:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
|
||||
T7015430.java:114:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
|
||||
T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
1 error
|
||||
12 warnings
|
@ -1,13 +1,10 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @ignore 7041019 Bogus type-variable substitution with array types with dependencies on accessibility check
|
||||
* @bug 7034511 7040883
|
||||
* @bug 7034511 7040883 7041019
|
||||
* @summary Loophole in typesafety
|
||||
* @compile/fail/ref=T7034511a.out -XDrawDiagnostics T7034511a.java
|
||||
*/
|
||||
|
||||
// backing out 7034511, see 7040883
|
||||
|
||||
class T7034511a {
|
||||
|
||||
interface A<T> {
|
||||
|
@ -1,2 +1,2 @@
|
||||
T7034511a.java:18:14: compiler.err.cant.apply.symbol: kindname.method, foo, compiler.misc.type.captureof: 1, ?[], java.lang.String[], kindname.interface, T7034511a.A<T>, (compiler.misc.no.conforming.assignment.exists: java.lang.String[], compiler.misc.type.captureof: 1, ?[])
|
||||
T7034511a.java:18:14: compiler.err.cant.apply.symbol: kindname.method, foo, compiler.misc.type.captureof: 1, ?[], java.lang.String[], kindname.interface, T7034511a.A<T>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String[], compiler.misc.type.captureof: 1, ?[]))
|
||||
1 error
|
||||
|
@ -1,13 +1,10 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @ignore 7041019 Bogus type-variable substitution with array types with dependencies on accessibility check
|
||||
* @bug 7034511 7040883
|
||||
* @bug 7034511 7040883 7041019
|
||||
* @summary Loophole in typesafety
|
||||
* @compile/fail/ref=T7034511b.out -XDrawDiagnostics T7034511b.java
|
||||
*/
|
||||
|
||||
// backing out 7034511, see 7040883
|
||||
|
||||
class T7034511b {
|
||||
static class MyList<E> {
|
||||
E toArray(E[] e) { return null; }
|
||||
|
@ -1,2 +1,2 @@
|
||||
T7034511b.java:14:11: compiler.err.cant.apply.symbol: kindname.method, toArray, compiler.misc.type.captureof: 1, ?[], java.lang.Object[], kindname.class, T7034511b.MyList<E>, (compiler.misc.no.conforming.assignment.exists: java.lang.Object[], compiler.misc.type.captureof: 1, ?[])
|
||||
T7034511b.java:14:11: compiler.err.cant.apply.symbol: kindname.method, toArray, compiler.misc.type.captureof: 1, ?[], java.lang.Object[], kindname.class, T7034511b.MyList<E>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object[], compiler.misc.type.captureof: 1, ?[]))
|
||||
1 error
|
||||
|
39
langtools/test/tools/javac/generics/7034511/T7041019.java
Normal file
39
langtools/test/tools/javac/generics/7034511/T7041019.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7034511 7040883 7041019
|
||||
* @summary Bogus type-variable substitution with array types with dependencies on accessibility check
|
||||
*
|
||||
* @compile T7041019.java
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
class T7041019 {
|
||||
<E> List<E>[] m(List<E> l) { return null; }
|
||||
|
||||
void test(List<? extends String> ls) {
|
||||
int i = m(ls).length;
|
||||
}
|
||||
}
|
10
langtools/test/tools/javac/generics/8016640/T8016640.java
Normal file
10
langtools/test/tools/javac/generics/8016640/T8016640.java
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016640
|
||||
* @summary compiler hangs if the generics arity of a base class is wrong
|
||||
* @compile/fail/ref=T8016640.out -XDrawDiagnostics T8016640.java
|
||||
*/
|
||||
class T8016640 {
|
||||
static class Foo<X,Y> { }
|
||||
static class BadFoo<T> extends Foo<T> { }
|
||||
}
|
2
langtools/test/tools/javac/generics/8016640/T8016640.out
Normal file
2
langtools/test/tools/javac/generics/8016640/T8016640.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8016640.java:9:39: compiler.err.wrong.number.type.args: 2
|
||||
1 error
|
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8019824
|
||||
* @summary very long error messages on inference error
|
||||
* @compile/fail/ref=T8019824.out -XDrawDiagnostics T8019824.java
|
||||
*/
|
||||
class T8019824 {
|
||||
void test(Class<? extends Foo<?, ?>> cls) {
|
||||
Foo<?, ?> foo = make(cls);
|
||||
}
|
||||
|
||||
<A, B, C extends Foo<A, B>> Foo<A, B> make(Class<C> cls) { return null; }
|
||||
|
||||
interface Foo<A, B> {}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
T8019824.java:9:25: compiler.err.cant.apply.symbol: kindname.method, make, java.lang.Class<C>, java.lang.Class<compiler.misc.type.captureof: 1, ? extends T8019824.Foo<?,?>>, kindname.class, T8019824, (compiler.misc.incompatible.eq.upper.bounds: C, compiler.misc.type.captureof: 1, ? extends T8019824.Foo<?,?>, T8019824.Foo<compiler.misc.type.captureof: 2, ?,B>)
|
||||
1 error
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8020149
|
||||
* @summary Graph inference: wrong logic for picking best variable to solve
|
||||
* @compile T8020149.java
|
||||
*/
|
||||
class T8020149 {
|
||||
static class TestData<X,Y> { }
|
||||
|
||||
interface Foo<X, Y extends Foo<X, Y>> { }
|
||||
|
||||
interface IntFoo extends Foo<Integer, IntFoo> { }
|
||||
|
||||
interface Function<X, Y> {
|
||||
Y apply(X x);
|
||||
}
|
||||
|
||||
void test(TestData<Integer, IntFoo> data) {
|
||||
m1(data, s->s);
|
||||
m2(data, s->s);
|
||||
}
|
||||
|
||||
<E, E_OUT extends Foo<E, E_OUT>, W, W_IN extends Foo<W, W_IN>> void m1(TestData<W, W_IN> data, Function<W_IN, E_OUT> m) { }
|
||||
<W, W_IN extends Foo<W, W_IN>, E, E_OUT extends Foo<E, E_OUT>> void m2(TestData<W, W_IN> data, Function<W_IN, E_OUT> m) { }
|
||||
}
|
23
langtools/test/tools/javac/lambda/8019480/T8019480.java
Normal file
23
langtools/test/tools/javac/lambda/8019480/T8019480.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8019480
|
||||
* @summary Javac crashes when method is called on a type-variable receiver from lambda expression
|
||||
* @author Maurizio Cimadamore
|
||||
* @compile/fail/ref=T8019480.out -XDrawDiagnostics T8019480.java
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
class T8019480<U> {
|
||||
interface Predicate<T> {
|
||||
void m(T t);
|
||||
}
|
||||
|
||||
interface Stream<T> {
|
||||
void forEach(Predicate<T> pt);
|
||||
}
|
||||
|
||||
void test(U current, Stream<U> stream) {
|
||||
List<U> list3 = new ArrayList<>();
|
||||
stream.forEach(i -> list3.add(current.clone()));
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/lambda/8019480/T8019480.out
Normal file
3
langtools/test/tools/javac/lambda/8019480/T8019480.out
Normal file
@ -0,0 +1,3 @@
|
||||
T8019480.java:21:46: compiler.err.report.access: clone(), protected, java.lang.Object
|
||||
T8019480.java:21:34: compiler.err.cant.apply.symbols: kindname.method, add, java.lang.Object,{(compiler.misc.inapplicable.method: kindname.method, java.util.Collection, add(U), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, U))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, add(U), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, U))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, add(int,U), (compiler.misc.arg.length.mismatch))}
|
||||
2 errors
|
19
langtools/test/tools/javac/lambda/8020147/T8020147.java
Normal file
19
langtools/test/tools/javac/lambda/8020147/T8020147.java
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8020147
|
||||
* @summary Spurious errors when compiling nested stuck lambdas
|
||||
* @compile/fail/ref=T8020147.out -Werror -Xlint:cast -XDrawDiagnostics T8020147.java
|
||||
*/
|
||||
class T8020147 {
|
||||
interface Function<X, Y> {
|
||||
Y apply(X x);
|
||||
}
|
||||
|
||||
<T> void g(Function<String, T> f) { }
|
||||
<U> String m(U u, Function<U, U> fuu) { return null; }
|
||||
|
||||
void test() {
|
||||
g(x->m("", i->(String)i));
|
||||
g(x->m("", i->(String)x));
|
||||
}
|
||||
}
|
5
langtools/test/tools/javac/lambda/8020147/T8020147.out
Normal file
5
langtools/test/tools/javac/lambda/8020147/T8020147.out
Normal file
@ -0,0 +1,5 @@
|
||||
T8020147.java:16:23: compiler.warn.redundant.cast: java.lang.String
|
||||
T8020147.java:17:23: compiler.warn.redundant.cast: java.lang.String
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
2 warnings
|
11
langtools/test/tools/javac/lambda/BadNestedLambda.java
Normal file
11
langtools/test/tools/javac/lambda/BadNestedLambda.java
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8017618
|
||||
* @summary NullPointerException in RichDiagnosticFormatter for bad input program
|
||||
* @compile/fail/ref=BadNestedLambda.out -XDrawDiagnostics BadNestedLambda.java
|
||||
*/
|
||||
class BadNestedLambda {
|
||||
void test() {
|
||||
Runnable add = (int x) -> (int y) -> x + y;
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/lambda/BadNestedLambda.out
Normal file
3
langtools/test/tools/javac/lambda/BadNestedLambda.out
Normal file
@ -0,0 +1,3 @@
|
||||
BadNestedLambda.java:9:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.not.a.functional.intf: void))
|
||||
BadNestedLambda.java:9:24: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda)
|
||||
2 errors
|
23
langtools/test/tools/javac/lambda/MethodReference68.java
Normal file
23
langtools/test/tools/javac/lambda/MethodReference68.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile/fail/ref=MethodReference68.out -XDrawDiagnostics MethodReference68.java
|
||||
*/
|
||||
class MethodReference68 {
|
||||
interface F<X> {
|
||||
String m(X x);
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
String getName() { return ""; }
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<Z> void g(F<Z> fz, Z... zs) { }
|
||||
|
||||
void test() {
|
||||
g(Foo::getName);
|
||||
g(Foo::getName, 1); //incompatible constraints, Z <: Foo, Z :> Integer
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/lambda/MethodReference68.out
Normal file
2
langtools/test/tools/javac/lambda/MethodReference68.out
Normal file
@ -0,0 +1,2 @@
|
||||
MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F<Z>,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object)
|
||||
1 error
|
21
langtools/test/tools/javac/lambda/MethodReference69.java
Normal file
21
langtools/test/tools/javac/lambda/MethodReference69.java
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile/fail/ref=MethodReference69.out -XDrawDiagnostics MethodReference69.java
|
||||
*/
|
||||
class MethodReference69 {
|
||||
interface F<X> {
|
||||
String m(Integer x1, X x2);
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
String getNameAt(Integer i) { return ""; }
|
||||
}
|
||||
|
||||
<Z> void g(F<Z> fz) { }
|
||||
|
||||
void test() {
|
||||
g(Foo::getName);
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/lambda/MethodReference69.out
Normal file
2
langtools/test/tools/javac/lambda/MethodReference69.out
Normal file
@ -0,0 +1,2 @@
|
||||
MethodReference69.java:19:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, getName, , , (compiler.misc.location: kindname.class, MethodReference69.Foo, null))
|
||||
1 error
|
28
langtools/test/tools/javac/lambda/MethodReference70.java
Normal file
28
langtools/test/tools/javac/lambda/MethodReference70.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile/fail/ref=MethodReference70.out -XDrawDiagnostics MethodReference70.java
|
||||
*/
|
||||
class MethodReference70 {
|
||||
interface F<X> {
|
||||
void m(X x);
|
||||
}
|
||||
|
||||
interface G<X> {
|
||||
Integer m(X x);
|
||||
}
|
||||
|
||||
void m1(Integer i) { }
|
||||
|
||||
void m2(Integer i) { }
|
||||
void m2(String i) { }
|
||||
|
||||
<Z> void g(F<Z> fz) { }
|
||||
<Z> void g(G<Z> gz) { }
|
||||
|
||||
void test() {
|
||||
g(this::m1); //ok
|
||||
g(this::m2); //ambiguous (stuck!)
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/lambda/MethodReference70.out
Normal file
3
langtools/test/tools/javac/lambda/MethodReference70.out
Normal file
@ -0,0 +1,3 @@
|
||||
MethodReference70.java:26:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference70.F<Z>), MethodReference70, kindname.method, <Z>g(MethodReference70.G<Z>), MethodReference70
|
||||
MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
|
||||
2 errors
|
26
langtools/test/tools/javac/lambda/MethodReference71.java
Normal file
26
langtools/test/tools/javac/lambda/MethodReference71.java
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile/fail/ref=MethodReference71.out -XDrawDiagnostics MethodReference71.java
|
||||
*/
|
||||
class MethodReference71 {
|
||||
interface F<X> {
|
||||
void m(X x);
|
||||
}
|
||||
|
||||
interface G<X> {
|
||||
Integer m(X x);
|
||||
}
|
||||
|
||||
void m1(Integer i) { }
|
||||
void m2(Integer... i) { }
|
||||
|
||||
<Z> void g(F<Z> f) { }
|
||||
<Z> void g(G<Z> g) { }
|
||||
|
||||
void test() {
|
||||
g(this::m1); //ok
|
||||
g(this::m2); //ambiguous (stuck!)
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/lambda/MethodReference71.out
Normal file
3
langtools/test/tools/javac/lambda/MethodReference71.out
Normal file
@ -0,0 +1,3 @@
|
||||
MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, kindname.method, <Z>g(MethodReference71.F<Z>), MethodReference71, kindname.method, <Z>g(MethodReference71.G<Z>), MethodReference71
|
||||
MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z)
|
||||
2 errors
|
20
langtools/test/tools/javac/lambda/MethodReference72.java
Normal file
20
langtools/test/tools/javac/lambda/MethodReference72.java
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile/fail/ref=MethodReference72.out -XDrawDiagnostics MethodReference72.java
|
||||
*/
|
||||
class MethodReference72 {
|
||||
interface F<X> {
|
||||
@SuppressWarnings("unchecked")
|
||||
void m(X... x);
|
||||
}
|
||||
|
||||
void m1(Integer i) { }
|
||||
|
||||
<Z> void g(F<Z> f) { }
|
||||
|
||||
void test() {
|
||||
g(this::m1); //?
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/lambda/MethodReference72.out
Normal file
2
langtools/test/tools/javac/lambda/MethodReference72.out
Normal file
@ -0,0 +1,2 @@
|
||||
MethodReference72.java:18:9: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference72.F<Z>, @420, kindname.class, MethodReference72, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m1, java.lang.Integer, Z[], kindname.class, MethodReference72, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: Z[], java.lang.Integer)))))
|
||||
1 error
|
43
langtools/test/tools/javac/lambda/NestedCapture01.java
Normal file
43
langtools/test/tools/javac/lambda/NestedCapture01.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012238
|
||||
* @summary Nested method capture and inference
|
||||
* @compile NestedCapture01.java
|
||||
*/
|
||||
class NestedCapture01 {
|
||||
|
||||
void test(String s) {
|
||||
g(m(s.getClass()));
|
||||
}
|
||||
|
||||
<F extends String> F m(Class<F> cf) {
|
||||
return null;
|
||||
}
|
||||
|
||||
<P extends String> P g(P vo) {
|
||||
return null;
|
||||
}
|
||||
}
|
43
langtools/test/tools/javac/lambda/NestedCapture02.java
Normal file
43
langtools/test/tools/javac/lambda/NestedCapture02.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012238
|
||||
* @summary Nested method capture and inference
|
||||
* @compile NestedCapture02.java
|
||||
*/
|
||||
class NestedCapture02<S,T> {
|
||||
|
||||
<S,T> NestedCapture02<S,T> create(NestedCapture02<? super S,?> first,
|
||||
NestedCapture02<? super S, T> second) {
|
||||
return null;
|
||||
}
|
||||
|
||||
<U> NestedCapture02<S, ? extends U> cast(Class<U> target) { return null; }
|
||||
|
||||
<U> NestedCapture02<S, ? extends U> test(Class<U> target,
|
||||
NestedCapture02<? super S, ?> first, NestedCapture02<? super S, T> second) {
|
||||
return create(first, second.cast(target));
|
||||
}
|
||||
}
|
36
langtools/test/tools/javac/lambda/NestedCapture03.java
Normal file
36
langtools/test/tools/javac/lambda/NestedCapture03.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012238
|
||||
* @summary Nested method capture and inference
|
||||
* @compile NestedCapture03.java
|
||||
*/
|
||||
class NestedCapture03 {
|
||||
<T extends String> T factory(Class<T> c) { return null; }
|
||||
|
||||
void test(Class<?> c) {
|
||||
factory(c.asSubclass(String.class)).matches(null);
|
||||
}
|
||||
}
|
@ -23,11 +23,10 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @ignore 8013404: Test awaits spec clarification
|
||||
* @bug 8003280
|
||||
* @bug 8003280 8013404
|
||||
* @summary Add lambda tests
|
||||
* check that target type of cast is propagated to conditional subexpressions
|
||||
* @compile TargetType36.java
|
||||
* check that target type of cast is not propagated to conditional subexpressions
|
||||
* @compile/fail/ref=TargetType36.out -XDrawDiagnostics TargetType36.java
|
||||
*/
|
||||
class TargetType36 { //awaits spec wording on cast vs. poly
|
||||
|
||||
|
3
langtools/test/tools/javac/lambda/TargetType36.out
Normal file
3
langtools/test/tools/javac/lambda/TargetType36.out
Normal file
@ -0,0 +1,3 @@
|
||||
TargetType36.java:40:30: compiler.err.unexpected.lambda
|
||||
TargetType36.java:40:43: compiler.err.unexpected.lambda
|
||||
2 errors
|
@ -1,7 +1,7 @@
|
||||
TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60
|
||||
TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>g(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:60:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:60:28: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n1, java.lang.String, TargetType60, kindname.class, TargetType60, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: TargetType60, java.lang.String)))))
|
||||
TargetType60.java:60:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n1(java.lang.String))
|
||||
TargetType60.java:61:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n2(TargetType60,java.lang.String))
|
||||
TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
|
40
langtools/test/tools/javac/lambda/TargetType63.java
Normal file
40
langtools/test/tools/javac/lambda/TargetType63.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @summary smoke test for inference of throws type variables
|
||||
* @compile/fail/ref=TargetType63.out -XDrawDiagnostics TargetType63.java
|
||||
*/
|
||||
class TargetType63 {
|
||||
|
||||
interface F<T extends Throwable> {
|
||||
void m() throws T;
|
||||
}
|
||||
|
||||
void g1() { }
|
||||
void g2() throws ClassNotFoundException { }
|
||||
void g3() throws Exception { }
|
||||
|
||||
<Z extends Throwable> void m1(F<Z> fz) throws Z { }
|
||||
<Z extends ClassNotFoundException> void m2(F<Z> fz) throws Z { }
|
||||
|
||||
void test1() {
|
||||
m1(()->{ }); //ok (Z = RuntimeException)
|
||||
m1(this::g1); //ok (Z = RuntimeException)
|
||||
}
|
||||
|
||||
void test2() {
|
||||
m2(()->{ }); //fail (Z = ClassNotFoundException)
|
||||
m2(this::g1); //fail (Z = ClassNotFoundException)
|
||||
}
|
||||
|
||||
void test3() {
|
||||
m1(()->{ throw new ClassNotFoundException(); }); //fail (Z = ClassNotFoundException)
|
||||
m1(this::g2); //fail (Z = ClassNotFoundException)
|
||||
m2(()->{ throw new ClassNotFoundException(); }); //fail (Z = ClassNotFoundException)
|
||||
m2(this::g2); //fail (Z = ClassNotFoundException)
|
||||
}
|
||||
|
||||
void test4() {
|
||||
m1(()->{ throw new Exception(); }); //fail (Z = Exception)
|
||||
m1(this::g3); //fail (Z = Exception)
|
||||
}
|
||||
}
|
9
langtools/test/tools/javac/lambda/TargetType63.out
Normal file
9
langtools/test/tools/javac/lambda/TargetType63.out
Normal file
@ -0,0 +1,9 @@
|
||||
TargetType63.java:25:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:26:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:30:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:31:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:32:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:33:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.ClassNotFoundException
|
||||
TargetType63.java:37:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
TargetType63.java:38:11: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
|
||||
8 errors
|
41
langtools/test/tools/javac/lambda/TargetType75.java
Normal file
41
langtools/test/tools/javac/lambda/TargetType75.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8016060 8016059
|
||||
* @summary Lambda isn't compiled with return statement
|
||||
* @compile TargetType75.java
|
||||
*/
|
||||
class TargetType75 {
|
||||
interface P<X> {
|
||||
void m(X x);
|
||||
}
|
||||
|
||||
<Z> void m(P<Z> r, Z z) { }
|
||||
|
||||
void test() {
|
||||
m(x->{ return; }, "");
|
||||
m(x->System.out.println(""), "");
|
||||
}
|
||||
}
|
65
langtools/test/tools/javac/lambda/TargetType76.java
Normal file
65
langtools/test/tools/javac/lambda/TargetType76.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8016175
|
||||
* @summary Add bottom-up type-checking support for unambiguous method references
|
||||
* @compile TargetType76.java
|
||||
*/
|
||||
class TargetType76 {
|
||||
|
||||
interface Function<X, Y> {
|
||||
Y m(X x);
|
||||
}
|
||||
|
||||
interface OfRef<T> { }
|
||||
|
||||
interface Supplier<X> {
|
||||
X make();
|
||||
}
|
||||
|
||||
interface Stream<X> { }
|
||||
|
||||
interface Node<E> {
|
||||
Spliterator<E> spliterator();
|
||||
}
|
||||
|
||||
interface Spliterator<X> {
|
||||
Spliterator<X> spliterator();
|
||||
}
|
||||
|
||||
class RefTestData<T, I> implements OfRef<T> {
|
||||
RefTestData(I state,
|
||||
Function<I, Stream<T>> streamFn,
|
||||
Function<I, Spliterator<T>> splitrFn) { }
|
||||
}
|
||||
|
||||
<O> OfRef<O> ofCollection(Node<O> collection) {
|
||||
return new RefTestData<>(collection,
|
||||
x->stream(x::spliterator),
|
||||
Node::spliterator);
|
||||
}
|
||||
|
||||
<S> Stream<S> stream(Supplier<? extends Spliterator<S>> supplier) { return null; }
|
||||
}
|
17
langtools/test/tools/javac/meth/VarargsWarn.java
Normal file
17
langtools/test/tools/javac/meth/VarargsWarn.java
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8019340
|
||||
* @summary varargs-related warnings are meaningless on signature-polymorphic methods such as MethodHandle.invokeExact
|
||||
*
|
||||
* @compile/fail/ref=VarargsWarn.out -XDrawDiagnostics -Werror VarargsWarn.java
|
||||
*/
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
class VarargsWarn {
|
||||
void test(MethodHandle mh) throws Throwable {
|
||||
mh.invokeExact((Integer[])null);
|
||||
mh.invoke((Integer[])null);
|
||||
mh.invokeWithArguments((Integer[])null); //not a sig poly method - warning here!
|
||||
}
|
||||
}
|
4
langtools/test/tools/javac/meth/VarargsWarn.out
Normal file
4
langtools/test/tools/javac/meth/VarargsWarn.out
Normal file
@ -0,0 +1,4 @@
|
||||
VarargsWarn.java:15:32: compiler.warn.inexact.non-varargs.call: java.lang.Object, java.lang.Object[]
|
||||
- compiler.err.warnings.and.werror
|
||||
1 error
|
||||
1 warning
|
@ -0,0 +1,5 @@
|
||||
import java.io.StringBufferInputStream;
|
||||
|
||||
public class Auxiliary {
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
|
||||
1 warning
|
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8020586
|
||||
* @summary Warnings in the imports section should be attributed to the correct source file
|
||||
* @clean Auxiliary ImplicitCompilation
|
||||
* @compile/ref=ImplicitCompilation.out -XDrawDiagnostics -Xlint:deprecation -sourcepath . ImplicitCompilation.java
|
||||
* @clean Auxiliary ImplicitCompilation
|
||||
* @compile/ref=ExplicitCompilation.out -XDrawDiagnostics -Xlint:deprecation ImplicitCompilation.java Auxiliary.java
|
||||
*/
|
||||
|
||||
public class ImplicitCompilation {
|
||||
private Auxiliary a;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
|
||||
1 warning
|
@ -35,7 +35,7 @@ import java.io.StringWriter;
|
||||
public class JavapReturns0AfterClassNotFoundTest {
|
||||
|
||||
static final String fileNotFoundErrorMsg =
|
||||
"Error: class not found: Unexisting.class";
|
||||
"Error: class not found: Unexisting.class";
|
||||
static final String exitCodeClassNotFoundAssertionMsg =
|
||||
"Javap's exit code for class not found should be 1";
|
||||
static final String classNotFoundMsgAssertionMsg =
|
||||
|
Loading…
x
Reference in New Issue
Block a user