diff --git a/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java index b45b944416a5fcda2f251d00413810888f28a99e..633e941041add16439c0a3e3ecef73374a757766 100644 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java @@ -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")) { diff --git a/src/share/classes/com/sun/tools/doclint/DocLint.java b/src/share/classes/com/sun/tools/doclint/DocLint.java index c1d8d994316e27e7c9e176ac4b00abd465768678..0e5be61120c5378853361578a2806fff95951f1e 100644 --- a/src/share/classes/com/sun/tools/doclint/DocLint.java +++ b/src/share/classes/com/sun/tools/doclint/DocLint.java @@ -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 { 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()); diff --git a/src/share/classes/com/sun/tools/doclint/Env.java b/src/share/classes/com/sun/tools/doclint/Env.java index ffe3a7a0da7c0e86ed0091988dd79ee857a38af1..0af19be96a8397718d2603fa2301b6380180d58a 100644 --- a/src/share/classes/com/sun/tools/doclint/Env.java +++ b/src/share/classes/com/sun/tools/doclint/Env.java @@ -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) { diff --git a/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/src/share/classes/com/sun/tools/doclint/resources/doclint.properties index 995cb3350879324b63c0b07eed06c7c6ea24d06f..8905235d082259ba6c111e788db9b97b6efa0f1f 100644 --- a/src/share/classes/com/sun/tools/doclint/resources/doclint.properties +++ b/src/share/classes/com/sun/tools/doclint/resources/doclint.properties @@ -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\ diff --git a/src/share/classes/com/sun/tools/javac/code/Flags.java b/src/share/classes/com/sun/tools/javac/code/Flags.java index e57e683d49becfc958e0a479ac244cff8b36df87..12acc8dc27e158c264c699f45480be6805aef9e1 100644 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -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; diff --git a/src/share/classes/com/sun/tools/javac/code/Scope.java b/src/share/classes/com/sun/tools/javac/code/Scope.java index e8153da270382dd6cedf58781e5e0550ff36f45d..3697e05dead4d75ede771595a716d37a55f44406 100644 --- a/src/share/classes/com/sun/tools/javac/code/Scope.java +++ b/src/share/classes/com/sun/tools/javac/code/Scope.java @@ -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 sf) { Entry e = table[getIndex(name)]; if (e == null || e == sentinel) @@ -361,6 +362,10 @@ public class Scope { } } + public boolean anyMatch(Filter sf) { + return getElements(sf).iterator().hasNext(); + } + public Iterable getElements() { return getElements(noFilter); } diff --git a/src/share/classes/com/sun/tools/javac/code/Type.java b/src/share/classes/com/sun/tools/javac/code/Type.java index a89f86eed501f009275368017e432b0de148a032..2764900d054a774c327b81151b0f21dc7115d44c 100644 --- a/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/share/classes/com/sun/tools/javac/code/Type.java @@ -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> bounds; + protected Map> 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 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 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. diff --git a/src/share/classes/com/sun/tools/javac/code/Types.java b/src/share/classes/com/sun/tools/javac/code/Types.java index 517684247223ae8a720412a7ea30e939f6ed97e7..6b7e2752b69c8c7c1cd4f44f3cc9d495c4fd3f35 100644 --- a/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/src/share/classes/com/sun/tools/javac/code/Types.java @@ -2330,7 +2330,7 @@ public class Types { @Override public Type visitErrorType(ErrorType t, Void ignored) { - return t; + return Type.noType; } }; // @@ -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 diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java index 5db4dee8850893f38132944a6d76f4c786089b63..20bfc25d6b2700e21a3b3f6e91166cde9d857cfa 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -481,31 +481,7 @@ public class Attr extends JCTree.Visitor { static final long serialVersionUID = -6924771130405446405L; private Env env; private BreakAttr(Env env) { - this.env = copyEnv(env); - } - - private Env copyEnv(Env env) { - Env 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 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 copyEnv(Env env) { + Env 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 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 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 targetChecker = new Types.MapVisitor() { @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 argtypes = desc.getParameterTypes(); + Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck; + + if (resultInfo.checkContext.inferenceContext().free(argtypes)) { + referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext()); + } - Pair refResult = - rs.resolveMemberReference(that.pos(), localEnv, that, - that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck); + Pair refResult = null; + List 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 anyNonAbstractOrDefaultMethod = new Filter() { + @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 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) { diff --git a/src/share/classes/com/sun/tools/javac/comp/Check.java b/src/share/classes/com/sun/tools/javac/comp/Check.java index c1371992d0e6bc288ef758b1cfe41c406cff5ebc..49ea61783aee433786535b0da3416a4019dc2d5d 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -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(); diff --git a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 27b0c606fc2952f7c5e056b8900d7e35088a43ce..6b7cfdd37ee8e4ba843acec057da485935486a53 100644 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -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 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 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 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 argtypes = ListBuffer.lb(); - for (Type t : types.findDescriptorType(pt).getParameterTypes()) { - argtypes.append(Type.noType); - } - JCMemberReference mref2 = new TreeCopier(make).copy(tree); - mref2.expr = exprTree; - Pair 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 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 stuckVarsInternal(JCTree tree, Type pt, Infer.InferenceContext inferenceContext) { - StuckChecker sc = new StuckChecker(pt, inferenceContext); + private List stuckVarsInternal(JCTree tree, Type pt, Env 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 env; Infer.InferenceContext inferenceContext; Set stuckVars = new LinkedHashSet(); - StuckChecker(Type pt, Infer.InferenceContext inferenceContext) { + StuckChecker(Type pt, Env 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 freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes()); - stuckVars.addAll(freeArgVars); + Env 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 argtypes = ListBuffer.lb(); + for (Type t : descType.getParameterTypes()) { + argtypes.append(Type.noType); + } + JCMemberReference mref2 = new TreeCopier(make).copy(tree); + mref2.expr = exprTree; + Pair 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 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.nil(), MethodResolutionPhase.VARARITY) { + List args = rs.dummyArgs(tree.args.length()); + + Resolve.LookupHelper lh = rs.new LookupHelper(name, site, args, List.nil(), MethodResolutionPhase.VARARITY) { @Override Symbol lookup(Env env, MethodResolutionPhase phase) { return rec == null ? diff --git a/src/share/classes/com/sun/tools/javac/comp/Flow.java b/src/share/classes/com/sun/tools/javac/comp/Flow.java index df66e345703694674ad9307767b9749fb973f2dc..dbab4de383bd47e8d8dd5a3266c72ab5e9d132a4 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -373,6 +373,15 @@ public class Flow { boolean resolveBreaks(JCTree tree, ListBuffer

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); + } + } } /** diff --git a/src/share/classes/com/sun/tools/javac/comp/Infer.java b/src/share/classes/com/sun/tools/javac/comp/Infer.java index c5f4b271f2e2663354dfefdbb44250bae6fb1aad..ebc6867a4bad0a4bd661e01ba0c0fe726d8ba409 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -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 saved_undet = inferenceContext.save(); try { while (true) { mlistener.reset(); @@ -435,7 +451,9 @@ public class Infer { EnumSet 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 undetvars; @@ -468,13 +489,12 @@ public class Infer { public void varChanged(UndetVar uv, Set 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 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 incorporationCache = + new HashMap(); + /** * 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 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.nil(), 0); + } + + int computeMinPath(InferenceGraph g, Node n, List path, int cost) { + if (path.contains(n)) return Integer.MAX_VALUE; + List 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 costMap = new HashMap(); - ArrayList leaves = new ArrayList(); + final Map leavesMap = new HashMap(); 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() { + Assert.check(!leavesMap.isEmpty(), "No nodes to solve!"); + TreeSet orderedLeaves = new TreeSet(new Comparator() { 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 steps; @@ -1090,7 +1348,7 @@ public class Infer { while (!sstrategy.done()) { InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); List varsToSolve = List.from(nodeToSolve.data); - inferenceContext.save(); + List 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 inferencevars; - /** backed up inference variables */ - List saved_undet; - java.util.Map> freeTypeListeners = new java.util.HashMap>(); @@ -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 save() { ListBuffer 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 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; + } } /** diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 9b3457c7c8324df8d2cda7b82a53068162b4f729..24a69f09e96f3b1fe75bb0137412a1a58a667d4c 100644 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -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 typarams, + Type signature(MethodSymbol msym, + List typarams, List params, JCTree res, JCVariableDecl recvparam, @@ -392,8 +393,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer { ListBuffer thrownbuf = new ListBuffer(); for (List 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); diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 14f9d4bd2b6e828af944d94458e11d579293d898..ff4d048fd5ca4a3070aac810503c1ef5159646ec 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -345,7 +345,7 @@ public class Resolve { boolean isAccessible(Env 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 dummyArgs(int length) { + ListBuffer 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 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 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 argtypes, List 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 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 c = errCandidate(); if (compactMethodDiags) { for (Map.Entry _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 errCandidate() { Candidate bestSoFar = null; for (Candidate c : resolveContext.candidates) { if (c.isApplicable()) continue; bestSoFar = c; } Assert.checkNonNull(bestSoFar); - return bestSoFar; + return new Pair(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 _e = + filteredCandidates.entrySet().iterator().next(); + final Pair p = new Pair(_e.getKey(), _e.getValue()); + JCDiagnostic d = new InapplicableSymbolError(resolveContext) { + @Override + protected Pair errCandidate() { + return p; + } + }.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes); if (truncatedDiag) { d.setFlag(DiagnosticFlag.COMPRESSED); diff --git a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index b142df2ccc891e517c8f16755173023909284c00..9650422087cedadcd6009ffe202033221c3db57e 100644 --- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -303,8 +303,9 @@ public class RichDiagnosticFormatter extends conflicts.contains(s))) { List 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; } diff --git a/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java index b6f7d66dc3846c1e5076464c7d745b2d82c8c065..ba1908f218ffd7bf01b6ca6a47b6325a21801e9f 100644 --- a/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java @@ -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); } /** diff --git a/src/share/classes/com/sun/tools/javadoc/ToolOption.java b/src/share/classes/com/sun/tools/javadoc/ToolOption.java index 7b0936e77b86f075c9b5d7355b6eebcd91f79866..2bd68ed0b183ca64c4d04724f7873768be61dbdd 100644 --- a/src/share/classes/com/sun/tools/javadoc/ToolOption.java +++ b/src/share/classes/com/sun/tools/javadoc/ToolOption.java @@ -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) { diff --git a/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties b/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties index 3e384a165de76e91631190f4b5d2b3c48965a5f6..8ac2c3480e7a2d23850db649491db10ec5b68e71 100644 --- a/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties +++ b/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties @@ -39,6 +39,7 @@ main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\ \ -docletpath Specify where to find doclet class files\n\ \ -sourcepath Specify where to find source files\n\ \ -classpath Specify where to find user class files\n\ +\ -cp Specify where to find user class files\n\ \ -exclude Specify a list of packages to exclude\n\ \ -subpackages Specify subpackages to recursively load\n\ \ -breakiterator Compute first sentence with BreakIterator\n\ diff --git a/src/share/classes/com/sun/tools/javah/JavahTask.java b/src/share/classes/com/sun/tools/javah/JavahTask.java index d203f1140bbf8b5d28e0aca751aa2a06a57c248a..84b7c2b699d2a6b346a5a075a0dcfdbc0e6481dd 100644 --- a/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -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; diff --git a/src/share/classes/com/sun/tools/javah/resources/l10n.properties b/src/share/classes/com/sun/tools/javah/resources/l10n.properties index 632cd1581f9921f171a567fa1d2909108601ddcb..875816b2050a91c529104e3d212f7408da67761c 100644 --- a/src/share/classes/com/sun/tools/javah/resources/l10n.properties +++ b/src/share/classes/com/sun/tools/javah/resources/l10n.properties @@ -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 from which to load classes\n\t\ +-cp Path from which to load classes\n\t\ -bootclasspath Path from which to load bootstrap classes\n\t\ -d

Output directory\n\t\ -o 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 from which to load classes +main.opt.cp=\ +\ -cp Path from which to load classes main.opt.bootclasspath=\ \ -bootclasspath Path from which to load bootstrap classes main.usage.foot=\ diff --git a/src/share/classes/com/sun/tools/javap/JavapTask.java b/src/share/classes/com/sun/tools/javap/JavapTask.java index 77f9c3c89915f335eda018635021ac46ded6d944..0cafe023ccadb3a176bfe29f88e6a47b99aa6f2c 100644 --- a/src/share/classes/com/sun/tools/javap/JavapTask.java +++ b/src/share/classes/com/sun/tools/javap/JavapTask.java @@ -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; diff --git a/src/share/classes/com/sun/tools/javap/resources/javap.properties b/src/share/classes/com/sun/tools/javap/resources/javap.properties index 4a13d60197036e0407c77669651babe1ff95d4bc..c77024f75f59d867059ecfb1cc6367d4cb0342ca 100644 --- a/src/share/classes/com/sun/tools/javap/resources/javap.properties +++ b/src/share/classes/com/sun/tools/javap/resources/javap.properties @@ -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 Specify where to find user class files +main.opt.cp=\ +\ -cp Specify where to find user class files + main.opt.bootclasspath=\ \ -bootclasspath Override location of bootstrap class files diff --git a/test/tools/doclint/BadPackageCommentTest.java b/test/tools/doclint/BadPackageCommentTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a3f71f0849b0651ccb74f1ad871089cef35bc987 --- /dev/null +++ b/test/tools/doclint/BadPackageCommentTest.java @@ -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; diff --git a/test/tools/doclint/BadPackageCommentTest.out b/test/tools/doclint/BadPackageCommentTest.out new file mode 100644 index 0000000000000000000000000000000000000000..57b4db9c1b228dddbe4dcd8e79ee0c01f11b5977 --- /dev/null +++ b/test/tools/doclint/BadPackageCommentTest.out @@ -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 diff --git a/test/tools/doclint/tool/HelpTest.out b/test/tools/doclint/tool/HelpTest.out index 78db573f178cfda425efdf9937337bb419a3cafb..0d7d4020a7c80b8a0930084647af9eff5c2f497c 100644 --- a/test/tools/doclint/tool/HelpTest.out +++ b/test/tools/doclint/tool/HelpTest.out @@ -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 diff --git a/test/tools/javac/Diagnostics/compressed/T8020286.java b/test/tools/javac/Diagnostics/compressed/T8020286.java new file mode 100644 index 0000000000000000000000000000000000000000..eaf73ebc369479902cba7f84e3db423e82db1eef --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8020286.java @@ -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); + } +} diff --git a/test/tools/javac/Diagnostics/compressed/T8020286.out b/test/tools/javac/Diagnostics/compressed/T8020286.out new file mode 100644 index 0000000000000000000000000000000000000000..60801fd540c0a266dbadbbdf97a5d20335714267 --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8020286.out @@ -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 diff --git a/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java b/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ffdf34d5c8e08c8f0deca2ccb6a5e093cd73533d --- /dev/null +++ b/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java @@ -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; } + } +} diff --git a/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out b/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out new file mode 100644 index 0000000000000000000000000000000000000000..b600771774663afd4e64bd60aa81acbed7d90dd0 --- /dev/null +++ b/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out @@ -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 diff --git a/test/tools/javac/conditional/T8016702.java b/test/tools/javac/conditional/T8016702.java new file mode 100644 index 0000000000000000000000000000000000000000..df99fd6246530e41d1f56ab6091e63a33f7bdd8d --- /dev/null +++ b/test/tools/javac/conditional/T8016702.java @@ -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 m(int x); + } + + void test(List li) { + map(i -> (i % 2 == 0) ? "" : "i="+i, li); + } + + + @SuppressWarnings("unchecked") + void map(IntFunction mapper, List 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); + } +} diff --git a/test/tools/javac/generics/6723444/T6723444.java b/test/tools/javac/generics/6723444/T6723444.java index 6d7c3396304520518fd6372478bf74c1d7d6c507..faf563dcc109e8d63ce201d4d807a8936e86a92d 100644 --- a/test/tools/javac/generics/6723444/T6723444.java +++ b/test/tools/javac/generics/6723444/T6723444.java @@ -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 { diff --git a/test/tools/javac/generics/6723444/T6723444.out b/test/tools/javac/generics/6723444/T6723444_1.out similarity index 78% rename from test/tools/javac/generics/6723444/T6723444.out rename to test/tools/javac/generics/6723444/T6723444_1.out index 8fc9df443a3c63e747b6c85824791e9fac668439..0b1499374fd0aa79eb20408cbe2bb2b38e5d8f0b 100644 --- a/test/tools/javac/generics/6723444/T6723444.out +++ b/test/tools/javac/generics/6723444/T6723444_1.out @@ -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 diff --git a/test/tools/javac/generics/6723444/T6723444_2.out b/test/tools/javac/generics/6723444/T6723444_2.out new file mode 100644 index 0000000000000000000000000000000000000000..7fbc519aa41bcd683d48ecad7efba2d40901fe55 --- /dev/null +++ b/test/tools/javac/generics/6723444/T6723444_2.out @@ -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 diff --git a/test/tools/javac/generics/7015430/T7015430.java b/test/tools/javac/generics/7015430/T7015430.java index f875e530555261b22eae11f0d65b3ec7452e3520..c0f89d62e750faccc338b84ce7a59a4189084a8b 100644 --- a/test/tools/javac/generics/7015430/T7015430.java +++ b/test/tools/javac/generics/7015430/T7015430.java @@ -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 * */ diff --git a/test/tools/javac/generics/7015430/T7015430.out b/test/tools/javac/generics/7015430/T7015430.out deleted file mode 100644 index 6e33877e05e20f4779b3d960be8f07c145ce1f14..0000000000000000000000000000000000000000 --- a/test/tools/javac/generics/7015430/T7015430.out +++ /dev/null @@ -1,19 +0,0 @@ -T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 -T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 -T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 -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 diff --git a/test/tools/javac/generics/7015430/T7015430_1.out b/test/tools/javac/generics/7015430/T7015430_1.out new file mode 100644 index 0000000000000000000000000000000000000000..3bee4e5da71dafc7324cbcf3f4a92f1406265f0e --- /dev/null +++ b/test/tools/javac/generics/7015430/T7015430_1.out @@ -0,0 +1,19 @@ +T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +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 diff --git a/test/tools/javac/generics/7015430/T7015430_2.out b/test/tools/javac/generics/7015430/T7015430_2.out new file mode 100644 index 0000000000000000000000000000000000000000..da5be70691739a9c481e2cb2c64f31a6e27f4a60 --- /dev/null +++ b/test/tools/javac/generics/7015430/T7015430_2.out @@ -0,0 +1,15 @@ +T7015430.java:42:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:51:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, 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 +T7015430.java:69:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:78:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:105:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:114:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, 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 +T7015430.java:130:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +1 error +12 warnings diff --git a/test/tools/javac/generics/7034511/T7034511a.java b/test/tools/javac/generics/7034511/T7034511a.java index af1f5a97b1b83f292585442e2fb87e400921db52..26418d6308e7b7c719474d61cc64393e413bf3e0 100644 --- a/test/tools/javac/generics/7034511/T7034511a.java +++ b/test/tools/javac/generics/7034511/T7034511a.java @@ -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 { diff --git a/test/tools/javac/generics/7034511/T7034511a.out b/test/tools/javac/generics/7034511/T7034511a.out index e05cd632368bd3b998597b49af92bee27856b7ff..4ce8eafd27a32cb1497a7c5c022266f11a1ec625 100644 --- a/test/tools/javac/generics/7034511/T7034511a.out +++ b/test/tools/javac/generics/7034511/T7034511a.out @@ -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, (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, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String[], compiler.misc.type.captureof: 1, ?[])) 1 error diff --git a/test/tools/javac/generics/7034511/T7034511b.java b/test/tools/javac/generics/7034511/T7034511b.java index 2adebca079dadd012cd71177f540c69b1b7df912..93d16787e3c81d082075aa3fcddc6d66374adfea 100644 --- a/test/tools/javac/generics/7034511/T7034511b.java +++ b/test/tools/javac/generics/7034511/T7034511b.java @@ -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 toArray(E[] e) { return null; } diff --git a/test/tools/javac/generics/7034511/T7034511b.out b/test/tools/javac/generics/7034511/T7034511b.out index 8d0d9335b1018788f96f3ec5c06c78007b26d58b..1cff6c38d3892f206a7ab9d069af6df5c7dffdac 100644 --- a/test/tools/javac/generics/7034511/T7034511b.out +++ b/test/tools/javac/generics/7034511/T7034511b.out @@ -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, (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, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object[], compiler.misc.type.captureof: 1, ?[])) 1 error diff --git a/test/tools/javac/generics/7034511/T7041019.java b/test/tools/javac/generics/7034511/T7041019.java new file mode 100644 index 0000000000000000000000000000000000000000..78b7bed7101be0eeb6e68b0d8e27c6b2b10c3404 --- /dev/null +++ b/test/tools/javac/generics/7034511/T7041019.java @@ -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 { + List[] m(List l) { return null; } + + void test(List ls) { + int i = m(ls).length; + } +} diff --git a/test/tools/javac/generics/8016640/T8016640.java b/test/tools/javac/generics/8016640/T8016640.java new file mode 100644 index 0000000000000000000000000000000000000000..39e7c13e3eb15a58885466ca68ba199eb7c229cb --- /dev/null +++ b/test/tools/javac/generics/8016640/T8016640.java @@ -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 { } + static class BadFoo extends Foo { } +} diff --git a/test/tools/javac/generics/8016640/T8016640.out b/test/tools/javac/generics/8016640/T8016640.out new file mode 100644 index 0000000000000000000000000000000000000000..7731422f3016a29fb465e349b607e3a7a6d68ac2 --- /dev/null +++ b/test/tools/javac/generics/8016640/T8016640.out @@ -0,0 +1,2 @@ +T8016640.java:9:39: compiler.err.wrong.number.type.args: 2 +1 error diff --git a/test/tools/javac/generics/inference/8019824/T8019824.java b/test/tools/javac/generics/inference/8019824/T8019824.java new file mode 100644 index 0000000000000000000000000000000000000000..30f0effd87a63d04a9249ae26fa2db562b22006e --- /dev/null +++ b/test/tools/javac/generics/inference/8019824/T8019824.java @@ -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> cls) { + Foo foo = make(cls); + } + + > Foo make(Class cls) { return null; } + + interface Foo {} +} diff --git a/test/tools/javac/generics/inference/8019824/T8019824.out b/test/tools/javac/generics/inference/8019824/T8019824.out new file mode 100644 index 0000000000000000000000000000000000000000..481268c3436b85f6363094efb479f65784b77372 --- /dev/null +++ b/test/tools/javac/generics/inference/8019824/T8019824.out @@ -0,0 +1,2 @@ +T8019824.java:9:25: compiler.err.cant.apply.symbol: kindname.method, make, java.lang.Class, java.lang.Class>, kindname.class, T8019824, (compiler.misc.incompatible.eq.upper.bounds: C, compiler.misc.type.captureof: 1, ? extends T8019824.Foo, T8019824.Foo) +1 error diff --git a/test/tools/javac/generics/inference/8020149/T8020149.java b/test/tools/javac/generics/inference/8020149/T8020149.java new file mode 100644 index 0000000000000000000000000000000000000000..863fdaf0ee573f5e7bca86d727845257ad914a78 --- /dev/null +++ b/test/tools/javac/generics/inference/8020149/T8020149.java @@ -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 { } + + interface Foo> { } + + interface IntFoo extends Foo { } + + interface Function { + Y apply(X x); + } + + void test(TestData data) { + m1(data, s->s); + m2(data, s->s); + } + + , W, W_IN extends Foo> void m1(TestData data, Function m) { } + , E, E_OUT extends Foo> void m2(TestData data, Function m) { } +} diff --git a/test/tools/javac/lambda/8019480/T8019480.java b/test/tools/javac/lambda/8019480/T8019480.java new file mode 100644 index 0000000000000000000000000000000000000000..6d270b12a2b576975fd8ff65ac996d0d558168cb --- /dev/null +++ b/test/tools/javac/lambda/8019480/T8019480.java @@ -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 { + interface Predicate { + void m(T t); + } + + interface Stream { + void forEach(Predicate pt); + } + + void test(U current, Stream stream) { + List list3 = new ArrayList<>(); + stream.forEach(i -> list3.add(current.clone())); + } +} diff --git a/test/tools/javac/lambda/8019480/T8019480.out b/test/tools/javac/lambda/8019480/T8019480.out new file mode 100644 index 0000000000000000000000000000000000000000..afc509cb1dda104805921b31e4394a1dc9cf873f --- /dev/null +++ b/test/tools/javac/lambda/8019480/T8019480.out @@ -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 diff --git a/test/tools/javac/lambda/8020147/T8020147.java b/test/tools/javac/lambda/8020147/T8020147.java new file mode 100644 index 0000000000000000000000000000000000000000..ec2ae91eea05c6cbb3b599e8adb49b68ce6c13bd --- /dev/null +++ b/test/tools/javac/lambda/8020147/T8020147.java @@ -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 { + Y apply(X x); + } + + void g(Function f) { } + String m(U u, Function fuu) { return null; } + + void test() { + g(x->m("", i->(String)i)); + g(x->m("", i->(String)x)); + } +} diff --git a/test/tools/javac/lambda/8020147/T8020147.out b/test/tools/javac/lambda/8020147/T8020147.out new file mode 100644 index 0000000000000000000000000000000000000000..88a4aef0a8ab31441a075a7194063ae19a5ff394 --- /dev/null +++ b/test/tools/javac/lambda/8020147/T8020147.out @@ -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 diff --git a/test/tools/javac/lambda/BadNestedLambda.java b/test/tools/javac/lambda/BadNestedLambda.java new file mode 100644 index 0000000000000000000000000000000000000000..616c0868a336c6c3bcd9010720e541d29cd51cf2 --- /dev/null +++ b/test/tools/javac/lambda/BadNestedLambda.java @@ -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; + } +} diff --git a/test/tools/javac/lambda/BadNestedLambda.out b/test/tools/javac/lambda/BadNestedLambda.out new file mode 100644 index 0000000000000000000000000000000000000000..268ad85aa813e5cf65298b6de29e4413a5b7c1ef --- /dev/null +++ b/test/tools/javac/lambda/BadNestedLambda.out @@ -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 diff --git a/test/tools/javac/lambda/MethodReference68.java b/test/tools/javac/lambda/MethodReference68.java new file mode 100644 index 0000000000000000000000000000000000000000..fa5f861e8c36aaf839ffd62551c56d6b3e52d28e --- /dev/null +++ b/test/tools/javac/lambda/MethodReference68.java @@ -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 { + String m(X x); + } + + static class Foo { + String getName() { return ""; } + } + + @SuppressWarnings("unchecked") + void g(F fz, Z... zs) { } + + void test() { + g(Foo::getName); + g(Foo::getName, 1); //incompatible constraints, Z <: Foo, Z :> Integer + } +} diff --git a/test/tools/javac/lambda/MethodReference68.out b/test/tools/javac/lambda/MethodReference68.out new file mode 100644 index 0000000000000000000000000000000000000000..2db24d17bf030c48246af9800589ba0cefd8c40f --- /dev/null +++ b/test/tools/javac/lambda/MethodReference68.out @@ -0,0 +1,2 @@ +MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F,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 diff --git a/test/tools/javac/lambda/MethodReference69.java b/test/tools/javac/lambda/MethodReference69.java new file mode 100644 index 0000000000000000000000000000000000000000..70dc42da57c635e63f0a637e6b75d0891c682508 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference69.java @@ -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 { + String m(Integer x1, X x2); + } + + static class Foo { + String getNameAt(Integer i) { return ""; } + } + + void g(F fz) { } + + void test() { + g(Foo::getName); + } +} diff --git a/test/tools/javac/lambda/MethodReference69.out b/test/tools/javac/lambda/MethodReference69.out new file mode 100644 index 0000000000000000000000000000000000000000..de40b53e07d850337ceb785404dbd940604a7310 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference69.out @@ -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 diff --git a/test/tools/javac/lambda/MethodReference70.java b/test/tools/javac/lambda/MethodReference70.java new file mode 100644 index 0000000000000000000000000000000000000000..0cc26f5fd842f720fb306d383efff9658500ca76 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference70.java @@ -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 { + void m(X x); + } + + interface G { + Integer m(X x); + } + + void m1(Integer i) { } + + void m2(Integer i) { } + void m2(String i) { } + + void g(F fz) { } + void g(G gz) { } + + void test() { + g(this::m1); //ok + g(this::m2); //ambiguous (stuck!) + } +} diff --git a/test/tools/javac/lambda/MethodReference70.out b/test/tools/javac/lambda/MethodReference70.out new file mode 100644 index 0000000000000000000000000000000000000000..875b9d2d064a7e245eb93d340bd64bb3b97b0409 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference70.out @@ -0,0 +1,3 @@ +MethodReference70.java:26:10: compiler.err.ref.ambiguous: g, kindname.method, g(MethodReference70.F), MethodReference70, kindname.method, g(MethodReference70.G), MethodReference70 +MethodReference70.java:26:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z) +2 errors diff --git a/test/tools/javac/lambda/MethodReference71.java b/test/tools/javac/lambda/MethodReference71.java new file mode 100644 index 0000000000000000000000000000000000000000..5b59c7defaa9fe4c4a4f6b6df8dad7cc3888db68 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference71.java @@ -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 { + void m(X x); + } + + interface G { + Integer m(X x); + } + + void m1(Integer i) { } + void m2(Integer... i) { } + + void g(F f) { } + void g(G g) { } + + void test() { + g(this::m1); //ok + g(this::m2); //ambiguous (stuck!) + } +} diff --git a/test/tools/javac/lambda/MethodReference71.out b/test/tools/javac/lambda/MethodReference71.out new file mode 100644 index 0000000000000000000000000000000000000000..f1a8942e3d1f9820bb0ffca1150317a9fca14557 --- /dev/null +++ b/test/tools/javac/lambda/MethodReference71.out @@ -0,0 +1,3 @@ +MethodReference71.java:24:10: compiler.err.ref.ambiguous: g, kindname.method, g(MethodReference71.F), MethodReference71, kindname.method, g(MethodReference71.G), MethodReference71 +MethodReference71.java:24:11: compiler.err.prob.found.req: (compiler.misc.cyclic.inference: Z) +2 errors diff --git a/test/tools/javac/lambda/MethodReference72.java b/test/tools/javac/lambda/MethodReference72.java new file mode 100644 index 0000000000000000000000000000000000000000..b3dfa1bb44ba4dd113bf93d27955fd256b955d9f --- /dev/null +++ b/test/tools/javac/lambda/MethodReference72.java @@ -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 { + @SuppressWarnings("unchecked") + void m(X... x); + } + + void m1(Integer i) { } + + void g(F f) { } + + void test() { + g(this::m1); //? + } +} diff --git a/test/tools/javac/lambda/MethodReference72.out b/test/tools/javac/lambda/MethodReference72.out new file mode 100644 index 0000000000000000000000000000000000000000..cf4c08cf2fac3fad8ed7a1ade88f47d4d61dcf3e --- /dev/null +++ b/test/tools/javac/lambda/MethodReference72.out @@ -0,0 +1,2 @@ +MethodReference72.java:18:9: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference72.F, @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 diff --git a/test/tools/javac/lambda/NestedCapture01.java b/test/tools/javac/lambda/NestedCapture01.java new file mode 100644 index 0000000000000000000000000000000000000000..4b7e9036a0b95a2b4fded27575da2560e2da2da6 --- /dev/null +++ b/test/tools/javac/lambda/NestedCapture01.java @@ -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 m(Class cf) { + return null; + } + +

P g(P vo) { + return null; + } +} diff --git a/test/tools/javac/lambda/NestedCapture02.java b/test/tools/javac/lambda/NestedCapture02.java new file mode 100644 index 0000000000000000000000000000000000000000..89f2589139af049e1baa079dc48623a3ab376ad4 --- /dev/null +++ b/test/tools/javac/lambda/NestedCapture02.java @@ -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 { + + NestedCapture02 create(NestedCapture02 first, + NestedCapture02 second) { + return null; + } + + NestedCapture02 cast(Class target) { return null; } + + NestedCapture02 test(Class target, + NestedCapture02 first, NestedCapture02 second) { + return create(first, second.cast(target)); + } +} diff --git a/test/tools/javac/lambda/NestedCapture03.java b/test/tools/javac/lambda/NestedCapture03.java new file mode 100644 index 0000000000000000000000000000000000000000..11a0f2e5479c0bb261913673acf98bf4503c0241 --- /dev/null +++ b/test/tools/javac/lambda/NestedCapture03.java @@ -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 factory(Class c) { return null; } + + void test(Class c) { + factory(c.asSubclass(String.class)).matches(null); + } +} diff --git a/test/tools/javac/lambda/TargetType36.java b/test/tools/javac/lambda/TargetType36.java index 7740b5705e500402b14f3fdf1fbe9b8c985f165f..38f9c2add40725476f751f18111112eb78c994d7 100644 --- a/test/tools/javac/lambda/TargetType36.java +++ b/test/tools/javac/lambda/TargetType36.java @@ -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 diff --git a/test/tools/javac/lambda/TargetType36.out b/test/tools/javac/lambda/TargetType36.out new file mode 100644 index 0000000000000000000000000000000000000000..92542ddd1828946195fcfdef7c1f0764778c1abe --- /dev/null +++ b/test/tools/javac/lambda/TargetType36.out @@ -0,0 +1,3 @@ +TargetType36.java:40:30: compiler.err.unexpected.lambda +TargetType36.java:40:43: compiler.err.unexpected.lambda +2 errors diff --git a/test/tools/javac/lambda/TargetType60.out b/test/tools/javac/lambda/TargetType60.out index cbc5e13f4175fb27618cec5bedfa6266688e8ecf..e0bf52fc3e6066bc8cf7a36011cfa23ce95d5a8b 100644 --- a/test/tools/javac/lambda/TargetType60.out +++ b/test/tools/javac/lambda/TargetType60.out @@ -1,7 +1,7 @@ TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, g(TargetType60.Sam1), TargetType60 TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam1), TargetType60, kindname.method, g(TargetType60.Sam2), TargetType60 TargetType60.java:60:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), 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(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 diff --git a/test/tools/javac/lambda/TargetType63.java b/test/tools/javac/lambda/TargetType63.java new file mode 100644 index 0000000000000000000000000000000000000000..93d292a8342fb84ad4ab9c4ab305adcdd60b3539 --- /dev/null +++ b/test/tools/javac/lambda/TargetType63.java @@ -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 { + void m() throws T; + } + + void g1() { } + void g2() throws ClassNotFoundException { } + void g3() throws Exception { } + + void m1(F fz) throws Z { } + void m2(F 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) + } +} diff --git a/test/tools/javac/lambda/TargetType63.out b/test/tools/javac/lambda/TargetType63.out new file mode 100644 index 0000000000000000000000000000000000000000..cfacfe2dd35011fab71cb942dd0c2ee8c1ac8a52 --- /dev/null +++ b/test/tools/javac/lambda/TargetType63.out @@ -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 diff --git a/test/tools/javac/lambda/TargetType75.java b/test/tools/javac/lambda/TargetType75.java new file mode 100644 index 0000000000000000000000000000000000000000..a65b9b95bcbd6781537ca24941377197527cab75 --- /dev/null +++ b/test/tools/javac/lambda/TargetType75.java @@ -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 { + void m(X x); + } + + void m(P r, Z z) { } + + void test() { + m(x->{ return; }, ""); + m(x->System.out.println(""), ""); + } +} diff --git a/test/tools/javac/lambda/TargetType76.java b/test/tools/javac/lambda/TargetType76.java new file mode 100644 index 0000000000000000000000000000000000000000..c8a808628bb2e82dd717425044aa4a8e597dfb75 --- /dev/null +++ b/test/tools/javac/lambda/TargetType76.java @@ -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 { + Y m(X x); + } + + interface OfRef { } + + interface Supplier { + X make(); + } + + interface Stream { } + + interface Node { + Spliterator spliterator(); + } + + interface Spliterator { + Spliterator spliterator(); + } + + class RefTestData implements OfRef { + RefTestData(I state, + Function> streamFn, + Function> splitrFn) { } + } + + OfRef ofCollection(Node collection) { + return new RefTestData<>(collection, + x->stream(x::spliterator), + Node::spliterator); + } + + Stream stream(Supplier> supplier) { return null; } +} diff --git a/test/tools/javac/meth/VarargsWarn.java b/test/tools/javac/meth/VarargsWarn.java new file mode 100644 index 0000000000000000000000000000000000000000..476617b4eddb83bf20d3659ae51d350c964ac8c3 --- /dev/null +++ b/test/tools/javac/meth/VarargsWarn.java @@ -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! + } +} diff --git a/test/tools/javac/meth/VarargsWarn.out b/test/tools/javac/meth/VarargsWarn.out new file mode 100644 index 0000000000000000000000000000000000000000..13decfad07dae5914af26d3f93141d058dd9f5f4 --- /dev/null +++ b/test/tools/javac/meth/VarargsWarn.out @@ -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 diff --git a/test/tools/javac/warnings/6594914/Auxiliary.java b/test/tools/javac/warnings/6594914/Auxiliary.java new file mode 100644 index 0000000000000000000000000000000000000000..e9c881643e23a312f572da8f1116318b79e9ac87 --- /dev/null +++ b/test/tools/javac/warnings/6594914/Auxiliary.java @@ -0,0 +1,5 @@ +import java.io.StringBufferInputStream; + +public class Auxiliary { + +} diff --git a/test/tools/javac/warnings/6594914/ExplicitCompilation.out b/test/tools/javac/warnings/6594914/ExplicitCompilation.out new file mode 100644 index 0000000000000000000000000000000000000000..3dff7922cf75e8569f2bd3e4b51487e2905d21aa --- /dev/null +++ b/test/tools/javac/warnings/6594914/ExplicitCompilation.out @@ -0,0 +1,2 @@ +Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io +1 warning diff --git a/test/tools/javac/warnings/6594914/ImplicitCompilation.java b/test/tools/javac/warnings/6594914/ImplicitCompilation.java new file mode 100644 index 0000000000000000000000000000000000000000..6bf41567f5a016a88ae3e56f720d3bccba776026 --- /dev/null +++ b/test/tools/javac/warnings/6594914/ImplicitCompilation.java @@ -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; +} diff --git a/test/tools/javac/warnings/6594914/ImplicitCompilation.out b/test/tools/javac/warnings/6594914/ImplicitCompilation.out new file mode 100644 index 0000000000000000000000000000000000000000..3dff7922cf75e8569f2bd3e4b51487e2905d21aa --- /dev/null +++ b/test/tools/javac/warnings/6594914/ImplicitCompilation.out @@ -0,0 +1,2 @@ +Auxiliary.java:1:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io +1 warning diff --git a/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java b/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java index 06e94963fafcabb9356c7813380946aa31158645..709d8cbded91c730a0e252a5a64d87b3ea0dc38e 100644 --- a/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java +++ b/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java @@ -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 =