Mercurial > hg > openjdk > aarch64-port > langtools
changeset 2862:9a668535900b
Merge
author | asaha |
---|---|
date | Mon, 02 Mar 2015 12:13:35 -0800 |
parents | 2904142783dd (diff) cbbf2cd7ed1c (current diff) |
children | d727ca30ce3c |
files | .hgtags |
diffstat | 98 files changed, 4103 insertions(+), 1342 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Feb 10 15:02:50 2015 -0800 +++ b/.hgtags Mon Mar 02 12:13:35 2015 -0800 @@ -353,3 +353,29 @@ b813a76f10911ac8db2c775e52b29f36ab0005f4 jdk8u31-b31 8dc0c7e42d90c9f323582b742a7f228bad57b124 jdk8u31-b32 f75e26a5c3acc1ca9f5035dbfc4a40710d354dff jdk8u31-b33 +d231957fe3103e790465fcf058fb8cb33bbc4c4e jdk8u40-b00 +bf89a471779d13a9407f7d1c86f7716258bc4aa6 jdk8u40-b01 +0b6cc4ea670f5d17b56c088f202869bdbb80a5ce jdk8u40-b02 +5183e8b58a03206ca65b4b211be85b3740a70c39 jdk8u40-b03 +cde557bc48f5cd0c6b6aa70bdbc7563677379347 jdk8u40-b04 +a36fce70b505ec15be8353d40d417d331fcce740 jdk8u40-b05 +7c3d27120b92b6abbd2df910722405dfb02d4399 jdk8u40-b06 +2fa3858a281f9deae15bcc49224efd5b951b745d jdk8u40-b07 +d3515520e68e26c1012fca18eef190f8aff3a7a1 jdk8u40-b08 +8bb38a35072279618aa2cacd4fea74155a6dccf9 jdk8u40-b09 +69b84370397fbb5a66b99578242c47da7f8b3cb5 jdk8u40-b10 +d3c93dc64c5e1ffd610fb31362a78bedfd8097ba jdk8u40-b11 +e7560bceb36a933f5eb6ce8c33dce030ba0288f2 jdk8u40-b12 +88ce114c6adc387dc7fc5831b8263f152f0412fb jdk8u40-b13 +f18c5b47f27b387d94487890684abe5a554b0d9b jdk8u40-b14 +682a6c1aefd766eaf774ffeb1207a5189edf94d6 jdk8u40-b15 +74c51ff270c51d17732250411fe9cd5392bc925e jdk8u40-b16 +a12a9932f649dd3df174d3e340527433d3695c49 jdk8u40-b17 +94f30e5fde53e3ddcd3c4e9842349318eae8fe10 jdk8u40-b18 +0c514d1fd006fc79d35b670de10c370c8d559db7 jdk8u40-b19 +c3d6d1a5339952fbe4124e700407b7211446c99c jdk8u40-b20 +9113c7c8d902ec94b28ca0ef4a6466bdba65fcfc jdk8u40-b21 +79177246b3dbe5296fb53755d8695acdaef59fc8 jdk8u40-b22 +fb294b49373bda0b3afc7f011d64ecefed73b42e jdk8u40-b23 +c5d4ffa220f3824c2ea5d39dc99d41a9df9e5ae5 jdk8u40-b24 +991141080b2078e67179ff307a5051e59431762c jdk8u40-b25
--- a/THIRD_PARTY_README Tue Feb 10 15:02:50 2015 -0800 +++ b/THIRD_PARTY_README Mon Mar 02 12:13:35 2015 -0800 @@ -3385,7 +3385,7 @@ included with JRE 8, JDK 8, and OpenJDK 8. Apache Commons Math 3.2 - Apache Derby 10.10.1.3 + Apache Derby 10.11.1.2 Apache Jakarta BCEL 5.1 Apache Jakarta Regexp 1.4 Apache Santuario XML Security for Java 1.5.4
--- a/src/share/classes/com/sun/source/doctree/package-info.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/source/doctree/package-info.java Mon Mar 02 12:13:35 2015 -0800 @@ -29,7 +29,7 @@ * * @author Jonathan Gibbons * @since 1.8 - * @see <a href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags">http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags</a> + * @see <a href="https://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags">https://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags</a> */ @jdk.Exported package com.sun.source.doctree;
--- a/src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java Mon Mar 02 12:13:35 2015 -0800 @@ -29,7 +29,7 @@ /** * See JVMS 4.7.21 - * http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21 + * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21 * * <p><b>This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk.
--- a/src/share/classes/com/sun/tools/javac/code/Source.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Mon Mar 02 12:13:35 2015 -0800 @@ -233,6 +233,9 @@ public boolean allowFunctionalInterfaceMostSpecific() { return compareTo(JDK1_8) >= 0; } + public boolean allowPostApplicabilityVarargsAccessCheck() { + return compareTo(JDK1_8) >= 0; + } public static SourceVersion toSourceVersion(Source source) { switch(source) { case JDK1_2:
--- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Mar 02 12:13:35 2015 -0800 @@ -1305,7 +1305,8 @@ UndetVar undetvar = (UndetVar)t; WildcardType wt = (WildcardType)s.unannotatedType(); switch(wt.kind) { - case UNBOUND: //similar to ? extends Object + case UNBOUND: + break; case EXTENDS: { Type bound = wildUpperBound(s); undetvar.addBound(InferenceBound.UPPER, bound, this); @@ -1396,6 +1397,7 @@ else { // debugContainsType(t, s); return isSameWildcard(t, s) + || t.type == s || isCaptureOf(s, t) || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), cvarLowerBound(wildLowerBound(s)))) && // TODO: JDK-8039214, cvarUpperBound call here is incorrect @@ -1890,7 +1892,12 @@ * Mapping to take element type of an arraytype */ private Mapping elemTypeFun = new Mapping ("elemTypeFun") { - public Type apply(Type t) { return elemtype(t); } + public Type apply(Type t) { + while (t.hasTag(TYPEVAR)) { + t = t.getUpperBound(); + } + return elemtype(t); + } }; /** @@ -2954,6 +2961,12 @@ } @Override + public Type visitUndetVar(UndetVar t, Void ignored) { + //do nothing - we should not replace inside undet variables + return t; + } + + @Override public Type visitClassType(ClassType t, Void ignored) { if (!t.isCompound()) { List<Type> typarams = t.getTypeArguments(); @@ -3513,40 +3526,46 @@ } /** - * Return the least upper bound of pair of types. if the lub does + * Return the least upper bound of list of types. if the lub does * not exist return null. */ - public Type lub(Type t1, Type t2) { - return lub(List.of(t1, t2)); + public Type lub(List<Type> ts) { + return lub(ts.toArray(new Type[ts.length()])); } /** * Return the least upper bound (lub) of set of types. If the lub * does not exist return the type of null (bottom). */ - public Type lub(List<Type> ts) { + public Type lub(Type... ts) { + final int UNKNOWN_BOUND = 0; final int ARRAY_BOUND = 1; final int CLASS_BOUND = 2; - int boundkind = 0; - for (Type t : ts) { + + int[] kinds = new int[ts.length]; + + int boundkind = UNKNOWN_BOUND; + for (int i = 0 ; i < ts.length ; i++) { + Type t = ts[i]; switch (t.getTag()) { case CLASS: - boundkind |= CLASS_BOUND; + boundkind |= kinds[i] = CLASS_BOUND; break; case ARRAY: - boundkind |= ARRAY_BOUND; + boundkind |= kinds[i] = ARRAY_BOUND; break; case TYPEVAR: do { t = t.getUpperBound(); } while (t.hasTag(TYPEVAR)); if (t.hasTag(ARRAY)) { - boundkind |= ARRAY_BOUND; + boundkind |= kinds[i] = ARRAY_BOUND; } else { - boundkind |= CLASS_BOUND; + boundkind |= kinds[i] = CLASS_BOUND; } break; default: + kinds[i] = UNKNOWN_BOUND; if (t.isPrimitive()) return syms.errType; } @@ -3557,15 +3576,16 @@ case ARRAY_BOUND: // calculate lub(A[], B[]) - List<Type> elements = Type.map(ts, elemTypeFun); - for (Type t : elements) { - if (t.isPrimitive()) { + Type[] elements = new Type[ts.length]; + for (int i = 0 ; i < ts.length ; i++) { + Type elem = elements[i] = elemTypeFun.apply(ts[i]); + if (elem.isPrimitive()) { // if a primitive type is found, then return // arraySuperType unless all the types are the // same - Type first = ts.head; - for (Type s : ts.tail) { - if (!isSameType(first, s)) { + Type first = ts[0]; + for (int j = 1 ; j < ts.length ; j++) { + if (!isSameType(first, ts[j])) { // lub(int[], B[]) is Cloneable & Serializable return arraySuperType(); } @@ -3580,13 +3600,20 @@ case CLASS_BOUND: // calculate lub(A, B) - while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) { - ts = ts.tail; + int startIdx = 0; + for (int i = 0; i < ts.length ; i++) { + Type t = ts[i]; + if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) { + break; + } else { + startIdx++; + } } - Assert.check(!ts.isEmpty()); + Assert.check(startIdx < ts.length); //step 1 - compute erased candidate set (EC) - List<Type> cl = erasedSupertypes(ts.head); - for (Type t : ts.tail) { + List<Type> cl = erasedSupertypes(ts[startIdx]); + for (int i = startIdx + 1 ; i < ts.length ; i++) { + Type t = ts[i]; if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) cl = intersect(cl, erasedSupertypes(t)); } @@ -3595,9 +3622,10 @@ //step 3 - for each element G in MEC, compute lci(Inv(G)) List<Type> candidates = List.nil(); for (Type erasedSupertype : mec) { - List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym)); - for (Type t : ts) { - lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym))); + List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym)); + for (int i = startIdx + 1 ; i < ts.length ; i++) { + Type superType = asSuper(ts[i], erasedSupertype.tsym); + lci = intersect(lci, superType != null ? List.of(superType) : List.<Type>nil()); } candidates = candidates.appendList(lci); } @@ -3608,9 +3636,9 @@ default: // calculate lub(A, B[]) List<Type> classes = List.of(arraySuperType()); - for (Type t : ts) { - if (!t.hasTag(ARRAY)) // Filter out any arrays - classes = classes.prepend(t); + for (int i = 0 ; i < ts.length ; i++) { + if (kinds[i] != ARRAY_BOUND) // Filter out any arrays + classes = classes.prepend(ts[i]); } // lub(A, B[]) is lub(A, arraySuperType) return lub(classes);
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Mar 02 12:13:35 2015 -0800 @@ -252,36 +252,30 @@ */ Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) { InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); - Type owntype = found; - if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { - if (allowPoly && inferenceContext.free(found)) { - if ((ownkind & ~resultInfo.pkind) == 0) { - owntype = resultInfo.check(tree, inferenceContext.asUndetVar(owntype)); - } else { - log.error(tree.pos(), "unexpected.type", - kindNames(resultInfo.pkind), - kindName(ownkind)); - owntype = types.createErrorType(owntype); - } + Type owntype; + if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { + if ((ownkind & ~resultInfo.pkind) != 0) { + log.error(tree.pos(), "unexpected.type", + kindNames(resultInfo.pkind), + kindName(ownkind)); + owntype = types.createErrorType(found); + } else if (allowPoly && inferenceContext.free(found)) { + //delay the check if there are inference variables in the found type + //this means we are dealing with a partially inferred poly expression + owntype = resultInfo.pt; inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { @Override public void typesInferred(InferenceContext inferenceContext) { ResultInfo pendingResult = - resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); + resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); check(tree, inferenceContext.asInstType(found), ownkind, pendingResult); } }); - return tree.type = resultInfo.pt; } else { - if ((ownkind & ~resultInfo.pkind) == 0) { - owntype = resultInfo.check(tree, owntype); - } else { - log.error(tree.pos(), "unexpected.type", - kindNames(resultInfo.pkind), - kindName(ownkind)); - owntype = types.createErrorType(owntype); - } + owntype = resultInfo.check(tree, found); } + } else { + owntype = found; } tree.type = owntype; return owntype; @@ -293,7 +287,7 @@ * @param env The current environment. */ boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) { - Symbol owner = owner(env); + Symbol owner = env.info.scope.owner; // owner refers to the innermost variable, method or // initializer block declaration at this point. return @@ -308,41 +302,6 @@ ((v.flags() & STATIC) != 0) == Resolve.isStatic(env)); } - /** - * Return the innermost enclosing owner symbol in a given attribution context - */ - Symbol owner(Env<AttrContext> env) { - while (true) { - switch (env.tree.getTag()) { - case VARDEF: - //a field can be owner - VarSymbol vsym = ((JCVariableDecl)env.tree).sym; - if (vsym.owner.kind == TYP) { - return vsym; - } - break; - case METHODDEF: - //method def is always an owner - return ((JCMethodDecl)env.tree).sym; - case CLASSDEF: - //class def is always an owner - return ((JCClassDecl)env.tree).sym; - case BLOCK: - //static/instance init blocks are owner - Symbol blockSym = env.info.scope.owner; - if ((blockSym.flags() & BLOCK) != 0) { - return blockSym; - } - break; - case TOPLEVEL: - //toplevel is always an owner (for pkge decls) - return env.info.scope.owner; - } - Assert.checkNonNull(env.next); - env = env.next; - } - } - /** Check that variable can be assigned to. * @param pos The current source code position. * @param v The assigned varaible @@ -1051,8 +1010,12 @@ // parameters have already been entered env.info.scope.enter(tree.sym); } else { - memberEnter.memberEnter(tree, env); - annotate.flush(); + try { + annotate.enterStart(); + memberEnter.memberEnter(tree, env); + } finally { + annotate.enterDone(); + } } } else { if (tree.init != null) { @@ -2335,6 +2298,7 @@ currentTarget = infer.instantiateFunctionalInterface(that, currentTarget, explicitParamTypes, resultInfo.checkContext); } + currentTarget = types.removeWildcards(currentTarget); lambdaType = types.findDescriptorType(currentTarget); } else { currentTarget = Type.recoveryType; @@ -2727,7 +2691,7 @@ resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && isSerializable(currentTarget); if (currentTarget != Type.recoveryType) { - currentTarget = targetChecker.visit(currentTarget, that); + currentTarget = types.removeWildcards(targetChecker.visit(currentTarget, that)); desc = types.findDescriptorType(currentTarget); } else { currentTarget = Type.recoveryType; @@ -3262,8 +3226,9 @@ elt = ((ArrayType)elt.unannotatedType()).elemtype; if (elt.hasTag(TYPEVAR)) { log.error(tree.pos(), "type.var.cant.be.deref"); - result = types.createErrorType(tree.type); - return; + result = tree.type = types.createErrorType(tree.name, site.tsym, site); + tree.sym = tree.type.tsym; + return ; } } @@ -3279,6 +3244,10 @@ // Determine the symbol represented by the selection. env.info.pendingResolutionPhase = null; Symbol sym = selectSym(tree, sitesym, site, env, resultInfo); + if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) { + log.error(tree.selected.pos(), "not.encl.class", site.tsym); + sym = syms.errSymbol; + } if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) { site = capture(site); sym = selectSym(tree, sitesym, site, env, resultInfo); @@ -3665,7 +3634,7 @@ // and are subject to definite assignment checking. if ((env.info.enclVar == v || v.pos > tree.pos) && v.owner.kind == TYP && - canOwnInitializer(owner(env)) && + enclosingInitEnv(env) != null && v.owner == env.info.scope.owner.enclClass() && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && (!env.tree.hasTag(ASSIGN) || @@ -3685,6 +3654,36 @@ } /** + * Returns the enclosing init environment associated with this env (if any). An init env + * can be either a field declaration env or a static/instance initializer env. + */ + Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) { + while (true) { + switch (env.tree.getTag()) { + case VARDEF: + JCVariableDecl vdecl = (JCVariableDecl)env.tree; + if (vdecl.sym.owner.kind == TYP) { + //field + return env; + } + break; + case BLOCK: + if (env.next.tree.hasTag(CLASSDEF)) { + //instance/static initializer + return env; + } + break; + case METHODDEF: + case CLASSDEF: + case TOPLEVEL: + return null; + } + Assert.checkNonNull(env.next); + env = env.next; + } + } + + /** * Check for illegal references to static members of enum. In * an enum type, constructors and initializers may not * reference its static members unless they are constant. @@ -3737,17 +3736,6 @@ v.name != names._class; } - /** Can the given symbol be the owner of code which forms part - * if class initialization? This is the case if the symbol is - * a type or field, or if the symbol is the synthetic method. - * owning a block. - */ - private boolean canOwnInitializer(Symbol sym) { - return - (sym.kind & (VAR | TYP)) != 0 || - (sym.kind == MTH && (sym.flags() & BLOCK) != 0); - } - Warner noteWarner = new Warner(); /** @@ -4516,14 +4504,15 @@ super.visitTypeTest(tree); } public void visitNewClass(JCNewClass tree) { - if (tree.clazz.hasTag(ANNOTATED_TYPE)) { - checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, - tree.clazz.type.tsym); - } - if (tree.def != null) { - checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym); - } - if (tree.clazz.type != null) { + if (tree.clazz != null && tree.clazz.type != null) { + if (tree.clazz.hasTag(ANNOTATED_TYPE)) { + checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, + tree.clazz.type.tsym); + } + if (tree.def != null) { + checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym); + } + validateAnnotatedType(tree.clazz, tree.clazz.type); } super.visitNewClass(tree);
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Mar 02 12:13:35 2015 -0800 @@ -531,8 +531,8 @@ Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) { final Infer.InferenceContext inferenceContext = checkContext.inferenceContext(); - if (inferenceContext.free(req)) { - inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() { + if (inferenceContext.free(req) || inferenceContext.free(found)) { + inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() { @Override public void typesInferred(InferenceContext inferenceContext) { checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext); @@ -1715,7 +1715,12 @@ // Warn if a deprecated method overridden by a non-deprecated one. if (!isDeprecatedOverrideIgnorable(other, origin)) { - checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other); + Lint prevLint = setLint(lint.augment(m)); + try { + checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other); + } finally { + setLint(prevLint); + } } } // where
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Mon Mar 02 12:13:35 2015 -0800 @@ -497,13 +497,11 @@ } } if (!progress) { - DeferredAttrContext dac = this; - while (dac != emptyDeferredAttrContext) { - if (dac.mode == AttrMode.SPECULATIVE) { - //unsticking does not take place during overload - break; + if (insideOverloadPhase()) { + for (DeferredAttrNode deferredNode: deferredAttrNodes) { + deferredNode.dt.tree.type = Type.noType; } - dac = dac.parent; + return; } //remove all variables that have already been instantiated //from the list of stuck variables @@ -519,6 +517,17 @@ } } } + + private boolean insideOverloadPhase() { + DeferredAttrContext dac = this; + if (dac == emptyDeferredAttrContext) { + return false; + } + if (dac.mode == AttrMode.SPECULATIVE) { + return true; + } + return dac.parent.insideOverloadPhase(); + } } /** @@ -579,6 +588,8 @@ return false; } } else { + Assert.check(!deferredAttrContext.insideOverloadPhase(), + "attribution shouldn't be happening here"); ResultInfo instResultInfo = resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt)); dt.check(instResultInfo, dummyStuckPolicy, basicCompleter); @@ -1314,6 +1325,12 @@ site = env.enclClass.sym.type; } + while (site.hasTag(TYPEVAR)) { + site = site.getUpperBound(); + } + + site = types.capture(site); + List<Type> args = rs.dummyArgs(tree.args.length()); Name name = TreeInfo.name(tree.meth); @@ -1337,7 +1354,9 @@ @Override public Symbol process(MethodSymbol ms) { ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types); - return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null; + if (kind == ArgumentExpressionKind.POLY || ms.getReturnType().hasTag(TYPEVAR)) + return null; + return ms.getReturnType().tsym; } @Override public Symbol reduce(Symbol s1, Symbol s2) {
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Mon Mar 02 12:13:35 2015 -0800 @@ -208,7 +208,7 @@ public void analyzeTree(Env<AttrContext> env, TreeMaker make) { new AliveAnalyzer().analyzeTree(env, make); - new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); + new AssignAnalyzer().analyzeTree(env); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); } @@ -241,13 +241,19 @@ //related errors, which will allow for more errors to be detected Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); try { - new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) { + new AssignAnalyzer() { + Scope enclosedSymbols = new Scope(env.enclClass.sym); + @Override + public void visitVarDef(JCVariableDecl tree) { + enclosedSymbols.enter(tree.sym); + super.visitVarDef(tree); + } @Override protected boolean trackable(VarSymbol sym) { - return !env.info.scope.includes(sym) && + return enclosedSymbols.includes(sym) && sym.owner.kind == MTH; } - }.analyzeTree(env); + }.analyzeTree(env, that); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; @@ -1373,12 +1379,12 @@ * effectively-final local variables/parameters. */ - public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit> + public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit> extends BaseAnalyzer<P> { /** The set of definitely assigned variables. */ - protected final Bits inits; + protected Bits inits; /** The set of definitely unassigned variables. */ @@ -1432,13 +1438,7 @@ /** The starting position of the analysed tree */ int startPos; - final Symtab syms; - - protected Names names; - - final boolean enforceThisDotInit; - - public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { + public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { final Bits inits; final Bits uninits; @@ -1460,17 +1460,14 @@ } } - public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) { - this.inits = inits; + public AbstractAssignAnalyzer() { + this.inits = new Bits(); uninits = new Bits(); uninitsTry = new Bits(); initsWhenTrue = new Bits(true); initsWhenFalse = new Bits(true); uninitsWhenTrue = new Bits(true); uninitsWhenFalse = new Bits(true); - this.syms = syms; - this.names = names; - this.enforceThisDotInit = enforceThisDotInit; } private boolean isInitialConstructor = false; @@ -2439,26 +2436,15 @@ } } - public static class AssignAnalyzer - extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> { + public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> { - Log log; - Lint lint; - - public static class AssignPendingExit - extends AbstractAssignAnalyzer.AbstractAssignPendingExit { + public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit { public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { super(tree, inits, uninits); } } - public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) { - super(new Bits(), syms, names, enforceThisDotInit); - this.log = log; - this.lint = lint; - } - @Override protected AssignPendingExit createNewPendingExit(JCTree tree, Bits inits, Bits uninits) {
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Mon Mar 02 12:13:35 2015 -0800 @@ -353,6 +353,7 @@ Type to, Attr.ResultInfo resultInfo, InferenceContext inferenceContext) { inferenceContext.solve(List.of(from.qtype), new Warner()); + inferenceContext.notifyChange(); Type capturedType = resultInfo.checkContext.inferenceContext() .cachedCapture(tree, from.inst, false); if (types.isConvertible(capturedType, @@ -449,7 +450,7 @@ class ImplicitArgType extends DeferredAttr.DeferredTypeMap { public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) { - rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase); + (rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase); } public Type apply(Type t) { @@ -517,6 +518,8 @@ //or if it's not a subtype of the original target, issue an error checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); } + //propagate constraints as per JLS 18.2.1 + checkContext.compatible(owntype, funcInterface, types.noWarnings); return owntype; } } @@ -781,7 +784,10 @@ while (tmpTail.nonEmpty()) { Type b1 = boundList.head; Type b2 = tmpTail.head; - if (b1 != b2) { + /* This wildcard check is temporary workaround. This code may need to be + * revisited once spec bug JDK-7034922 is fixed. + */ + if (b1 != b2 && !b1.hasTag(WILDCARD) && !b2.hasTag(WILDCARD)) { Pair<Type, Type> commonSupers = infer.getParameterizedSupers(b1, b2); if (commonSupers != null) { List<Type> allParamsSuperBound1 = commonSupers.fst.allparams();
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Mar 02 12:13:35 2015 -0800 @@ -41,6 +41,7 @@ import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.MethodType; +import com.sun.tools.javac.code.Type.TypeVar; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*; import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector; @@ -61,6 +62,7 @@ import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; +import javax.lang.model.type.TypeKind; /** * This pass desugars lambda expressions into static methods @@ -321,7 +323,9 @@ ListBuffer<JCExpression> syntheticInits = new ListBuffer<>(); - if (!sym.isStatic()) { + if (localContext.methodReferenceReceiver != null) { + syntheticInits.append(localContext.methodReferenceReceiver); + } else if (!sym.isStatic()) { syntheticInits.append(makeThis( sym.owner.enclClass().asType(), localContext.owner.enclClass())); @@ -364,17 +368,10 @@ //first determine the method symbol to be used to generate the sam instance //this is either the method reference symbol, or the bridged reference symbol - Symbol refSym = localContext.needsBridge() - ? localContext.bridgeSym - : localContext.isSignaturePolymorphic() + Symbol refSym = localContext.isSignaturePolymorphic() ? localContext.sigPolySym : tree.sym; - //build the bridge method, if needed - if (localContext.needsBridge()) { - bridgeMemberReference(tree, localContext); - } - //the qualifying expression is treated as a special captured arg JCExpression init; switch(tree.kind) { @@ -744,126 +741,146 @@ // </editor-fold> /** - * Generate an adapter method "bridge" for a method reference which cannot - * be used directly. + * Converts a method reference which cannot be used directly into a lambda */ - private class MemberReferenceBridger { + private class MemberReferenceToLambda { private final JCMemberReference tree; private final ReferenceTranslationContext localContext; + private final Symbol owner; private final ListBuffer<JCExpression> args = new ListBuffer<>(); private final ListBuffer<JCVariableDecl> params = new ListBuffer<>(); - MemberReferenceBridger(JCMemberReference tree, ReferenceTranslationContext localContext) { + private JCExpression receiverExpression = null; + + MemberReferenceToLambda(JCMemberReference tree, ReferenceTranslationContext localContext, Symbol owner) { this.tree = tree; this.localContext = localContext; + this.owner = owner; } - /** - * Generate the bridge - */ - JCMethodDecl bridge() { + JCLambda lambda() { int prevPos = make.pos; try { make.at(tree); - Type samDesc = localContext.bridgedRefSig(); - List<Type> samPTypes = samDesc.getParameterTypes(); - - //an extra argument is prepended to the signature of the bridge in case - //the member reference is an instance method reference (in which case - //the receiver expression is passed to the bridge itself). - Type recType = null; - switch (tree.kind) { - case IMPLICIT_INNER: - recType = tree.sym.owner.type.getEnclosingType(); - break; - case BOUND: - recType = tree.getQualifierExpression().type; - break; - case UNBOUND: - recType = samPTypes.head; - samPTypes = samPTypes.tail; - break; - } - - //generate the parameter list for the bridged member reference - the - //bridge signature will match the signature of the target sam descriptor - - VarSymbol rcvr = (recType == null) - ? null - : addParameter("rec$", recType, false); - - List<Type> refPTypes = tree.sym.type.getParameterTypes(); - int refSize = refPTypes.size(); - int samSize = samPTypes.size(); - // Last parameter to copy from referenced method - int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize; - List<Type> l = refPTypes; - // Use parameter types of the referenced method, excluding final var args - for (int i = 0; l.nonEmpty() && i < last; ++i) { - addParameter("x$" + i, l.head, true); - l = l.tail; - } - // Flatten out the var args - for (int i = last; i < samSize; ++i) { - addParameter("xva$" + i, tree.varargsElement, true); - } + //body generation - this can be either a method call or a + //new instance creation expression, depending on the member reference kind + VarSymbol rcvr = addParametersReturnReceiver(); + JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE) + ? expressionInvoke(rcvr) + : expressionNew(); - //generate the bridge method declaration - JCMethodDecl bridgeDecl = make.MethodDef(make.Modifiers(localContext.bridgeSym.flags()), - localContext.bridgeSym.name, - make.QualIdent(samDesc.getReturnType().tsym), - List.<JCTypeParameter>nil(), - params.toList(), - tree.sym.type.getThrownTypes() == null - ? List.<JCExpression>nil() - : make.Types(tree.sym.type.getThrownTypes()), - null, - null); - bridgeDecl.sym = (MethodSymbol) localContext.bridgeSym; - bridgeDecl.type = localContext.bridgeSym.type = - types.createMethodTypeWithParameters(samDesc, TreeInfo.types(params.toList())); - - //bridge method body generation - this can be either a method call or a - //new instance creation expression, depending on the member reference kind - JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE) - ? bridgeExpressionInvoke(makeReceiver(rcvr)) - : bridgeExpressionNew(); - - //the body is either a return expression containing a method call, - //or the method call itself, depending on whether the return type of - //the bridge is non-void/void. - bridgeDecl.body = makeLambdaExpressionBody(bridgeExpr, bridgeDecl); - - return bridgeDecl; + JCLambda slam = make.Lambda(params.toList(), expr); + slam.targets = tree.targets; + slam.type = tree.type; + slam.pos = tree.pos; + return slam; } finally { make.at(prevPos); } } - //where - private JCExpression makeReceiver(VarSymbol rcvr) { - if (rcvr == null) return null; - JCExpression rcvrExpr = make.Ident(rcvr); - Type rcvrType = tree.sym.enclClass().type; - if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) { - rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType); + + /** + * Generate the parameter list for the converted member reference. + * + * @return The receiver variable symbol, if any + */ + VarSymbol addParametersReturnReceiver() { + Type samDesc = localContext.bridgedRefSig(); + List<Type> samPTypes = samDesc.getParameterTypes(); + List<Type> descPTypes = tree.getDescriptorType(types).getParameterTypes(); + + // Determine the receiver, if any + VarSymbol rcvr; + switch (tree.kind) { + case BOUND: + // The receiver is explicit in the method reference + rcvr = addParameter("rec$", tree.getQualifierExpression().type, false); + receiverExpression = attr.makeNullCheck(tree.getQualifierExpression()); + break; + case UNBOUND: + // The receiver is the first parameter, extract it and + // adjust the SAM and unerased type lists accordingly + rcvr = addParameter("rec$", samDesc.getParameterTypes().head, false); + samPTypes = samPTypes.tail; + descPTypes = descPTypes.tail; + break; + default: + rcvr = null; + break; + } + List<Type> implPTypes = tree.sym.type.getParameterTypes(); + int implSize = implPTypes.size(); + int samSize = samPTypes.size(); + // Last parameter to copy from referenced method, exclude final var args + int last = localContext.needsVarArgsConversion() ? implSize - 1 : implSize; + + // Failsafe -- assure match-up + boolean checkForIntersection = tree.varargsElement != null || implSize == descPTypes.size(); + + // Use parameter types of the implementation method unless the unerased + // SAM parameter type is an intersection type, in that case use the + // erased SAM parameter type so that the supertype relationship + // the implementation method parameters is not obscured. + // Note: in this loop, the lists implPTypes, samPTypes, and descPTypes + // are used as pointers to the current parameter type information + // and are thus not usable afterwards. + for (int i = 0; implPTypes.nonEmpty() && i < last; ++i) { + // By default use the implementation method parmeter type + Type parmType = implPTypes.head; + // If the unerased parameter type is a type variable whose + // bound is an intersection (eg. <T extends A & B>) then + // use the SAM parameter type + if (checkForIntersection && descPTypes.head.getKind() == TypeKind.TYPEVAR) { + TypeVar tv = (TypeVar) descPTypes.head; + if (tv.bound.getKind() == TypeKind.INTERSECTION) { + parmType = samPTypes.head; + } } - return rcvrExpr; + addParameter("x$" + i, parmType, true); + + // Advance to the next parameter + implPTypes = implPTypes.tail; + samPTypes = samPTypes.tail; + descPTypes = descPTypes.tail; + } + // Flatten out the var args + for (int i = last; i < samSize; ++i) { + addParameter("xva$" + i, tree.varargsElement, true); } + return rcvr; + } + + JCExpression getReceiverExpression() { + return receiverExpression; + } + + private JCExpression makeReceiver(VarSymbol rcvr) { + if (rcvr == null) return null; + JCExpression rcvrExpr = make.Ident(rcvr); + Type rcvrType = tree.sym.enclClass().type; + if (rcvrType == syms.arrayClass.type) { + // Map the receiver type to the actually type, not just "array" + rcvrType = tree.getQualifierExpression().type; + } + if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) { + rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType); + } + return rcvrExpr; + } + /** - * determine the receiver of the bridged method call - the receiver can - * be either the synthetic receiver parameter or a type qualifier; the - * original qualifier expression is never used here, as it might refer - * to symbols not available in the static context of the bridge + * determine the receiver of the method call - the receiver can + * be a type qualifier, the synthetic receiver parameter or 'super'. */ - private JCExpression bridgeExpressionInvoke(JCExpression rcvr) { + private JCExpression expressionInvoke(VarSymbol rcvr) { JCExpression qualifier = tree.sym.isStatic() ? make.Type(tree.sym.owner.type) : (rcvr != null) ? - rcvr : + makeReceiver(rcvr) : tree.getQualifierExpression(); //create the qualifier expression @@ -882,10 +899,9 @@ } /** - * the enclosing expression is either 'null' (no enclosing type) or set - * to the first bridge synthetic parameter + * Lambda body to use for a 'new'. */ - private JCExpression bridgeExpressionNew() { + private JCExpression expressionNew() { if (tree.kind == ReferenceKind.ARRAY_CTOR) { //create the array creation expression JCNewArray newArr = make.NewArray( @@ -895,15 +911,10 @@ newArr.type = tree.getQualifierExpression().type; return newArr; } else { - JCExpression encl = null; - switch (tree.kind) { - case UNBOUND: - case IMPLICIT_INNER: - encl = make.Ident(params.first()); - } - //create the instance creation expression - JCNewClass newClass = make.NewClass(encl, + //note that method reference syntax does not allow an explicit + //enclosing class (so the enclosing class is null) + JCNewClass newClass = make.NewClass(null, List.<JCExpression>nil(), make.Type(tree.getQualifierExpression().type), convertArgs(tree.sym, args.toList(), tree.varargsElement), @@ -917,7 +928,8 @@ } private VarSymbol addParameter(String name, Type p, boolean genArg) { - VarSymbol vsym = new VarSymbol(0, names.fromString(name), p, localContext.bridgeSym); + VarSymbol vsym = new VarSymbol(PARAMETER | SYNTHETIC, names.fromString(name), p, owner); + vsym.pos = tree.pos; params.append(make.VarDef(vsym, null)); if (genArg) { args.append(make.Ident(vsym)); @@ -926,15 +938,6 @@ } } - /** - * Bridges a member reference - this is needed when: - * * Var args in the referenced method need to be flattened away - * * super is used - */ - private void bridgeMemberReference(JCMemberReference tree, ReferenceTranslationContext localContext) { - kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge()); - } - private MethodType typeToMethodType(Type mt) { Type type = types.erasure(mt); return new MethodType(type.getParameterTypes(), @@ -1254,9 +1257,25 @@ @Override public void visitLambda(JCLambda tree) { + analyzeLambda(tree, "lambda.stat"); + } + + private void analyzeLambda(JCLambda tree, JCExpression methodReferenceReceiver) { + // Translation of the receiver expression must occur first + JCExpression rcvr = translate(methodReferenceReceiver); + LambdaTranslationContext context = analyzeLambda(tree, "mref.stat.1"); + if (rcvr != null) { + context.methodReferenceReceiver = rcvr; + } + } + + private LambdaTranslationContext analyzeLambda(JCLambda tree, String statKey) { List<Frame> prevStack = frameStack; try { - LambdaTranslationContext context = (LambdaTranslationContext)makeLambdaContext(tree); + LambdaTranslationContext context = new LambdaTranslationContext(tree); + if (dumpLambdaToMethodStats) { + log.note(tree, statKey, context.needsAltMetafactory(), context.translatedSym); + } frameStack = frameStack.prepend(new Frame(tree)); for (JCVariableDecl param : tree.params) { context.addSymbol(param.sym, PARAM); @@ -1265,6 +1284,7 @@ contextMap.put(tree, context); super.visitLambda(tree); context.complete(); + return context; } finally { frameStack = prevStack; @@ -1353,47 +1373,24 @@ * information added in the LambdaToMethod pass will have the wrong * signature. Hooks between Lower and LambdaToMethod have been added to * handle normal "new" in this case. This visitor converts potentially - * effected method references into a lambda containing a normal "new" of - * the class. + * affected method references into a lambda containing a normal + * expression. * * @param tree */ @Override public void visitReference(JCMemberReference tree) { - if (tree.getMode() == ReferenceMode.NEW - && tree.kind != ReferenceKind.ARRAY_CTOR - && tree.sym.owner.isLocal()) { - MethodSymbol consSym = (MethodSymbol) tree.sym; - List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes(); - Type classType = consSym.owner.type; - - // Build lambda parameters - // partially cloned from TreeMaker.Params until 8014021 is fixed - Symbol owner = owner(); - ListBuffer<JCVariableDecl> paramBuff = new ListBuffer<JCVariableDecl>(); - int i = 0; - for (List<Type> l = ptypes; l.nonEmpty(); l = l.tail) { - JCVariableDecl param = make.Param(make.paramName(i++), l.head, owner); - param.sym.pos = tree.pos; - paramBuff.append(param); - } - List<JCVariableDecl> params = paramBuff.toList(); - - // Make new-class call - JCNewClass nc = makeNewClass(classType, make.Idents(params)); - nc.pos = tree.pos; - - // Make lambda holding the new-class call - JCLambda slam = make.Lambda(params, nc); - slam.targets = tree.targets; - slam.type = tree.type; - slam.pos = tree.pos; - - // Now it is a lambda, process as such - visitLambda(slam); + ReferenceTranslationContext rcontext = new ReferenceTranslationContext(tree); + contextMap.put(tree, rcontext); + if (rcontext.needsConversionToLambda()) { + // Convert to a lambda, and process as such + MemberReferenceToLambda conv = new MemberReferenceToLambda(tree, rcontext, owner()); + analyzeLambda(conv.lambda(), conv.getReceiverExpression()); } else { super.visitReference(tree); - contextMap.put(tree, makeReferenceContext(tree)); + if (dumpLambdaToMethodStats) { + log.note(tree, "mref.stat", rcontext.needsAltMetafactory(), null); + } } } @@ -1648,14 +1645,6 @@ } } - private TranslationContext<JCLambda> makeLambdaContext(JCLambda tree) { - return new LambdaTranslationContext(tree); - } - - private TranslationContext<JCMemberReference> makeReferenceContext(JCMemberReference tree) { - return new ReferenceTranslationContext(tree); - } - private class Frame { final JCTree tree; List<Symbol> locals; @@ -1775,6 +1764,13 @@ */ final Set<Symbol> freeVarProcessedLocalClasses; + /** + * For method references converted to lambdas. The method + * reference receiver expression. Must be treated like a captured + * variable. + */ + JCExpression methodReferenceReceiver; + LambdaTranslationContext(JCLambda tree) { super(tree); Frame frame = frameStack.head; @@ -1794,9 +1790,6 @@ // This symbol will be filled-in in complete this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass()); - if (dumpLambdaToMethodStats) { - log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym); - } translatedSymbols = new EnumMap<>(LambdaSymbolKind.class); translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); @@ -1994,7 +1987,11 @@ // If instance access isn't needed, make it static. // Interface instance methods must be default methods. // Lambda methods are private synthetic. + // Inherit ACC_STRICT from the enclosing method, or, for clinit, + // from the class. translatedSym.flags_field = SYNTHETIC | LAMBDA_METHOD | + owner.flags_field & STRICTFP | + owner.owner.flags_field & STRICTFP | PRIVATE | (thisReferenced? (inInterface? DEFAULT : 0) : STATIC); @@ -2009,6 +2006,13 @@ for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) { params.append(make.VarDef((VarSymbol) thisSym, null)); } + if (methodReferenceReceiver != null) { + params.append(make.VarDef( + make.Modifiers(PARAMETER|FINAL), + names.fromString("$rcvr$"), + make.Type(methodReferenceReceiver.type), + null)); + } for (Symbol thisSym : getSymbolMap(PARAM).values()) { params.append(make.VarDef((VarSymbol) thisSym, null)); } @@ -2036,40 +2040,27 @@ * and the used by the main translation routines in order to adjust method * references (i.e. in case a bridge is needed) */ - private class ReferenceTranslationContext extends TranslationContext<JCMemberReference> { + private final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> { final boolean isSuper; - final Symbol bridgeSym; final Symbol sigPolySym; ReferenceTranslationContext(JCMemberReference tree) { super(tree); this.isSuper = tree.hasKind(ReferenceKind.SUPER); - this.bridgeSym = needsBridge() - ? makePrivateSyntheticMethod(isSuper ? 0 : STATIC, - referenceBridgeName(), null, - owner.enclClass()) - : null; this.sigPolySym = isSignaturePolymorphic() ? makePrivateSyntheticMethod(tree.sym.flags(), tree.sym.name, bridgedRefSig(), tree.sym.enclClass()) : null; - if (dumpLambdaToMethodStats) { - String key = bridgeSym == null ? - "mref.stat" : "mref.stat.1"; - log.note(tree, key, needsAltMetafactory(), bridgeSym); - } } /** * Get the opcode associated with this method reference */ int referenceKind() { - return LambdaToMethod.this.referenceKind(needsBridge() - ? bridgeSym - : tree.sym); + return LambdaToMethod.this.referenceKind(tree.sym); } boolean needsVarArgsConversion() { @@ -2077,62 +2068,6 @@ } /** - * Generate a disambiguating string to increase stability (important - * if serialized) - * - * @return String to differentiate synthetic lambda method names - */ - private String referenceBridgeDisambiguation() { - StringBuilder buf = new StringBuilder(); - // Append the enclosing method signature to differentiate - // overloaded enclosing methods. - if (owner.type != null) { - buf.append(typeSig(owner.type)); - buf.append(":"); - } - - // Append qualifier type - buf.append(classSig(tree.sym.owner.type)); - - // Note static/instance - buf.append(tree.sym.isStatic()? " S " : " I "); - - // Append referenced signature - buf.append(typeSig(tree.sym.erasure(types))); - - return buf.toString(); - } - - /** - * Construct a unique stable name for the method reference bridge - * - * @return Name to use for the synthetic method name - */ - private Name referenceBridgeName() { - StringBuilder buf = new StringBuilder(); - // Append lambda ID, this is semantically significant - buf.append(names.lambda); - // Note that it is a method reference bridge - buf.append("MR$"); - // Append the enclosing method name - buf.append(enclosingMethodName()); - buf.append('$'); - // Append the referenced method name - buf.append(syntheticMethodNameComponent(tree.sym.name)); - buf.append('$'); - // Append a hash of the disambiguating string : enclosing method - // signature, etc. - String disam = referenceBridgeDisambiguation(); - buf.append(Integer.toHexString(disam.hashCode())); - buf.append('$'); - // The above appended name components may not be unique, append - // a count based on the above name components. - buf.append(syntheticMethodNameCounts.getIndex(buf)); - String result = buf.toString(); - return names.fromString(result); - } - - /** * @return Is this an array operation like clone() */ boolean isArrayOp() { @@ -2167,13 +2102,40 @@ } /** - * Does this reference needs a bridge (i.e. var args need to be - * expanded or "super" is used) + * Erasure destroys the implementation parameter subtype + * relationship for intersection types */ - final boolean needsBridge() { - return isSuper || needsVarArgsConversion() || isArrayOp() || + boolean interfaceParameterIsIntersectionType() { + List<Type> tl = tree.getDescriptorType(types).getParameterTypes(); + if (tree.kind == ReferenceKind.UNBOUND) { + tl = tl.tail; + } + for (; tl.nonEmpty(); tl = tl.tail) { + Type pt = tl.head; + if (pt.getKind() == TypeKind.TYPEVAR) { + TypeVar tv = (TypeVar) pt; + if (tv.bound.getKind() == TypeKind.INTERSECTION) { + return true; + } + } + } + return false; + } + + /** + * Does this reference need to be converted to a lambda + * (i.e. var args need to be expanded or "super" is used) + */ + final boolean needsConversionToLambda() { + return interfaceParameterIsIntersectionType() || + isSuper || + needsVarArgsConversion() || + isArrayOp() || isPrivateInOtherClass() || - !receiverAccessible(); + !receiverAccessible() || + (tree.getMode() == ReferenceMode.NEW && + tree.kind != ReferenceKind.ARRAY_CTOR && + (tree.sym.owner.isLocal() || tree.sym.owner.isInner())); } Type generatedRefSig() {
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Mon Mar 02 12:13:35 2015 -0800 @@ -575,51 +575,46 @@ Env<AttrContext> localEnv = methodEnv(tree, env); - annotate.enterStart(); + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); try { - DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); - try { - // Compute the method type - m.type = signature(m, tree.typarams, tree.params, - tree.restype, tree.recvparam, - tree.thrown, - localEnv); - } finally { - deferredLintHandler.setPos(prevLintPos); - } + // Compute the method type + m.type = signature(m, tree.typarams, tree.params, + tree.restype, tree.recvparam, + tree.thrown, + localEnv); + } finally { + deferredLintHandler.setPos(prevLintPos); + } - if (types.isSignaturePolymorphic(m)) { - m.flags_field |= SIGNATURE_POLYMORPHIC; - } + if (types.isSignaturePolymorphic(m)) { + m.flags_field |= SIGNATURE_POLYMORPHIC; + } - // Set m.params - ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>(); - JCVariableDecl lastParam = null; - for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { - JCVariableDecl param = lastParam = l.head; - params.append(Assert.checkNonNull(param.sym)); - } - m.params = params.toList(); + // Set m.params + ListBuffer<VarSymbol> params = new ListBuffer<VarSymbol>(); + JCVariableDecl lastParam = null; + for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { + JCVariableDecl param = lastParam = l.head; + params.append(Assert.checkNonNull(param.sym)); + } + m.params = params.toList(); - // mark the method varargs, if necessary - if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0) - m.flags_field |= Flags.VARARGS; + // mark the method varargs, if necessary + if (lastParam != null && (lastParam.mods.flags & Flags.VARARGS) != 0) + m.flags_field |= Flags.VARARGS; - localEnv.info.scope.leave(); - if (chk.checkUnique(tree.pos(), m, enclScope)) { - enclScope.enter(m); - } + localEnv.info.scope.leave(); + if (chk.checkUnique(tree.pos(), m, enclScope)) { + enclScope.enter(m); + } - annotateLater(tree.mods.annotations, localEnv, m, tree.pos()); - // Visit the signature of the method. Note that - // TypeAnnotate doesn't descend into the body. - typeAnnotate(tree, localEnv, m, tree.pos()); + annotateLater(tree.mods.annotations, localEnv, m, tree.pos()); + // Visit the signature of the method. Note that + // TypeAnnotate doesn't descend into the body. + typeAnnotate(tree, localEnv, m, tree.pos()); - if (tree.defaultValue != null) - annotateDefaultValueLater(tree.defaultValue, localEnv, m); - } finally { - annotate.enterDone(); - } + if (tree.defaultValue != null) + annotateDefaultValueLater(tree.defaultValue, localEnv, m); } /** Create a fresh environment for method bodies. @@ -647,54 +642,49 @@ localEnv.info.staticLevel++; } DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); - annotate.enterStart(); try { - try { - if (TreeInfo.isEnumInit(tree)) { - attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); - } else { - attr.attribType(tree.vartype, localEnv); - if (TreeInfo.isReceiverParam(tree)) - checkReceiver(tree, localEnv); - } - } finally { - deferredLintHandler.setPos(prevLintPos); - } - - if ((tree.mods.flags & VARARGS) != 0) { - //if we are entering a varargs parameter, we need to - //replace its type (a plain array type) with the more - //precise VarargsType --- we need to do it this way - //because varargs is represented in the tree as a - //modifier on the parameter declaration, and not as a - //distinct type of array node. - ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType(); - tree.vartype.type = atype.makeVarargs(); + if (TreeInfo.isEnumInit(tree)) { + attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); + } else { + attr.attribType(tree.vartype, localEnv); + if (TreeInfo.isReceiverParam(tree)) + checkReceiver(tree, localEnv); } - Scope enclScope = enter.enterScope(env); - VarSymbol v = - new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner); - v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree); - tree.sym = v; - if (tree.init != null) { - v.flags_field |= HASINIT; - if ((v.flags_field & FINAL) != 0 && - needsLazyConstValue(tree.init)) { - Env<AttrContext> initEnv = getInitEnv(tree, env); - initEnv.info.enclVar = v; - v.setLazyConstValue(initEnv(tree, initEnv), attr, tree); - } + } finally { + deferredLintHandler.setPos(prevLintPos); + } + + if ((tree.mods.flags & VARARGS) != 0) { + //if we are entering a varargs parameter, we need to + //replace its type (a plain array type) with the more + //precise VarargsType --- we need to do it this way + //because varargs is represented in the tree as a + //modifier on the parameter declaration, and not as a + //distinct type of array node. + ArrayType atype = (ArrayType)tree.vartype.type.unannotatedType(); + tree.vartype.type = atype.makeVarargs(); + } + Scope enclScope = enter.enterScope(env); + VarSymbol v = + new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner); + v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree); + tree.sym = v; + if (tree.init != null) { + v.flags_field |= HASINIT; + if ((v.flags_field & FINAL) != 0 && + needsLazyConstValue(tree.init)) { + Env<AttrContext> initEnv = getInitEnv(tree, env); + initEnv.info.enclVar = v; + v.setLazyConstValue(initEnv(tree, initEnv), attr, tree); } - if (chk.checkUnique(tree.pos(), v, enclScope)) { - chk.checkTransparentVar(tree.pos(), v, enclScope); - enclScope.enter(v); - } - annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); - typeAnnotate(tree.vartype, env, v, tree.pos()); - v.pos = tree.pos; - } finally { - annotate.enterDone(); } + if (chk.checkUnique(tree.pos(), v, enclScope)) { + chk.checkTransparentVar(tree.pos(), v, enclScope); + enclScope.enter(v); + } + annotateLater(tree.mods.annotations, localEnv, v, tree.pos()); + typeAnnotate(tree.vartype, env, v, tree.pos()); + v.pos = tree.pos; } // where void checkType(JCTree tree, Type type, String diag) { @@ -1030,189 +1020,194 @@ JCClassDecl tree = (JCClassDecl)env.tree; boolean wasFirst = isFirst; isFirst = false; + try { + annotate.enterStart(); - JavaFileObject prev = log.useSource(env.toplevel.sourcefile); - DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); - try { - // Save class environment for later member enter (2) processing. - halfcompleted.append(env); + JavaFileObject prev = log.useSource(env.toplevel.sourcefile); + DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos()); + try { + // Save class environment for later member enter (2) processing. + halfcompleted.append(env); + + // Mark class as not yet attributed. + c.flags_field |= UNATTRIBUTED; - // Mark class as not yet attributed. - c.flags_field |= UNATTRIBUTED; + // If this is a toplevel-class, make sure any preceding import + // clauses have been seen. + if (c.owner.kind == PCK) { + memberEnter(env.toplevel, env.enclosing(TOPLEVEL)); + todo.append(env); + } + + if (c.owner.kind == TYP) + c.owner.complete(); + + // create an environment for evaluating the base clauses + Env<AttrContext> baseEnv = baseEnv(tree, env); + + if (tree.extending != null) + typeAnnotate(tree.extending, baseEnv, sym, tree.pos()); + for (JCExpression impl : tree.implementing) + typeAnnotate(impl, baseEnv, sym, tree.pos()); + annotate.flush(); - // If this is a toplevel-class, make sure any preceding import - // clauses have been seen. - if (c.owner.kind == PCK) { - memberEnter(env.toplevel, env.enclosing(TOPLEVEL)); - todo.append(env); - } + // Determine supertype. + Type supertype = + (tree.extending != null) + ? attr.attribBase(tree.extending, baseEnv, true, false, true) + : ((tree.mods.flags & Flags.ENUM) != 0) + ? attr.attribBase(enumBase(tree.pos, c), baseEnv, + true, false, false) + : (c.fullname == names.java_lang_Object) + ? Type.noType + : syms.objectType; + ct.supertype_field = modelMissingTypes(supertype, tree.extending, false); - if (c.owner.kind == TYP) - c.owner.complete(); - - // create an environment for evaluating the base clauses - Env<AttrContext> baseEnv = baseEnv(tree, env); + // Determine interfaces. + ListBuffer<Type> interfaces = new ListBuffer<Type>(); + ListBuffer<Type> all_interfaces = null; // lazy init + Set<Type> interfaceSet = new HashSet<Type>(); + List<JCExpression> interfaceTrees = tree.implementing; + for (JCExpression iface : interfaceTrees) { + Type i = attr.attribBase(iface, baseEnv, false, true, true); + if (i.hasTag(CLASS)) { + interfaces.append(i); + if (all_interfaces != null) all_interfaces.append(i); + chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet); + } else { + if (all_interfaces == null) + all_interfaces = new ListBuffer<Type>().appendList(interfaces); + all_interfaces.append(modelMissingTypes(i, iface, true)); + } + } + if ((c.flags_field & ANNOTATION) != 0) { + ct.interfaces_field = List.of(syms.annotationType); + ct.all_interfaces_field = ct.interfaces_field; + } else { + ct.interfaces_field = interfaces.toList(); + ct.all_interfaces_field = (all_interfaces == null) + ? ct.interfaces_field : all_interfaces.toList(); + } - if (tree.extending != null) - typeAnnotate(tree.extending, baseEnv, sym, tree.pos()); - for (JCExpression impl : tree.implementing) - typeAnnotate(impl, baseEnv, sym, tree.pos()); - annotate.flush(); + if (c.fullname == names.java_lang_Object) { + if (tree.extending != null) { + chk.checkNonCyclic(tree.extending.pos(), + supertype); + ct.supertype_field = Type.noType; + } + else if (tree.implementing.nonEmpty()) { + chk.checkNonCyclic(tree.implementing.head.pos(), + ct.interfaces_field.head); + ct.interfaces_field = List.nil(); + } + } - // Determine supertype. - Type supertype = - (tree.extending != null) - ? attr.attribBase(tree.extending, baseEnv, true, false, true) - : ((tree.mods.flags & Flags.ENUM) != 0) - ? attr.attribBase(enumBase(tree.pos, c), baseEnv, - true, false, false) - : (c.fullname == names.java_lang_Object) - ? Type.noType - : syms.objectType; - ct.supertype_field = modelMissingTypes(supertype, tree.extending, false); + // Annotations. + // In general, we cannot fully process annotations yet, but we + // can attribute the annotation types and then check to see if the + // @Deprecated annotation is present. + attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); + if (hasDeprecatedAnnotation(tree.mods.annotations)) + c.flags_field |= DEPRECATED; + annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); + // class type parameters use baseEnv but everything uses env + + chk.checkNonCyclicDecl(tree); + + attr.attribTypeVariables(tree.typarams, baseEnv); + // Do this here, where we have the symbol. + for (JCTypeParameter tp : tree.typarams) + typeAnnotate(tp, baseEnv, sym, tree.pos()); - // Determine interfaces. - ListBuffer<Type> interfaces = new ListBuffer<Type>(); - ListBuffer<Type> all_interfaces = null; // lazy init - Set<Type> interfaceSet = new HashSet<Type>(); - List<JCExpression> interfaceTrees = tree.implementing; - for (JCExpression iface : interfaceTrees) { - Type i = attr.attribBase(iface, baseEnv, false, true, true); - if (i.hasTag(CLASS)) { - interfaces.append(i); - if (all_interfaces != null) all_interfaces.append(i); - chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet); - } else { - if (all_interfaces == null) - all_interfaces = new ListBuffer<Type>().appendList(interfaces); - all_interfaces.append(modelMissingTypes(i, iface, true)); + // Add default constructor if needed. + if ((c.flags() & INTERFACE) == 0 && + !TreeInfo.hasConstructors(tree.defs)) { + List<Type> argtypes = List.nil(); + List<Type> typarams = List.nil(); + List<Type> thrown = List.nil(); + long ctorFlags = 0; + boolean based = false; + boolean addConstructor = true; + JCNewClass nc = null; + if (c.name.isEmpty()) { + nc = (JCNewClass)env.next.tree; + if (nc.constructor != null) { + addConstructor = nc.constructor.kind != ERR; + Type superConstrType = types.memberType(c.type, + nc.constructor); + argtypes = superConstrType.getParameterTypes(); + typarams = superConstrType.getTypeArguments(); + ctorFlags = nc.constructor.flags() & VARARGS; + if (nc.encl != null) { + argtypes = argtypes.prepend(nc.encl.type); + based = true; + } + thrown = superConstrType.getThrownTypes(); + } + } + if (addConstructor) { + MethodSymbol basedConstructor = nc != null ? + (MethodSymbol)nc.constructor : null; + JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, + basedConstructor, + typarams, argtypes, thrown, + ctorFlags, based); + tree.defs = tree.defs.prepend(constrDef); + } } - } - if ((c.flags_field & ANNOTATION) != 0) { - ct.interfaces_field = List.of(syms.annotationType); - ct.all_interfaces_field = ct.interfaces_field; - } else { - ct.interfaces_field = interfaces.toList(); - ct.all_interfaces_field = (all_interfaces == null) - ? ct.interfaces_field : all_interfaces.toList(); - } + + // enter symbols for 'this' into current scope. + VarSymbol thisSym = + new VarSymbol(FINAL | HASINIT, names._this, c.type, c); + thisSym.pos = Position.FIRSTPOS; + env.info.scope.enter(thisSym); + // if this is a class, enter symbol for 'super' into current scope. + if ((c.flags_field & INTERFACE) == 0 && + ct.supertype_field.hasTag(CLASS)) { + VarSymbol superSym = + new VarSymbol(FINAL | HASINIT, names._super, + ct.supertype_field, c); + superSym.pos = Position.FIRSTPOS; + env.info.scope.enter(superSym); + } - if (c.fullname == names.java_lang_Object) { - if (tree.extending != null) { - chk.checkNonCyclic(tree.extending.pos(), - supertype); - ct.supertype_field = Type.noType; + // check that no package exists with same fully qualified name, + // but admit classes in the unnamed package which have the same + // name as a top-level package. + if (checkClash && + c.owner.kind == PCK && c.owner != syms.unnamedPackage && + reader.packageExists(c.fullname)) { + log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c); } - else if (tree.implementing.nonEmpty()) { - chk.checkNonCyclic(tree.implementing.head.pos(), - ct.interfaces_field.head); - ct.interfaces_field = List.nil(); + if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && + !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) { + c.flags_field |= AUXILIARY; } + } catch (CompletionFailure ex) { + chk.completionError(tree.pos(), ex); + } finally { + deferredLintHandler.setPos(prevLintPos); + log.useSource(prev); } - // Annotations. - // In general, we cannot fully process annotations yet, but we - // can attribute the annotation types and then check to see if the - // @Deprecated annotation is present. - attr.attribAnnotationTypes(tree.mods.annotations, baseEnv); - if (hasDeprecatedAnnotation(tree.mods.annotations)) - c.flags_field |= DEPRECATED; - annotateLater(tree.mods.annotations, baseEnv, c, tree.pos()); - // class type parameters use baseEnv but everything uses env - - chk.checkNonCyclicDecl(tree); - - attr.attribTypeVariables(tree.typarams, baseEnv); - // Do this here, where we have the symbol. - for (JCTypeParameter tp : tree.typarams) - typeAnnotate(tp, baseEnv, sym, tree.pos()); - - // Add default constructor if needed. - if ((c.flags() & INTERFACE) == 0 && - !TreeInfo.hasConstructors(tree.defs)) { - List<Type> argtypes = List.nil(); - List<Type> typarams = List.nil(); - List<Type> thrown = List.nil(); - long ctorFlags = 0; - boolean based = false; - boolean addConstructor = true; - JCNewClass nc = null; - if (c.name.isEmpty()) { - nc = (JCNewClass)env.next.tree; - if (nc.constructor != null) { - addConstructor = nc.constructor.kind != ERR; - Type superConstrType = types.memberType(c.type, - nc.constructor); - argtypes = superConstrType.getParameterTypes(); - typarams = superConstrType.getTypeArguments(); - ctorFlags = nc.constructor.flags() & VARARGS; - if (nc.encl != null) { - argtypes = argtypes.prepend(nc.encl.type); - based = true; + // Enter all member fields and methods of a set of half completed + // classes in a second phase. + if (wasFirst) { + try { + while (halfcompleted.nonEmpty()) { + Env<AttrContext> toFinish = halfcompleted.next(); + finish(toFinish); + if (allowTypeAnnos) { + typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); + typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); } - thrown = superConstrType.getThrownTypes(); } - } - if (addConstructor) { - MethodSymbol basedConstructor = nc != null ? - (MethodSymbol)nc.constructor : null; - JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, - basedConstructor, - typarams, argtypes, thrown, - ctorFlags, based); - tree.defs = tree.defs.prepend(constrDef); + } finally { + isFirst = true; } } - - // enter symbols for 'this' into current scope. - VarSymbol thisSym = - new VarSymbol(FINAL | HASINIT, names._this, c.type, c); - thisSym.pos = Position.FIRSTPOS; - env.info.scope.enter(thisSym); - // if this is a class, enter symbol for 'super' into current scope. - if ((c.flags_field & INTERFACE) == 0 && - ct.supertype_field.hasTag(CLASS)) { - VarSymbol superSym = - new VarSymbol(FINAL | HASINIT, names._super, - ct.supertype_field, c); - superSym.pos = Position.FIRSTPOS; - env.info.scope.enter(superSym); - } - - // check that no package exists with same fully qualified name, - // but admit classes in the unnamed package which have the same - // name as a top-level package. - if (checkClash && - c.owner.kind == PCK && c.owner != syms.unnamedPackage && - reader.packageExists(c.fullname)) { - log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c); - } - if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && - !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) { - c.flags_field |= AUXILIARY; - } - } catch (CompletionFailure ex) { - chk.completionError(tree.pos(), ex); } finally { - deferredLintHandler.setPos(prevLintPos); - log.useSource(prev); - } - - // Enter all member fields and methods of a set of half completed - // classes in a second phase. - if (wasFirst) { - try { - while (halfcompleted.nonEmpty()) { - Env<AttrContext> toFinish = halfcompleted.next(); - finish(toFinish); - if (allowTypeAnnos) { - typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); - typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree); - } - } - } finally { - isFirst = true; - } + annotate.enterDone(); } }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Mar 02 12:13:35 2015 -0800 @@ -96,6 +96,7 @@ public final boolean varargsEnabled; public final boolean allowMethodHandles; public final boolean allowFunctionalInterfaceMostSpecific; + public final boolean checkVarargsAccessAfterResolution; private final boolean debugResolve; private final boolean compactMethodDiags; final EnumSet<VerboseResolutionMode> verboseResolutionMode; @@ -137,6 +138,8 @@ Target target = Target.instance(context); allowMethodHandles = target.hasMethodHandles(); allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific(); + checkVarargsAccessAfterResolution = + source.allowPostApplicabilityVarargsAccessCheck(); polymorphicSignatureScope = new Scope(syms.noSymbol); inapplicableMethodException = new InapplicableMethodException(diags); @@ -835,9 +838,15 @@ super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn); //should we expand formals? if (deferredAttrContext.phase.isVarargsRequired()) { - //check varargs element type accessibility - varargsAccessible(env, types.elemtype(formals.last()), - deferredAttrContext.inferenceContext); + Type typeToCheck = null; + if (!checkVarargsAccessAfterResolution) { + typeToCheck = types.elemtype(formals.last()); + } else if (deferredAttrContext.mode == AttrMode.CHECK) { + typeToCheck = types.erasure(types.elemtype(formals.last())); + } + if (typeToCheck != null) { + varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext); + } } } @@ -948,9 +957,10 @@ } public boolean compatible(Type found, Type req, Warner warn) { + InferenceContext inferenceContext = deferredAttrContext.inferenceContext; return strict ? - types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn) : - types.isConvertible(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn); + types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) : + types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn); } public void report(DiagnosticPosition pos, JCDiagnostic details) { @@ -3035,7 +3045,7 @@ /** * Should lookup stop at given phase with given result */ - protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { + final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { return phase.ordinal() > maxPhase.ordinal() || sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS; } @@ -3210,7 +3220,7 @@ super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); if (site.isRaw() && !argtypes.head.hasTag(NONE)) { Type asSuperSite = types.asSuper(argtypes.head, site.tsym); - this.site = asSuperSite; + this.site = types.capture(asSuperSite); } } @@ -4218,15 +4228,39 @@ VARARITY(true, true) { @Override public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { - switch (sym.kind) { - case WRONG_MTH: - return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ? - bestSoFar : - sym; - case ABSENT_MTH: - return bestSoFar; - default: - return sym; + //Check invariants (see {@code LookupHelper.shouldStop}) + Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS); + if (sym.kind < ERRONEOUS) { + //varargs resolution successful + return sym; + } else { + //pick best error + switch (bestSoFar.kind) { + case WRONG_MTH: + case WRONG_MTHS: + //Override previous errors if they were caused by argument mismatch. + //This generally means preferring current symbols - but we need to pay + //attention to the fact that the varargs lookup returns 'less' candidates + //than the previous rounds, and adjust that accordingly. + switch (sym.kind) { + case WRONG_MTH: + //if the previous round matched more than one method, return that + //result instead + return bestSoFar.kind == WRONG_MTHS ? + bestSoFar : sym; + case ABSENT_MTH: + //do not override erroneous symbol if the arity lookup did not + //match any method + return bestSoFar; + case WRONG_MTHS: + default: + //safe to override + return sym; + } + default: + //otherwise, return first error + return bestSoFar; + } } } };
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Mon Mar 02 12:13:35 2015 -0800 @@ -1953,12 +1953,12 @@ } } - public void closeRange(char end) { - if (isLastRangeInitialized()) { + public void closeRange(char length) { + if (isLastRangeInitialized() && length > 0) { Range range = lastRange(); if (range != null) { if (range.length == Character.MAX_VALUE) { - range.length = end; + range.length = length; } } } else { @@ -2017,13 +2017,12 @@ List<VarSymbol> locals = lvtRanges.getVars(meth, tree); for (LocalVar localVar: lvar) { for (VarSymbol aliveLocal : locals) { - if (localVar == null) { - return; - } - if (localVar.sym == aliveLocal && localVar.lastRange() != null) { - char length = (char)(closingCP - localVar.lastRange().start_pc); - if (length > 0 && length < Character.MAX_VALUE) { - localVar.closeRange(length); + if (localVar != null) { + if (localVar.sym == aliveLocal && localVar.lastRange() != null) { + char length = (char)(closingCP - localVar.lastRange().start_pc); + if (length < Character.MAX_VALUE) { + localVar.closeRange(length); + } } } } @@ -2032,12 +2031,11 @@ void adjustAliveRanges(int oldCP, int delta) { for (LocalVar localVar: lvar) { - if (localVar == null) { - return; - } - for (LocalVar.Range range: localVar.aliveRanges) { - if (range.closed() && range.start_pc + range.length >= oldCP) { - range.length += delta; + if (localVar != null) { + for (LocalVar.Range range: localVar.aliveRanges) { + if (range.closed() && range.start_pc + range.length >= oldCP) { + range.length += delta; + } } } } @@ -2093,7 +2091,7 @@ lvar[adr].isLastRangeInitialized()) { LocalVar v = lvar[adr]; char length = (char)(curCP() - v.lastRange().start_pc); - if (length > 0 && length < Character.MAX_VALUE) { + if (length < Character.MAX_VALUE) { lvar[adr] = v.dup(); v.closeRange(length); putVar(v);
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Mar 02 12:13:35 2015 -0800 @@ -74,6 +74,7 @@ private Name accessDollar; private final Types types; private final Lower lower; + private final Flow flow; /** Switch: GJ mode? */ @@ -125,6 +126,7 @@ stringBufferAppend = new HashMap<Type,Symbol>(); accessDollar = names. fromString("access" + target.syntheticNameChar()); + flow = Flow.instance(context); lower = Lower.instance(context); Options options = Options.instance(context); @@ -2516,9 +2518,7 @@ */ if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) { try { - LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make( - lvtRanges, syms, names); - lvtAssignAnalyzer.analyzeTree(localEnv); + new LVTAssignAnalyzer().analyzeTree(localEnv); } catch (Throwable e) { throw e; } @@ -2609,11 +2609,10 @@ } } - static class LVTAssignAnalyzer + class LVTAssignAnalyzer extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> { final LVTBits lvtInits; - final LVTRanges lvtRanges; /* This class is anchored to a context dependent tree. The tree can * vary inside the same instruction for example in the switch instruction @@ -2621,35 +2620,12 @@ * to a given case. The aim is to always anchor the bits to the tree * capable of closing a DA range. */ - static class LVTBits extends Bits { - - enum BitsOpKind { - INIT, - CLEAR, - INCL_BIT, - EXCL_BIT, - ASSIGN, - AND_SET, - OR_SET, - DIFF_SET, - XOR_SET, - INCL_RANGE, - EXCL_RANGE, - } + class LVTBits extends Bits { JCTree currentTree; - LVTAssignAnalyzer analyzer; private int[] oldBits = null; BitsState stateBeforeOp; - LVTBits() { - super(false); - } - - LVTBits(int[] bits, BitsState initState) { - super(bits, initState); - } - @Override public void clear() { generalOp(null, -1, BitsOpKind.CLEAR); @@ -2757,12 +2733,11 @@ if (currentTree != null && stateBeforeOp != BitsState.UNKNOWN && trackTree(currentTree)) { - List<VarSymbol> locals = - analyzer.lvtRanges - .getVars(analyzer.currentMethod, currentTree); + List<VarSymbol> locals = lvtRanges + .getVars(currentMethod, currentTree); locals = locals != null ? locals : List.<VarSymbol>nil(); - for (JCVariableDecl vardecl : analyzer.vardecls) { + for (JCVariableDecl vardecl : vardecls) { //once the first is null, the rest will be so. if (vardecl == null) { break; @@ -2772,7 +2747,7 @@ } } if (!locals.isEmpty()) { - analyzer.lvtRanges.setEntry(analyzer.currentMethod, + lvtRanges.setEntry(currentMethod, currentTree, locals); } } @@ -2789,8 +2764,8 @@ boolean trackVar(VarSymbol var) { return (var.owner.kind == MTH && - (var.flags() & (PARAMETER | HASINIT)) == 0 && - analyzer.trackable(var)); + (var.flags() & PARAMETER) == 0 && + trackable(var)); } boolean trackTree(JCTree tree) { @@ -2806,7 +2781,8 @@ } - public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit { + public class LVTAssignPendingExit extends + Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit { LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { super(tree, inits, uninits); @@ -2819,16 +2795,10 @@ } } - private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { - super(new LVTBits(), syms, names, false); - lvtInits = (LVTBits)inits; - this.lvtRanges = lvtRanges; - } - - public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) { - LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names); - result.lvtInits.analyzer = result; - return result; + private LVTAssignAnalyzer() { + flow.super(); + lvtInits = new LVTBits(); + inits = lvtInits; } @Override
--- a/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Mon Mar 02 12:13:35 2015 -0800 @@ -1039,7 +1039,7 @@ } /** - * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a> + * @see <a href="https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a> */ private void initTagParsers() { TagParser[] parsers = {
--- a/src/share/classes/com/sun/tools/javac/util/Bits.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/util/Bits.java Mon Mar 02 12:13:35 2015 -0800 @@ -84,6 +84,20 @@ } + public enum BitsOpKind { + INIT, + CLEAR, + INCL_BIT, + EXCL_BIT, + ASSIGN, + AND_SET, + OR_SET, + DIFF_SET, + XOR_SET, + INCL_RANGE, + EXCL_RANGE, + } + private final static int wordlen = 32; private final static int wordshift = 5; private final static int wordmask = wordlen - 1;
--- a/src/share/classes/com/sun/tools/javac/util/Convert.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/javac/util/Convert.java Mon Mar 02 12:13:35 2015 -0800 @@ -36,9 +36,9 @@ * <p> * See also: * <ul> - * <li><a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7"> + * <li><a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4.7"> * JVMS 4.4.7 </a></li> - * <li><a href="http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8"> + * <li><a href="https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8"> java.io.DataInput: Modified UTF-8 </a></li> <li><a href="https://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8"> Modified UTF-8 (wikipedia) </a></li>
--- a/src/share/classes/com/sun/tools/jdeps/Analyzer.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/Analyzer.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,10 +24,8 @@ */ package com.sun.tools.jdeps; -import com.sun.tools.classfile.Dependency.Location; -import com.sun.tools.jdeps.PlatformClassPath.JDKArchive; -import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -37,6 +35,9 @@ import java.util.TreeMap; import java.util.TreeSet; +import com.sun.tools.classfile.Dependency.Location; +import com.sun.tools.jdeps.PlatformClassPath.JDKArchive; + /** * Dependency Analyzer. */ @@ -52,7 +53,16 @@ VERBOSE }; + /** + * Filter to be applied when analyzing the dependencies from the given archives. + * Only the accepted dependencies are recorded. + */ + interface Filter { + boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive); + } + private final Type type; + private final Filter filter; private final Map<Archive, ArchiveDeps> results = new HashMap<>(); private final Map<Location, Archive> map = new HashMap<>(); private final Archive NOT_FOUND @@ -62,9 +72,11 @@ * Constructs an Analyzer instance. * * @param type Type of the dependency analysis + * @param filter */ - public Analyzer(Type type) { + public Analyzer(Type type, Filter filter) { this.type = type; + this.filter = filter; } /** @@ -72,6 +84,18 @@ */ public void run(List<Archive> archives) { // build a map from Location to Archive + buildLocationArchiveMap(archives); + + // traverse and analyze all dependencies + for (Archive archive : archives) { + ArchiveDeps deps = new ArchiveDeps(archive, type); + archive.visitDependences(deps); + results.put(archive, deps); + } + } + + private void buildLocationArchiveMap(List<Archive> archives) { + // build a map from Location to Archive for (Archive archive: archives) { for (Location l: archive.getClasses()) { if (!map.containsKey(l)) { @@ -81,190 +105,236 @@ } } } - // traverse and analyze all dependencies - for (Archive archive : archives) { - ArchiveDeps deps; - if (type == Type.CLASS || type == Type.VERBOSE) { - deps = new ClassVisitor(archive); - } else { - deps = new PackageVisitor(archive); - } - archive.visitDependences(deps); - results.put(archive, deps); - } } public boolean hasDependences(Archive archive) { if (results.containsKey(archive)) { - return results.get(archive).deps.size() > 0; + return results.get(archive).dependencies().size() > 0; } return false; } + public Set<String> dependences(Archive source) { + ArchiveDeps result = results.get(source); + return result.targetDependences(); + } + public interface Visitor { /** - * Visits the source archive to its destination archive of - * a recorded dependency. - */ - void visitArchiveDependence(Archive origin, Archive target, Profile profile); - /** * Visits a recorded dependency from origin to target which can be - * a fully-qualified classname, a package name, a profile or + * a fully-qualified classname, a package name, a module or * archive name depending on the Analyzer's type. */ - void visitDependence(String origin, Archive source, String target, Archive archive, Profile profile); + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive); } - public void visitArchiveDependences(Archive source, Visitor v) { - ArchiveDeps r = results.get(source); - for (ArchiveDeps.Dep d: r.requireArchives()) { - v.visitArchiveDependence(r.archive, d.archive, d.profile); - } - } - - public void visitDependences(Archive source, Visitor v) { - ArchiveDeps r = results.get(source); - for (Map.Entry<String, SortedSet<ArchiveDeps.Dep>> e: r.deps.entrySet()) { - String origin = e.getKey(); - for (ArchiveDeps.Dep d: e.getValue()) { - // filter intra-dependency unless in verbose mode - if (type == Type.VERBOSE || d.archive != source) { - v.visitDependence(origin, source, d.target, d.archive, d.profile); - } + /** + * Visit the dependencies of the given source. + * If the requested level is SUMMARY, it will visit the required archives list. + */ + public void visitDependences(Archive source, Visitor v, Type level) { + if (level == Type.SUMMARY) { + final ArchiveDeps result = results.get(source); + SortedMap<String, Archive> sorted = new TreeMap<>(); + for (Archive a : result.requires()) { + sorted.put(a.getName(), a); + } + for (Archive archive : sorted.values()) { + Profile profile = result.getTargetProfile(archive); + v.visitDependence(source.getName(), source, + profile != null ? profile.profileName() : archive.getName(), archive); + } + } else { + ArchiveDeps result = results.get(source); + if (level != type) { + // requesting different level of analysis + result = new ArchiveDeps(source, level); + source.visitDependences(result); + } + SortedSet<Dep> sorted = new TreeSet<>(result.dependencies()); + for (Dep d : sorted) { + v.visitDependence(d.origin(), d.originArchive(), d.target(), d.targetArchive()); } } } + public void visitDependences(Archive source, Visitor v) { + visitDependences(source, v, type); + } + /** - * ArchiveDeps contains the dependencies for an Archive that - * can have one or more classes. + * ArchiveDeps contains the dependencies for an Archive that can have one or + * more classes. */ - private abstract class ArchiveDeps implements Archive.Visitor { - final Archive archive; - final SortedMap<String, SortedSet<Dep>> deps; - ArchiveDeps(Archive archive) { + class ArchiveDeps implements Archive.Visitor { + protected final Archive archive; + protected final Set<Archive> requires; + protected final Set<Dep> deps; + protected final Type level; + private Profile profile; + ArchiveDeps(Archive archive, Type level) { this.archive = archive; - this.deps = new TreeMap<>(); - } - - void add(String origin, String target, Archive targetArchive, String pkgName) { - SortedSet<Dep> set = deps.get(origin); - if (set == null) { - deps.put(origin, set = new TreeSet<>()); - } - Profile p = targetArchive instanceof JDKArchive - ? Profile.getProfile(pkgName) : null; - set.add(new Dep(target, targetArchive, p)); + this.deps = new HashSet<>(); + this.requires = new HashSet<>(); + this.level = level; } - /** - * Returns the list of Archive dependences. The returned - * list contains one {@code Dep} instance per one archive - * and with the minimum profile this archive depends on. - */ - List<Dep> requireArchives() { - Map<Archive,Profile> map = new HashMap<>(); - for (Set<Dep> set: deps.values()) { - for (Dep d: set) { - if (this.archive != d.archive) { - Profile p = map.get(d.archive); - if (p == null || (d.profile != null && p.profile < d.profile.profile)) { - map.put(d.archive, d.profile); - } - } - } + Set<Dep> dependencies() { + return deps; + } + + Set<String> targetDependences() { + Set<String> targets = new HashSet<>(); + for (Dep d : deps) { + targets.add(d.target()); } - List<Dep> list = new ArrayList<>(); - for (Map.Entry<Archive,Profile> e: map.entrySet()) { - list.add(new Dep("", e.getKey(), e.getValue())); + return targets; + } + + Set<Archive> requires() { + return requires; + } + + Profile getTargetProfile(Archive target) { + return JDKArchive.isProfileArchive(target) ? profile : null; + } + + Archive findArchive(Location t) { + Archive target = archive.getClasses().contains(t) ? archive : map.get(t); + if (target == null) { + map.put(t, target = NOT_FOUND); } - return list; + return target; } - /** - * Dep represents a dependence where the target can be - * a classname or packagename and the archive and profile - * the target belongs to. - */ - class Dep implements Comparable<Dep> { - final String target; - final Archive archive; - final Profile profile; - Dep(String target, Archive archive, Profile p) { - this.target = target; - this.archive = archive; - this.profile = p; + // return classname or package name depedning on the level + private String getLocationName(Location o) { + if (level == Type.CLASS || level == Type.VERBOSE) { + return o.getClassName(); + } else { + String pkg = o.getPackageName(); + return pkg.isEmpty() ? "<unnamed>" : pkg; + } + } + + @Override + public void visit(Location o, Location t) { + Archive targetArchive = findArchive(t); + if (filter.accepts(o, archive, t, targetArchive)) { + addDep(o, t); + if (!requires.contains(targetArchive)) { + requires.add(targetArchive); + } } + if (targetArchive instanceof JDKArchive) { + Profile p = Profile.getProfile(t.getPackageName()); + if (profile == null || (p != null && p.compareTo(profile) > 0)) { + profile = p; + } + } + } - @Override - public boolean equals(Object o) { - if (o instanceof Dep) { - Dep d = (Dep)o; - return this.archive == d.archive && this.target.equals(d.target); - } - return false; + private Dep curDep; + protected Dep addDep(Location o, Location t) { + String origin = getLocationName(o); + String target = getLocationName(t); + Archive targetArchive = findArchive(t); + if (curDep != null && + curDep.origin().equals(origin) && + curDep.originArchive() == archive && + curDep.target().equals(target) && + curDep.targetArchive() == targetArchive) { + return curDep; } - @Override - public int hashCode() { - int hash = 3; - hash = 17 * hash + Objects.hashCode(this.archive); - hash = 17 * hash + Objects.hashCode(this.target); - return hash; - } - - @Override - public int compareTo(Dep o) { - if (this.target.equals(o.target)) { - if (this.archive == o.archive) { - return 0; - } else { - return this.archive.getFileName().compareTo(o.archive.getFileName()); + Dep e = new Dep(origin, archive, target, targetArchive); + if (deps.contains(e)) { + for (Dep e1 : deps) { + if (e.equals(e1)) { + curDep = e1; } } - return this.target.compareTo(o.target); + } else { + deps.add(e); + curDep = e; } - } - public abstract void visit(Location o, Location t); - } - - private class ClassVisitor extends ArchiveDeps { - ClassVisitor(Archive archive) { - super(archive); - } - @Override - public void visit(Location o, Location t) { - Archive targetArchive = - this.archive.getClasses().contains(t) ? this.archive : map.get(t); - if (targetArchive == null) { - map.put(t, targetArchive = NOT_FOUND); - } - - String origin = o.getClassName(); - String target = t.getClassName(); - add(origin, target, targetArchive, t.getPackageName()); + return curDep; } } - private class PackageVisitor extends ArchiveDeps { - PackageVisitor(Archive archive) { - super(archive); + /* + * Class-level or package-level dependency + */ + class Dep implements Comparable<Dep> { + final String origin; + final Archive originArchive; + final String target; + final Archive targetArchive; + + Dep(String origin, Archive originArchive, String target, Archive targetArchive) { + this.origin = origin; + this.originArchive = originArchive; + this.target = target; + this.targetArchive = targetArchive; } + + String origin() { + return origin; + } + + Archive originArchive() { + return originArchive; + } + + String target() { + return target; + } + + Archive targetArchive() { + return targetArchive; + } + @Override - public void visit(Location o, Location t) { - Archive targetArchive = - this.archive.getClasses().contains(t) ? this.archive : map.get(t); - if (targetArchive == null) { - map.put(t, targetArchive = NOT_FOUND); + @SuppressWarnings("unchecked") + public boolean equals(Object o) { + if (o instanceof Dep) { + Dep d = (Dep) o; + return this.origin.equals(d.origin) && + this.originArchive == d.originArchive && + this.target.equals(d.target) && + this.targetArchive == d.targetArchive; } + return false; + } - String origin = packageOf(o); - String target = packageOf(t); - add(origin, target, targetArchive, t.getPackageName()); + @Override + public int hashCode() { + int hash = 7; + hash = 67*hash + Objects.hashCode(this.origin) + + Objects.hashCode(this.originArchive) + + Objects.hashCode(this.target) + + Objects.hashCode(this.targetArchive); + return hash; } - public String packageOf(Location o) { - String pkg = o.getPackageName(); - return pkg.isEmpty() ? "<unnamed>" : pkg; + + @Override + public int compareTo(Dep o) { + if (this.origin.equals(o.origin)) { + if (this.target.equals(o.target)) { + if (this.originArchive == o.originArchive && + this.targetArchive == o.targetArchive) { + return 0; + } else if (this.originArchive == o.originArchive) { + return this.targetArchive.getPathName().compareTo(o.targetArchive.getPathName()); + } else { + return this.originArchive.getPathName().compareTo(o.originArchive.getPathName()); + } + } else { + return this.target.compareTo(o.target); + } + } + return this.origin.compareTo(o.origin); } } }
--- a/src/share/classes/com/sun/tools/jdeps/Archive.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/Archive.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,28 +25,34 @@ package com.sun.tools.jdeps; import com.sun.tools.classfile.Dependency.Location; + +import java.io.IOException; import java.nio.file.Path; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; /** * Represents the source of the class files. */ public class Archive { + public static Archive getInstance(Path p) throws IOException { + return new Archive(p, ClassFileReader.newInstance(p)); + } + private final Path path; private final String filename; private final ClassFileReader reader; - private final Map<Location, Set<Location>> deps = new HashMap<>(); + protected Map<Location, Set<Location>> deps = new ConcurrentHashMap<>(); - public Archive(String name) { + protected Archive(String name) { this.path = null; this.filename = name; this.reader = null; } - public Archive(Path p, ClassFileReader reader) { + protected Archive(Path p, ClassFileReader reader) { this.path = p; this.filename = path.getFileName().toString(); this.reader = reader; @@ -56,7 +62,7 @@ return reader; } - public String getFileName() { + public String getName() { return filename; } @@ -89,6 +95,10 @@ } } + public boolean isEmpty() { + return getClasses().isEmpty(); + } + public String getPathName() { return path != null ? path.toString() : filename; }
--- a/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,8 @@ protected final Path path; protected final String baseFileName; - private ClassFileReader(Path path) { + protected final List<String> skippedEntries = new ArrayList<>(); + protected ClassFileReader(Path path) { this.path = path; this.baseFileName = path.getFileName() != null ? path.getFileName().toString() @@ -79,6 +80,10 @@ return baseFileName; } + public List<String> skippedEntries() { + return skippedEntries; + } + /** * Returns the ClassFile matching the given binary name * or a fully-qualified class name. @@ -232,11 +237,12 @@ } } - private static class JarFileReader extends ClassFileReader { - final JarFile jarfile; + static class JarFileReader extends ClassFileReader { + private final JarFile jarfile; JarFileReader(Path path) throws IOException { - this(path, new JarFile(path.toFile())); + this(path, new JarFile(path.toFile(), false)); } + JarFileReader(Path path, JarFile jf) throws IOException { super(path); this.jarfile = jf; @@ -252,18 +258,18 @@ + entryName.substring(i + 1, entryName.length())); } if (e != null) { - return readClassFile(e); + return readClassFile(jarfile, e); } } else { JarEntry e = jarfile.getJarEntry(name + ".class"); if (e != null) { - return readClassFile(e); + return readClassFile(jarfile, e); } } return null; } - private ClassFile readClassFile(JarEntry e) throws IOException { + protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException { InputStream is = null; try { is = jarfile.getInputStream(e); @@ -277,60 +283,76 @@ } public Iterable<ClassFile> getClassFiles() throws IOException { - final Iterator<ClassFile> iter = new JarFileIterator(); + final Iterator<ClassFile> iter = new JarFileIterator(this, jarfile); return new Iterable<ClassFile>() { public Iterator<ClassFile> iterator() { return iter; } }; } + } - class JarFileIterator implements Iterator<ClassFile> { - private Enumeration<JarEntry> entries; - private JarEntry nextEntry; - JarFileIterator() { - this.entries = jarfile.entries(); - while (entries.hasMoreElements()) { - JarEntry e = entries.nextElement(); - String name = e.getName(); - if (name.endsWith(".class")) { - this.nextEntry = e; - break; - } + class JarFileIterator implements Iterator<ClassFile> { + protected final JarFileReader reader; + protected Enumeration<JarEntry> entries; + protected JarFile jf; + protected JarEntry nextEntry; + protected ClassFile cf; + JarFileIterator(JarFileReader reader) { + this(reader, null); + } + JarFileIterator(JarFileReader reader, JarFile jarfile) { + this.reader = reader; + setJarFile(jarfile); + } + + void setJarFile(JarFile jarfile) { + if (jarfile == null) return; + + this.jf = jarfile; + this.entries = jf.entries(); + this.nextEntry = nextEntry(); + } + + public boolean hasNext() { + if (nextEntry != null && cf != null) { + return true; + } + while (nextEntry != null) { + try { + cf = reader.readClassFile(jf, nextEntry); + return true; + } catch (ClassFileError | IOException ex) { + skippedEntries.add(nextEntry.getName()); + } + nextEntry = nextEntry(); + } + return false; + } + + public ClassFile next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + ClassFile classFile = cf; + cf = null; + nextEntry = nextEntry(); + return classFile; + } + + protected JarEntry nextEntry() { + while (entries.hasMoreElements()) { + JarEntry e = entries.nextElement(); + String name = e.getName(); + if (name.endsWith(".class")) { + return e; } } - - public boolean hasNext() { - return nextEntry != null; - } - - public ClassFile next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } + return null; + } - ClassFile cf; - try { - cf = readClassFile(nextEntry); - } catch (IOException ex) { - throw new ClassFileError(ex); - } - JarEntry entry = nextEntry; - nextEntry = null; - while (entries.hasMoreElements()) { - JarEntry e = entries.nextElement(); - String name = e.getName(); - if (name.endsWith(".class")) { - nextEntry = e; - break; - } - } - return cf; - } - - public void remove() { - throw new UnsupportedOperationException("Not supported yet."); - } + public void remove() { + throw new UnsupportedOperationException("Not supported yet."); } } }
--- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,9 @@ import com.sun.tools.classfile.Dependencies; import com.sun.tools.classfile.Dependencies.ClassFileError; import com.sun.tools.classfile.Dependency; +import com.sun.tools.classfile.Dependency.Location; import com.sun.tools.jdeps.PlatformClassPath.JDKArchive; +import static com.sun.tools.jdeps.Analyzer.Type.*; import java.io.*; import java.nio.file.DirectoryStream; import java.nio.file.Files; @@ -110,7 +112,7 @@ void process(JdepsTask task, String opt, String arg) throws BadArgs { Path p = Paths.get(arg); if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) { - throw new BadArgs("err.dot.output.path", arg); + throw new BadArgs("err.invalid.path", arg); } task.options.dotOutputDir = arg; } @@ -118,25 +120,26 @@ new Option(false, "-s", "-summary") { void process(JdepsTask task, String opt, String arg) { task.options.showSummary = true; - task.options.verbose = Analyzer.Type.SUMMARY; + task.options.verbose = SUMMARY; } }, new Option(false, "-v", "-verbose", "-verbose:package", - "-verbose:class") - { + "-verbose:class") { void process(JdepsTask task, String opt, String arg) throws BadArgs { switch (opt) { case "-v": case "-verbose": - task.options.verbose = Analyzer.Type.VERBOSE; + task.options.verbose = VERBOSE; + task.options.filterSameArchive = false; + task.options.filterSamePackage = false; break; case "-verbose:package": - task.options.verbose = Analyzer.Type.PACKAGE; - break; + task.options.verbose = PACKAGE; + break; case "-verbose:class": - task.options.verbose = Analyzer.Type.CLASS; - break; + task.options.verbose = CLASS; + break; default: throw new BadArgs("err.invalid.arg.for.option", opt); } @@ -157,6 +160,32 @@ task.options.regex = arg; } }, + + new Option(true, "-f", "-filter") { + void process(JdepsTask task, String opt, String arg) { + task.options.filterRegex = arg; + } + }, + new Option(false, "-filter:package", + "-filter:archive", + "-filter:none") { + void process(JdepsTask task, String opt, String arg) { + switch (opt) { + case "-filter:package": + task.options.filterSamePackage = true; + task.options.filterSameArchive = false; + break; + case "-filter:archive": + task.options.filterSameArchive = true; + task.options.filterSamePackage = false; + break; + case "-filter:none": + task.options.filterSameArchive = false; + task.options.filterSamePackage = false; + break; + } + } + }, new Option(true, "-include") { void process(JdepsTask task, String opt, String arg) throws BadArgs { task.options.includePattern = Pattern.compile(arg); @@ -178,12 +207,15 @@ new Option(false, "-R", "-recursive") { void process(JdepsTask task, String opt, String arg) { task.options.depth = 0; + // turn off filtering + task.options.filterSameArchive = false; + task.options.filterSamePackage = false; } }, new Option(false, "-jdkinternals") { void process(JdepsTask task, String opt, String arg) { task.options.findJDKInternals = true; - task.options.verbose = Analyzer.Type.CLASS; + task.options.verbose = CLASS; if (task.options.includePattern == null) { task.options.includePattern = Pattern.compile(".*"); } @@ -204,6 +236,11 @@ task.options.showLabel = true; } }, + new HiddenOption(false, "-q", "-quiet") { + void process(JdepsTask task, String opt, String arg) { + task.options.nowarning = true; + } + }, new HiddenOption(true, "-depth") { void process(JdepsTask task, String opt, String arg) throws BadArgs { try { @@ -217,7 +254,7 @@ private static final String PROGNAME = "jdeps"; private final Options options = new Options(); - private final List<String> classes = new ArrayList<String>(); + private final List<String> classes = new ArrayList<>(); private PrintWriter log; void setLog(PrintWriter out) { @@ -262,7 +299,7 @@ showHelp(); return EXIT_CMDERR; } - if (options.showSummary && options.verbose != Analyzer.Type.SUMMARY) { + if (options.showSummary && options.verbose != SUMMARY) { showHelp(); return EXIT_CMDERR; } @@ -283,9 +320,30 @@ private final List<Archive> sourceLocations = new ArrayList<>(); private boolean run() throws IOException { + // parse classfiles and find all dependencies findDependencies(); - Analyzer analyzer = new Analyzer(options.verbose); + + Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() { + @Override + public boolean accepts(Location origin, Archive originArchive, + Location target, Archive targetArchive) + { + if (options.findJDKInternals) { + // accepts target that is JDK class but not exported + return isJDKArchive(targetArchive) && + !((JDKArchive) targetArchive).isExported(target.getClassName()); + } else if (options.filterSameArchive) { + // accepts origin and target that from different archive + return originArchive != targetArchive; + } + return true; + } + }); + + // analyze the dependencies analyzer.run(sourceLocations); + + // output result if (options.dotOutputDir != null) { Path dir = Paths.get(options.dotOutputDir); Files.createDirectories(dir); @@ -293,30 +351,41 @@ } else { printRawOutput(log, analyzer); } + + if (options.findJDKInternals && !options.nowarning) { + showReplacements(analyzer); + } return true; } + private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException { + // If verbose mode (-v or -verbose option), + // the summary.dot file shows package-level dependencies. + Analyzer.Type summaryType = + (options.verbose == PACKAGE || options.verbose == SUMMARY) ? SUMMARY : PACKAGE; + Path summary = dir.resolve("summary.dot"); + try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary)); + SummaryDotFile dotfile = new SummaryDotFile(sw, summaryType)) { + for (Archive archive : sourceLocations) { + if (!archive.isEmpty()) { + if (options.verbose == PACKAGE || options.verbose == SUMMARY) { + if (options.showLabel) { + // build labels listing package-level dependencies + analyzer.visitDependences(archive, dotfile.labelBuilder(), PACKAGE); + } + } + analyzer.visitDependences(archive, dotfile, summaryType); + } + } + } + } + private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException { - Path summary = dir.resolve("summary.dot"); - boolean verbose = options.verbose == Analyzer.Type.VERBOSE; - DotGraph<?> graph = verbose ? new DotSummaryForPackage() - : new DotSummaryForArchive(); - for (Archive archive : sourceLocations) { - analyzer.visitArchiveDependences(archive, graph); - if (verbose || options.showLabel) { - // traverse detailed dependences to generate package-level - // summary or build labels for edges - analyzer.visitDependences(archive, graph); - } - } - try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary))) { - graph.writeTo(sw); - } // output individual .dot file for each archive - if (options.verbose != Analyzer.Type.SUMMARY) { + if (options.verbose != SUMMARY) { for (Archive archive : sourceLocations) { if (analyzer.hasDependences(archive)) { - Path dotfile = dir.resolve(archive.getFileName() + ".dot"); + Path dotfile = dir.resolve(archive.getName() + ".dot"); try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile)); DotFileFormatter formatter = new DotFileFormatter(pw, archive)) { analyzer.visitDependences(archive, formatter); @@ -324,17 +393,23 @@ } } } + // generate summary dot file + generateSummaryDotFile(dir, analyzer); } private void printRawOutput(PrintWriter writer, Analyzer analyzer) { + RawOutputFormatter depFormatter = new RawOutputFormatter(writer); + RawSummaryFormatter summaryFormatter = new RawSummaryFormatter(writer); for (Archive archive : sourceLocations) { - RawOutputFormatter formatter = new RawOutputFormatter(writer); - analyzer.visitArchiveDependences(archive, formatter); - if (options.verbose != Analyzer.Type.SUMMARY) { - analyzer.visitDependences(archive, formatter); + if (!archive.isEmpty()) { + analyzer.visitDependences(archive, summaryFormatter, SUMMARY); + if (analyzer.hasDependences(archive) && options.verbose != SUMMARY) { + analyzer.visitDependences(archive, depFormatter); + } } } } + private boolean isValidClassName(String name) { if (!Character.isJavaIdentifierStart(name.charAt(0))) { return false; @@ -348,21 +423,54 @@ return true; } - private Dependency.Filter getDependencyFilter() { - if (options.regex != null) { - return Dependencies.getRegexFilter(Pattern.compile(options.regex)); - } else if (options.packageNames.size() > 0) { - return Dependencies.getPackageFilter(options.packageNames, false); - } else { - return new Dependency.Filter() { - @Override - public boolean accepts(Dependency dependency) { - return !dependency.getOrigin().equals(dependency.getTarget()); - } - }; + /* + * Dep Filter configured based on the input jdeps option + * 1. -p and -regex to match target dependencies + * 2. -filter:package to filter out same-package dependencies + * + * This filter is applied when jdeps parses the class files + * and filtered dependencies are not stored in the Analyzer. + * + * -filter:archive is applied later in the Analyzer as the + * containing archive of a target class may not be known until + * the entire archive + */ + class DependencyFilter implements Dependency.Filter { + final Dependency.Filter filter; + final Pattern filterPattern; + DependencyFilter() { + if (options.regex != null) { + this.filter = Dependencies.getRegexFilter(Pattern.compile(options.regex)); + } else if (options.packageNames.size() > 0) { + this.filter = Dependencies.getPackageFilter(options.packageNames, false); + } else { + this.filter = null; + } + + this.filterPattern = + options.filterRegex != null ? Pattern.compile(options.filterRegex) : null; + } + @Override + public boolean accepts(Dependency d) { + if (d.getOrigin().equals(d.getTarget())) { + return false; + } + String pn = d.getTarget().getPackageName(); + if (options.filterSamePackage && d.getOrigin().getPackageName().equals(pn)) { + return false; + } + + if (filterPattern != null && filterPattern.matcher(pn).matches()) { + return false; + } + return filter != null ? filter.accepts(d) : true; } } + /** + * Tests if the given class matches the pattern given in the -include option + * or if it's a public class if -apionly option is specified + */ private boolean matches(String classname, AccessFlags flags) { if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) { return false; @@ -377,14 +485,14 @@ Dependency.Finder finder = options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED) : Dependencies.getClassDependencyFinder(); - Dependency.Filter filter = getDependencyFilter(); + Dependency.Filter filter = new DependencyFilter(); List<Archive> archives = new ArrayList<>(); Deque<String> roots = new LinkedList<>(); for (String s : classes) { Path p = Paths.get(s); if (Files.exists(p)) { - archives.add(new Archive(p, ClassFileReader.newInstance(p))); + archives.add(Archive.getInstance(p)); } else { if (isValidClassName(s)) { roots.add(s); @@ -421,19 +529,26 @@ throw new ClassFileError(e); } - if (matches(classFileName, cf.access_flags)) { - if (!doneClasses.contains(classFileName)) { - doneClasses.add(classFileName); + // tests if this class matches the -include or -apiOnly option if specified + if (!matches(classFileName, cf.access_flags)) { + continue; + } + + if (!doneClasses.contains(classFileName)) { + doneClasses.add(classFileName); + } + + for (Dependency d : finder.findDependencies(cf)) { + if (filter.accepts(d)) { + String cn = d.getTarget().getName(); + if (!doneClasses.contains(cn) && !deque.contains(cn)) { + deque.add(cn); + } + a.addClass(d.getOrigin(), d.getTarget()); } - for (Dependency d : finder.findDependencies(cf)) { - if (filter.accepts(d)) { - String cn = d.getTarget().getName(); - if (!doneClasses.contains(cn) && !deque.contains(cn)) { - deque.add(cn); - } - a.addClass(d.getOrigin(), d.getTarget()); - } - } + } + for (String name : a.reader().skippedEntries()) { + warning("warn.skipped.entry", name, a.getPathName()); } } } @@ -462,6 +577,10 @@ // if name is a fully-qualified class name specified // from command-line, this class might already be parsed doneClasses.add(classFileName); + // process @jdk.Exported for JDK classes + if (isJDKArchive(a)) { + ((JDKArchive)a).processJdkExported(cf); + } for (Dependency d : finder.findDependencies(cf)) { if (depth == 0) { // ignore the dependency @@ -544,7 +663,7 @@ for (Option o : recognizedOptions) { String name = o.aliases[0].substring(1); // there must always be at least one name name = name.charAt(0) == '-' ? name.substring(1) : name; - if (o.isHidden() || name.equals("h")) { + if (o.isHidden() || name.equals("h") || name.startsWith("filter:")) { continue; } log.println(getMessage("main.opt." + name)); @@ -582,14 +701,19 @@ boolean fullVersion; boolean showProfile; boolean showSummary; - boolean wildcard; boolean apiOnly; boolean showLabel; boolean findJDKInternals; + boolean nowarning; + // default is to show package-level dependencies + // and filter references from same package + Analyzer.Type verbose = PACKAGE; + boolean filterSamePackage = true; + boolean filterSameArchive = false; + String filterRegex; String dotOutputDir; String classpath = ""; int depth = 1; - Analyzer.Type verbose = Analyzer.Type.PACKAGE; Set<String> packageNames = new HashSet<>(); String regex; // apply to the dependences Pattern includePattern; // apply to classes @@ -597,6 +721,7 @@ private static class ResourceBundleHelper { static final ResourceBundle versionRB; static final ResourceBundle bundle; + static final ResourceBundle jdkinternals; static { Locale locale = Locale.getDefault(); @@ -610,20 +735,12 @@ } catch (MissingResourceException e) { throw new InternalError("version.resource.missing"); } - } - } - - private List<Archive> getArchives(List<String> filenames) throws IOException { - List<Archive> result = new ArrayList<Archive>(); - for (String s : filenames) { - Path p = Paths.get(s); - if (Files.exists(p)) { - result.add(new Archive(p, ClassFileReader.newInstance(p))); - } else { - warning("warn.file.not.exist", s); + try { + jdkinternals = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdkinternals"); + } catch (MissingResourceException e) { + throw new InternalError("Cannot find jdkinternals resource bundle"); } } - return result; } private List<Archive> getClassPathArchives(String paths) throws IOException { @@ -648,7 +765,7 @@ } for (Path f : files) { if (Files.exists(f)) { - result.add(new Archive(f, ClassFileReader.newInstance(f))); + result.add(Archive.getInstance(f)); } } } @@ -656,81 +773,50 @@ return result; } - /** - * If the given archive is JDK archive and non-null Profile, - * this method returns the profile name only if -profile option is specified; - * a null profile indicates it accesses a private JDK API and this method - * will return "JDK internal API". - * - * For non-JDK archives, this method returns the file name of the archive. - */ - private String getProfileArchiveInfo(Archive source, Profile profile) { - if (options.showProfile && profile != null) - return profile.toString(); - - if (source instanceof JDKArchive) { - return profile == null ? "JDK internal API (" + source.getFileName() + ")" : ""; - } - return source.getFileName(); - } - - /** - * Returns the profile name or "JDK internal API" for JDK archive; - * otherwise empty string. - */ - private String profileName(Archive archive, Profile profile) { - if (archive instanceof JDKArchive) { - return Objects.toString(profile, "JDK internal API"); - } else { - return ""; - } - } - class RawOutputFormatter implements Analyzer.Visitor { private final PrintWriter writer; + private String pkg = ""; RawOutputFormatter(PrintWriter writer) { this.writer = writer; } - - private String pkg = ""; @Override - public void visitDependence(String origin, Archive source, - String target, Archive archive, Profile profile) { - if (options.findJDKInternals && - !(archive instanceof JDKArchive && profile == null)) { - // filter dependences other than JDK internal APIs - return; - } - if (options.verbose == Analyzer.Type.VERBOSE) { - writer.format(" %-50s -> %-50s %s%n", - origin, target, getProfileArchiveInfo(archive, profile)); + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive) { + String tag = toTag(target, targetArchive); + if (options.verbose == VERBOSE) { + writer.format(" %-50s -> %-50s %s%n", origin, target, tag); } else { if (!origin.equals(pkg)) { pkg = origin; - writer.format(" %s (%s)%n", origin, source.getFileName()); + writer.format(" %s (%s)%n", origin, originArchive.getName()); } - writer.format(" -> %-50s %s%n", - target, getProfileArchiveInfo(archive, profile)); - } - } - - @Override - public void visitArchiveDependence(Archive origin, Archive target, Profile profile) { - writer.format("%s -> %s", origin.getPathName(), target.getPathName()); - if (options.showProfile && profile != null) { - writer.format(" (%s)%n", profile); - } else { - writer.format("%n"); + writer.format(" -> %-50s %s%n", target, tag); } } } - class DotFileFormatter extends DotGraph<String> implements AutoCloseable { + class RawSummaryFormatter implements Analyzer.Visitor { + private final PrintWriter writer; + RawSummaryFormatter(PrintWriter writer) { + this.writer = writer; + } + @Override + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive) { + writer.format("%s -> %s", originArchive.getName(), targetArchive.getPathName()); + if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) { + writer.format(" (%s)", target); + } + writer.format("%n"); + } + } + + class DotFileFormatter implements Analyzer.Visitor, AutoCloseable { private final PrintWriter writer; private final String name; DotFileFormatter(PrintWriter writer, Archive archive) { this.writer = writer; - this.name = archive.getFileName(); + this.name = archive.getName(); writer.format("digraph \"%s\" {%n", name); writer.format(" // Path: %s%n", archive.getPathName()); } @@ -741,173 +827,176 @@ } @Override - public void visitDependence(String origin, Archive source, - String target, Archive archive, Profile profile) { - if (options.findJDKInternals && - !(archive instanceof JDKArchive && profile == null)) { - // filter dependences other than JDK internal APIs - return; - } - // if -P option is specified, package name -> profile will - // be shown and filter out multiple same edges. - String name = getProfileArchiveInfo(archive, profile); - writeEdge(writer, new Edge(origin, target, getProfileArchiveInfo(archive, profile))); - } - @Override - public void visitArchiveDependence(Archive origin, Archive target, Profile profile) { - throw new UnsupportedOperationException(); + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive) { + String tag = toTag(target, targetArchive); + writer.format(" %-50s -> \"%s\";%n", + String.format("\"%s\"", origin), + tag.isEmpty() ? target + : String.format("%s (%s)", target, tag)); } } - class DotSummaryForArchive extends DotGraph<Archive> { + class SummaryDotFile implements Analyzer.Visitor, AutoCloseable { + private final PrintWriter writer; + private final Analyzer.Type type; + private final Map<Archive, Map<Archive,StringBuilder>> edges = new HashMap<>(); + SummaryDotFile(PrintWriter writer, Analyzer.Type type) { + this.writer = writer; + this.type = type; + writer.format("digraph \"summary\" {%n"); + } + @Override - public void visitDependence(String origin, Archive source, - String target, Archive archive, Profile profile) { - Edge e = findEdge(source, archive); - assert e != null; - // add the dependency to the label if enabled and not compact1 - if (profile == Profile.COMPACT1) { - return; - } - e.addLabel(origin, target, profileName(archive, profile)); + public void close() { + writer.println("}"); } + @Override - public void visitArchiveDependence(Archive origin, Archive target, Profile profile) { - // add an edge with the archive's name with no tag - // so that there is only one node for each JDK archive - // while there may be edges to different profiles - Edge e = addEdge(origin, target, ""); - if (target instanceof JDKArchive) { - // add a label to print the profile - if (profile == null) { - e.addLabel("JDK internal API"); - } else if (options.showProfile && !options.showLabel) { - e.addLabel(profile.toString()); + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive) { + String targetName = type == PACKAGE ? target : targetArchive.getName(); + if (type == PACKAGE) { + String tag = toTag(target, targetArchive, type); + if (!tag.isEmpty()) + targetName += " (" + tag + ")"; + } else if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) { + targetName += " (" + target + ")"; + } + String label = getLabel(originArchive, targetArchive); + writer.format(" %-50s -> \"%s\"%s;%n", + String.format("\"%s\"", origin), targetName, label); + } + + String getLabel(Archive origin, Archive target) { + if (edges.isEmpty()) + return ""; + + StringBuilder label = edges.get(origin).get(target); + return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString()); + } + + Analyzer.Visitor labelBuilder() { + // show the package-level dependencies as labels in the dot graph + return new Analyzer.Visitor() { + @Override + public void visitDependence(String origin, Archive originArchive, + String target, Archive targetArchive) + { + Map<Archive,StringBuilder> labels = edges.get(originArchive); + if (!edges.containsKey(originArchive)) { + edges.put(originArchive, labels = new HashMap<>()); + } + StringBuilder sb = labels.get(targetArchive); + if (sb == null) { + labels.put(targetArchive, sb = new StringBuilder()); + } + String tag = toTag(target, targetArchive, PACKAGE); + addLabel(sb, origin, target, tag); } - } + + void addLabel(StringBuilder label, String origin, String target, String tag) { + label.append(origin).append(" -> ").append(target); + if (!tag.isEmpty()) { + label.append(" (" + tag + ")"); + } + label.append("\\n"); + } + }; } } - // DotSummaryForPackage generates the summary.dot file for verbose mode - // (-v or -verbose option) that includes all class dependencies. - // The summary.dot file shows package-level dependencies. - class DotSummaryForPackage extends DotGraph<String> { - private String packageOf(String cn) { - int i = cn.lastIndexOf('.'); - return i > 0 ? cn.substring(0, i) : "<unnamed>"; - } - @Override - public void visitDependence(String origin, Archive source, - String target, Archive archive, Profile profile) { - // add a package dependency edge - String from = packageOf(origin); - String to = packageOf(target); - Edge e = addEdge(from, to, getProfileArchiveInfo(archive, profile)); - - // add the dependency to the label if enabled and not compact1 - if (!options.showLabel || profile == Profile.COMPACT1) { - return; - } + /** + * Test if the given archive is part of the JDK + */ + private boolean isJDKArchive(Archive archive) { + return JDKArchive.class.isInstance(archive); + } - // trim the package name of origin to shorten the label - int i = origin.lastIndexOf('.'); - String n1 = i < 0 ? origin : origin.substring(i+1); - e.addLabel(n1, target, profileName(archive, profile)); - } - @Override - public void visitArchiveDependence(Archive origin, Archive target, Profile profile) { - // nop - } - } - abstract class DotGraph<T> implements Analyzer.Visitor { - private final Set<Edge> edges = new LinkedHashSet<>(); - private Edge curEdge; - public void writeTo(PrintWriter writer) { - writer.format("digraph \"summary\" {%n"); - for (Edge e: edges) { - writeEdge(writer, e); - } - writer.println("}"); - } - - void writeEdge(PrintWriter writer, Edge e) { - writer.format(" %-50s -> \"%s\"%s;%n", - String.format("\"%s\"", e.from.toString()), - e.tag.isEmpty() ? e.to - : String.format("%s (%s)", e.to, e.tag), - getLabel(e)); + /** + * If the given archive is JDK archive, this method returns the profile name + * only if -profile option is specified; it accesses a private JDK API and + * the returned value will have "JDK internal API" prefix + * + * For non-JDK archives, this method returns the file name of the archive. + */ + private String toTag(String name, Archive source, Analyzer.Type type) { + if (!isJDKArchive(source)) { + return source.getName(); } - Edge addEdge(T origin, T target, String tag) { - Edge e = new Edge(origin, target, tag); - if (e.equals(curEdge)) { - return curEdge; - } + JDKArchive jdk = (JDKArchive)source; + boolean isExported = false; + if (type == CLASS || type == VERBOSE) { + isExported = jdk.isExported(name); + } else { + isExported = jdk.isExportedPackage(name); + } + Profile p = getProfile(name, type); + if (isExported) { + // exported API + return options.showProfile && p != null ? p.profileName() : ""; + } else { + return "JDK internal API (" + source.getName() + ")"; + } + } + + private String toTag(String name, Archive source) { + return toTag(name, source, options.verbose); + } + + private Profile getProfile(String name, Analyzer.Type type) { + String pn = name; + if (type == CLASS || type == VERBOSE) { + int i = name.lastIndexOf('.'); + pn = i > 0 ? name.substring(0, i) : ""; + } + return Profile.getProfile(pn); + } - if (edges.contains(e)) { - for (Edge e1 : edges) { - if (e.equals(e1)) { - curEdge = e1; - } - } - } else { - edges.add(e); - curEdge = e; + /** + * Returns the recommended replacement API for the given classname; + * or return null if replacement API is not known. + */ + private String replacementFor(String cn) { + String name = cn; + String value = null; + while (value == null && name != null) { + try { + value = ResourceBundleHelper.jdkinternals.getString(name); + } catch (MissingResourceException e) { + // go up one subpackage level + int i = name.lastIndexOf('.'); + name = i > 0 ? name.substring(0, i) : null; } - return curEdge; } + return value; + }; - Edge findEdge(T origin, T target) { - for (Edge e : edges) { - if (e.from.equals(origin) && e.to.equals(target)) { - return e; + private void showReplacements(Analyzer analyzer) { + Map<String,String> jdkinternals = new TreeMap<>(); + boolean useInternals = false; + for (Archive source : sourceLocations) { + useInternals = useInternals || analyzer.hasDependences(source); + for (String cn : analyzer.dependences(source)) { + String repl = replacementFor(cn); + if (repl != null && !jdkinternals.containsKey(cn)) { + jdkinternals.put(cn, repl); } } - return null; + } + if (useInternals) { + log.println(); + warning("warn.replace.useJDKInternals", getMessage("jdeps.wiki.url")); } - - String getLabel(Edge e) { - String label = e.label.toString(); - return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label); + if (!jdkinternals.isEmpty()) { + log.println(); + log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement"); + log.format("%-40s %s%n", "----------------", "---------------------"); + for (Map.Entry<String,String> e : jdkinternals.entrySet()) { + log.format("%-40s %s%n", e.getKey(), e.getValue()); + } } - class Edge { - final T from; - final T to; - final String tag; // optional tag - final StringBuilder label = new StringBuilder(); - Edge(T from, T to, String tag) { - this.from = from; - this.to = to; - this.tag = tag; - } - void addLabel(String s) { - label.append(s).append("\\n"); - } - void addLabel(String origin, String target, String profile) { - label.append(origin).append(" -> ").append(target); - if (!profile.isEmpty()) { - label.append(" (" + profile + ")"); - } - label.append("\\n"); - } - @Override @SuppressWarnings("unchecked") - public boolean equals(Object o) { - if (o instanceof DotGraph<?>.Edge) { - DotGraph<?>.Edge e = (DotGraph<?>.Edge)o; - return this.from.equals(e.from) && - this.to.equals(e.to) && - this.tag.equals(e.tag); - } - return false; - } - @Override - public int hashCode() { - int hash = 7; - hash = 67 * hash + Objects.hashCode(this.from) + - Objects.hashCode(this.to) + Objects.hashCode(this.tag); - return hash; - } - } } }
--- a/src/share/classes/com/sun/tools/jdeps/Main.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/Main.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,4 +63,3 @@ return t.run(args); } } -
--- a/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,12 @@ */ package com.sun.tools.jdeps; +import com.sun.tools.classfile.Annotation; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.RuntimeAnnotations_attribute; +import com.sun.tools.classfile.Dependencies.ClassFileError; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; @@ -33,11 +39,15 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.*; +import static com.sun.tools.classfile.Attribute.*; + /** * ClassPath for Java SE and JDK */ class PlatformClassPath { - private final static List<Archive> javaHomeArchives = init(); + private static final List<String> NON_PLATFORM_JARFILES = + Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar"); + private static final List<Archive> javaHomeArchives = init(); static List<Archive> getArchives() { return javaHomeArchives; @@ -50,12 +60,19 @@ if (home.endsWith("jre")) { // jar files in <javahome>/jre/lib result.addAll(addJarFiles(home.resolve("lib"))); + if (home.getParent() != null) { + // add tools.jar and other JDK jar files + Path lib = home.getParent().resolve("lib"); + if (Files.exists(lib)) { + result.addAll(addJarFiles(lib)); + } + } } else if (Files.exists(home.resolve("lib"))) { // either a JRE or a jdk build image Path classes = home.resolve("classes"); if (Files.isDirectory(classes)) { // jdk build outputdir - result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes))); + result.add(new JDKArchive(classes)); } // add other JAR files result.addAll(addJarFiles(home.resolve("lib"))); @@ -91,9 +108,9 @@ if (fn.endsWith(".jar")) { // JDK may cobundle with JavaFX that doesn't belong to any profile // Treat jfxrt.jar as regular Archive - result.add(fn.equals("jfxrt.jar") - ? new Archive(p, ClassFileReader.newInstance(p)) - : new JDKArchive(p, ClassFileReader.newInstance(p))); + result.add(NON_PLATFORM_JARFILES.contains(fn) + ? Archive.getInstance(p) + : new JDKArchive(p)); } return FileVisitResult.CONTINUE; } @@ -106,8 +123,91 @@ * or implementation classes (i.e. JDK internal API) */ static class JDKArchive extends Archive { - JDKArchive(Path p, ClassFileReader reader) { - super(p, reader); + private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar"); + public static boolean isProfileArchive(Archive archive) { + if (archive instanceof JDKArchive) { + return PROFILE_JARS.contains(archive.getName()); + } + return false; + } + + private final Map<String,Boolean> exportedPackages = new HashMap<>(); + private final Map<String,Boolean> exportedTypes = new HashMap<>(); + JDKArchive(Path p) throws IOException { + super(p, ClassFileReader.newInstance(p)); + } + + /** + * Tests if a given fully-qualified name is an exported type. + */ + public boolean isExported(String cn) { + int i = cn.lastIndexOf('.'); + String pn = i > 0 ? cn.substring(0, i) : ""; + + boolean isJdkExported = isExportedPackage(pn); + if (exportedTypes.containsKey(cn)) { + return exportedTypes.get(cn); + } + return isJdkExported; + } + + /** + * Tests if a given package name is exported. + */ + public boolean isExportedPackage(String pn) { + if (Profile.getProfile(pn) != null || "javax.jnlp".equals(pn)) { + return true; + } + return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false; + } + + private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;"; + private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException { + RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute) + cf.attributes.get(RuntimeVisibleAnnotations); + if (attr != null) { + for (int i = 0; i < attr.annotations.length; i++) { + Annotation ann = attr.annotations[i]; + String annType = cf.constant_pool.getUTF8Value(ann.type_index); + if (JDK_EXPORTED_ANNOTATION.equals(annType)) { + boolean isJdkExported = true; + for (int j = 0; j < ann.num_element_value_pairs; j++) { + Annotation.element_value_pair pair = ann.element_value_pairs[j]; + Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value; + ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info) + cf.constant_pool.get(ev.const_value_index); + isJdkExported = info.value != 0; + } + return Boolean.valueOf(isJdkExported); + } + } + } + return null; + } + + void processJdkExported(ClassFile cf) throws IOException { + try { + String cn = cf.getName(); + String pn = cn.substring(0, cn.lastIndexOf('/')).replace('/', '.'); + + Boolean b = isJdkExported(cf); + if (b != null) { + exportedTypes.put(cn.replace('/', '.'), b); + } + if (!exportedPackages.containsKey(pn)) { + // check if package-info.class has @jdk.Exported + Boolean isJdkExported = null; + ClassFile pcf = reader().getClassFile(cn.substring(0, cn.lastIndexOf('/')+1) + "package-info"); + if (pcf != null) { + isJdkExported = isJdkExported(pcf); + } + if (isJdkExported != null) { + exportedPackages.put(pn, isJdkExported); + } + } + } catch (ConstantPoolException e) { + throw new ClassFileError(e); + } } } }
--- a/src/share/classes/com/sun/tools/jdeps/Profile.java Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/Profile.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ * Build the profile information from ct.sym if exists. */ enum Profile { - COMPACT1("compact1", 1), COMPACT2("compact2", 2), COMPACT3("compact3", 3), @@ -61,8 +60,7 @@ this.proprietaryPkgs = new HashSet<>(); } - @Override - public String toString() { + public String profileName() { return name; } @@ -77,7 +75,7 @@ public static Profile getProfile(String pn) { Profile profile = PackageToProfile.map.get(pn); return (profile != null && profile.packages.contains(pn)) - ? profile : null; + ? profile : null; } static class PackageToProfile {
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Mon Mar 02 12:13:35 2015 -0800 @@ -1,6 +1,6 @@ main.usage.summary=\ Usage: {0} <options> <classes...>\n\ -use -h, -? or --help for a list of possible options +use -h, -? or -help for a list of possible options main.usage=\ Usage: {0} <options> <classes...>\n\ @@ -18,20 +18,29 @@ main.opt.v=\ \ -v -verbose Print all class level dependencies\n\ +\ Equivalent to -verbose:class -filter:none.\n\ \ -verbose:package Print package-level dependencies excluding\n\ -\ dependencies within the same archive\n\ +\ dependencies within the same package by default\n\ \ -verbose:class Print class-level dependencies excluding\n\ -\ dependencies within the same archive +\ dependencies within the same package by default + +main.opt.f=\ +\ -f <regex> -filter <regex> Filter dependences matching the given pattern\n\ +\ If given multiple times, the last one will be used.\n\ +\ -filter:package Filter dependences within the same package (default)\n\ +\ -filter:archive Filter dependences within the same archive\n\ +\ -filter:none No -filter:package and -filter:archive filtering\n\ +\ Filtering specified via the -filter option still applies. main.opt.s=\ \ -s -summary Print dependency summary only main.opt.p=\ -\ -p <pkgname> -package <pkgname> Finds dependences in the given package\n\ +\ -p <pkgname> -package <pkgname> Finds dependences matching the given package name\n\ \ (may be given multiple times) main.opt.e=\ -\ -e <regex> -regex <regex> Finds dependences in packages matching pattern\n\ +\ -e <regex> -regex <regex> Finds dependences matching the given pattern\n\ \ (-p and -e are exclusive) main.opt.include=\ @@ -47,7 +56,10 @@ \ -cp <path> -classpath <path> Specify where to find class files main.opt.R=\ -\ -R -recursive Recursively traverse all dependencies +\ -R -recursive Recursively traverse all dependencies.\n\ +\ The -R option implies -filter:none. If -p, -e, -f\n\ +\ option is specified, only the matching dependences\n\ +\ are analyzed. main.opt.apionly=\ \ -apionly Restrict analysis to APIs i.e. dependences\n\ @@ -74,13 +86,19 @@ err.unknown.option=unknown option: {0} err.missing.arg=no value given for {0} -err.internal.error=internal error: {0} {1} {2} err.invalid.arg.for.option=invalid argument for option: {0} err.option.after.class=option must be specified before classes: {0} err.option.unsupported={0} not supported: {1} err.profiles.msg=No profile information -err.dot.output.path=invalid path: {0} +err.invalid.path=invalid path: {0} warn.invalid.arg=Invalid classname or pathname not exist: {0} warn.split.package=package {0} defined in {1} {2} +warn.replace.useJDKInternals=\ +JDK internal APIs are unsupported and private to JDK implementation that are\n\ +subject to be removed or changed incompatibly and could break your application.\n\ +Please modify your code to eliminate dependency on any JDK internal APIs.\n\ +For the most recent update on JDK internal API replacements, please check:\n\ +{0} artifact.not.found=not found +jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties Mon Mar 02 12:13:35 2015 -0800 @@ -1,4 +1,4 @@ -main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F--help\u3092\u4F7F\u7528\u3057\u307E\u3059 +main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F-help\u3092\u4F7F\u7528\u3057\u307E\u3059 main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n<classes>\u306B\u306F\u3001.class\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u540D\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u5B8C\u5168\u4FEE\u98FE\n\u30AF\u30E9\u30B9\u540D\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\u3002\u4F7F\u7528\u3067\u304D\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059: @@ -9,13 +9,15 @@ main.opt.version=\ -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831 -main.opt.v=\ -v -verbose \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n -verbose:package \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n -verbose:class \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F) +main.opt.v=\ -v -verbose \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n -verbose:class -filter:none\u3068\u540C\u7B49\u3067\u3059\u3002\n -verbose:package \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n -verbose:class \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F) + +main.opt.f=\ -f <regex> -filter <regex> \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n \u8907\u6570\u56DE\u6307\u5B9A\u3055\u308C\u305F\u5834\u5408\u3001\u6700\u5F8C\u306E\u3082\u306E\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n -filter:package \u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n -filter:archive \u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n -filter:none -filter:package\u304A\u3088\u3073-filter:archive\u306E\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306F\u884C\u308F\u308C\u307E\u305B\u3093\n -filter\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u304C\u5F15\u304D\u7D9A\u304D\u9069\u7528\u3055\u308C\u307E\u3059\u3002 main.opt.s=\ -s -summary \u4F9D\u5B58\u6027\u306E\u30B5\u30DE\u30EA\u30FC\u306E\u307F\u51FA\u529B\u3057\u307E\u3059 -main.opt.p=\ -p <pkgname> -package <pkgname> \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD) +main.opt.p=\ -p <pkgname> -package <pkgname> \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD) -main.opt.e=\ -e <regex> -regex <regex> \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (-p\u3068-e\u306F\u6392\u4ED6\u7684) +main.opt.e=\ -e <regex> -regex <regex> \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n (-p\u3068-e\u306F\u6392\u4ED6\u7684) main.opt.include=\ -include <regex> \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059 @@ -23,7 +25,7 @@ main.opt.cp=\ -cp <path> -classpath <path> \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059 -main.opt.R=\ -R -recursive \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u53CD\u5FA9\u7684\u306B\u8D70\u67FB\u3057\u307E\u3059 +main.opt.R=\ -R -recursive \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u518D\u5E30\u7684\u306B\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059\u3002\n -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-filter:none\u3092\u610F\u5473\u3057\u307E\u3059\u3002-p\u3001-e\u3001-f\n \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u306E\u307F\n \u5206\u6790\u3055\u308C\u307E\u3059\u3002 main.opt.apionly=\ -apionly \u5206\u6790\u3092API\u3001\u3064\u307E\u308A\u3001\u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30AF\u30E9\u30B9\u306E\n \u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30E1\u30F3\u30D0\u30FC\u304A\u3088\u3073\u4FDD\u8B77\u3055\u308C\u305F\u30E1\u30F3\u30D0\u30FC\u306E\n \u7F72\u540D\u306B\u304A\u3051\u308B\u4F9D\u5B58\u6027(\u30D5\u30A3\u30FC\u30EB\u30C9\u30FB\u30BF\u30A4\u30D7\u3001\u30E1\u30BD\u30C3\u30C9\u30FB\n \u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\u3001\u623B\u3055\u308C\u305F\u30BF\u30A4\u30D7\u3001\u30C1\u30A7\u30C3\u30AF\u3055\u308C\u305F\n \u4F8B\u5916\u30BF\u30A4\u30D7\u306A\u3069)\u306B\u5236\u9650\u3057\u307E\u3059 @@ -36,13 +38,14 @@ err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0} err.missing.arg={0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093 -err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} {1} {2} err.invalid.arg.for.option=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0} err.option.after.class=\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u30AF\u30E9\u30B9\u306E\u524D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0} err.option.unsupported={0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {1} err.profiles.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u60C5\u5831\u304C\u3042\u308A\u307E\u305B\u3093 -err.dot.output.path=\u7121\u52B9\u306A\u30D1\u30B9: {0} +err.invalid.path=\u7121\u52B9\u306A\u30D1\u30B9: {0} warn.invalid.arg=\u7121\u52B9\u306A\u30AF\u30E9\u30B9\u540D\u307E\u305F\u306F\u30D1\u30B9\u540D\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0} warn.split.package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306F{1} {2}\u3067\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059 +warn.replace.useJDKInternals=JDK\u5185\u90E8API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u304A\u3089\u305A\u3001JDK\u5B9F\u88C5\u5C02\u7528\u3067\u3059\u304C\u3001\u4E92\u63DB\u6027\u306A\u3057\u3067\n\u524A\u9664\u307E\u305F\u306F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E2D\u65AD\u3055\u305B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\nJDK\u5185\u90E8API\u306E\u4F9D\u5B58\u6027\u3092\u524A\u9664\u3059\u308B\u3088\u3046\u30B3\u30FC\u30C9\u3092\u5909\u66F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002\nJDK\u5185\u90E8API\u306E\u7F6E\u63DB\u306B\u95A2\u3059\u308B\u6700\u65B0\u306E\u66F4\u65B0\u306B\u3064\u3044\u3066\u306F\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044:\n{0} artifact.not.found=\u898B\u3064\u304B\u308A\u307E\u305B\u3093 +jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
--- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties Tue Feb 10 15:02:50 2015 -0800 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties Mon Mar 02 12:13:35 2015 -0800 @@ -1,4 +1,4 @@ -main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 --help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879 +main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 -help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879 main.usage=\u7528\u6CD5: {0} <options> <classes...>\n\u5176\u4E2D <classes> \u53EF\u4EE5\u662F .class \u6587\u4EF6, \u76EE\u5F55, JAR \u6587\u4EF6\u7684\u8DEF\u5F84\u540D,\n\u4E5F\u53EF\u4EE5\u662F\u5168\u9650\u5B9A\u7C7B\u540D\u3002\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC: @@ -9,13 +9,15 @@ main.opt.version=\ -version \u7248\u672C\u4FE1\u606F -main.opt.v=\ -v -verbose \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:package \u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:class \u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61 +main.opt.v=\ -v -verbose \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n \u7B49\u540C\u4E8E -verbose:class -filter:none\u3002\n -verbose:package \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -verbose:class \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61 + +main.opt.f=\ -f <regex> -filter <regex> \u7B5B\u9009\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n \u5982\u679C\u591A\u6B21\u6307\u5B9A, \u5219\u5C06\u4F7F\u7528\u6700\u540E\u4E00\u4E2A\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n -filter:package \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u7A0B\u5E8F\u5305\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61 (\u9ED8\u8BA4)\n -filter:archive \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6863\u6848\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n -filter:none \u4E0D\u4F7F\u7528 -filter:package \u548C -filter:archive \u7B5B\u9009\n \u901A\u8FC7 -filter \u9009\u9879\u6307\u5B9A\u7684\u7B5B\u9009\u4ECD\u65E7\u9002\u7528\u3002 main.opt.s=\ -s -summary \u4EC5\u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981 -main.opt.p=\ -p <pkgname> -package <pkgname> \u67E5\u627E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (\u53EF\u80FD\u591A\u6B21\u6307\u5B9A) +main.opt.p=\ -p <pkgname> -package <pkgname> \u67E5\u627E\u4E0E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u540D\u79F0\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (\u53EF\u591A\u6B21\u6307\u5B9A) -main.opt.e=\ -e <regex> -regex <regex> \u67E5\u627E\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (-p \u548C -e \u4E92\u76F8\u6392\u65A5) +main.opt.e=\ -e <regex> -regex <regex> \u67E5\u627E\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n (-p \u548C -e \u4E92\u76F8\u6392\u65A5) main.opt.include=\ -include <regex> \u5C06\u5206\u6790\u9650\u5236\u4E3A\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7C7B\n \u6B64\u9009\u9879\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u5217\u8868\u3002\n \u5B83\u53EF\u4EE5\u4E0E\u5411\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5E94\u7528\u6A21\u5F0F\u7684\n -p \u548C -e \u7ED3\u5408\u4F7F\u7528 @@ -23,7 +25,7 @@ main.opt.cp=\ -cp <path> -classpath <path> \u6307\u5B9A\u67E5\u627E\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E -main.opt.R=\ -R -recursive \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61 +main.opt.R=\ -R -recursive \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n -R \u9009\u9879\u8868\u793A -filter:none\u3002\u5982\u679C\u6307\u5B9A\u4E86 -p, -e, -f\n \u9009\u9879, \u5219\u53EA\u5206\u6790\u5339\u914D\u7684\n \u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002 main.opt.apionly=\ -apionly \u901A\u8FC7\u516C\u5171\u7C7B (\u5305\u62EC\u5B57\u6BB5\u7C7B\u578B, \u65B9\u6CD5\u53C2\u6570\n \u7C7B\u578B, \u8FD4\u56DE\u7C7B\u578B, \u53D7\u63A7\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B\n \u7B49) \u7684\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458\u7684\u7B7E\u540D\n \u9650\u5236\u5BF9 API (\u5373\u88AB\u4F9D\u8D56\u5BF9\u8C61)\n \u8FDB\u884C\u5206\u6790 @@ -36,13 +38,14 @@ err.unknown.option=\u672A\u77E5\u9009\u9879: {0} err.missing.arg=\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C -err.internal.error=\u5185\u90E8\u9519\u8BEF: {0} {1} {2} err.invalid.arg.for.option=\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0} err.option.after.class=\u5FC5\u987B\u5728\u7C7B\u4E4B\u524D\u6307\u5B9A\u9009\u9879: {0} err.option.unsupported=\u4E0D\u652F\u6301{0}: {1} err.profiles.msg=\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u4FE1\u606F -err.dot.output.path=\u65E0\u6548\u8DEF\u5F84: {0} +err.invalid.path=\u65E0\u6548\u8DEF\u5F84: {0} warn.invalid.arg=\u7C7B\u540D\u65E0\u6548\u6216\u8DEF\u5F84\u540D\u4E0D\u5B58\u5728: {0} warn.split.package=\u5DF2\u5728{1} {2}\u4E2D\u5B9A\u4E49\u7A0B\u5E8F\u5305{0} +warn.replace.useJDKInternals=\u4E0D\u652F\u6301 JDK \u5185\u90E8 API, \u5B83\u4EEC\u4E13\u7528\u4E8E\u901A\u8FC7\u4E0D\u517C\u5BB9\u65B9\u5F0F\u6765\u5220\u9664\n\u6216\u66F4\u6539\u7684 JDK \u5B9E\u73B0, \u53EF\u80FD\u4F1A\u635F\u574F\u60A8\u7684\u5E94\u7528\u7A0B\u5E8F\u3002\n\u8BF7\u4FEE\u6539\u60A8\u7684\u4EE3\u7801, \u6D88\u9664\u4E0E\u4EFB\u4F55 JDK \u5185\u90E8 API \u7684\u76F8\u5173\u6027\u3002\n\u6709\u5173 JDK \u5185\u90E8 API \u66FF\u6362\u7684\u6700\u65B0\u66F4\u65B0, \u8BF7\u67E5\u770B:\n{0} artifact.not.found=\u627E\u4E0D\u5230 +jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdkinternals.properties Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,22 @@ +// No translation needed +com.sun.crypto.provider.SunJCE=Use java.security.Security.getProvider(provider-name) @since 1.3 +com.sun.image.codec=Use javax.imageio @since 1.4 +com.sun.org.apache.xml.internal.security=Use java.xml.crypto @since 1.6 +com.sun.org.apache.xml.internal.security.utils.Base64=Use java.util.Base64 @since 1.8 +com.sun.net.ssl=Use javax.net.ssl @since 1.4 +com.sun.net.ssl.internal.ssl.Provider=Use java.security.Security.getProvider(provider-name) @since 1.3 +com.sun.rowset=Use javax.sql.rowset.RowSetProvider @since 1.7 +com.sun.tools.javac.tree=Use com.sun.source @since 1.6 +com.sun.tools.javac=Use javax.tools and javax.lang.model @since 1.6 +sun.awt.image.codec=Use javax.imageio @since 1.4 +sun.misc.BASE64Encoder=Use java.util.Base64 @since 1.8 +sun.misc.BASE64Decoder=Use java.util.Base64 @since 1.8 +sun.misc.Cleaner=Use java.lang.ref.PhantomReference @since 1.2 +sun.misc.Service=Use java.util.ServiceLoader @since 1.6 +sun.security.action=Use java.security.PrivilegedAction @since 1.1 +sun.security.krb5=Use com.sun.security.jgss +sun.security.provider.PolicyFile=Use java.security.Policy.getInstance("JavaPolicy", new URIParameter(uri)) @since 1.6 +sun.security.provider.Sun=Use java.security.Security.getProvider(provider-name) @since 1.3 +sun.security.util.SecurityConstants=Use appropriate java.security.Permission subclass @since 1.1 +sun.security.x509.X500Name=Use javax.security.auth.x500.X500Principal @since 1.4 +sun.tools.jar=Use java.util.jar or jar tool @since 1.2
--- a/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/com/sun/javadoc/testDocRootLink/TestDocRootLink.java Mon Mar 02 12:13:35 2015 -0800 @@ -60,21 +60,21 @@ }; private static final String[][] NEGATED_TEST1 = { {BUG_ID + FS + "pkg1" + FS + "C1.html", - "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">" }, {BUG_ID + FS + "pkg1" + FS + "C1.html", - "<a href=\"http://download.oracle.com/javase/7/docs/pkg2/C2.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/pkg2/C2.html\">" }, {BUG_ID + FS + "pkg1" + FS + "package-summary.html", - "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">" }, {BUG_ID + FS + "pkg1" + FS + "package-summary.html", - "<a href=\"http://download.oracle.com/javase/7/docs/pkg2/C2.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/pkg2/C2.html\">" } }; private static final String[][] TEST2 = { {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", - "Refer <a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">Here</a>" + "Refer <a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">Here</a>" }, {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", "This <a href=\"../pkg1/C1.html\">Here</a> should not be replaced" + NL + @@ -85,7 +85,7 @@ " <a href=\"../pkg1/C1.html\">Link 2</a>." }, {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", - "<a href=\"http://download.oracle.com/javase/7/docs/technotes/guides/index.html\">" + NL + + "<a href=\"https://docs.oracle.com/javase/7/docs/technotes/guides/index.html\">" + NL + " Test document 1</a>" }, {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", @@ -100,13 +100,13 @@ "<a href=\"../../technotes/guides/index.html\">" }, {BUG_ID + "-1" + FS + "pkg2" + FS + "C2.html", - "<a href=\"http://download.oracle.com/javase/7/docs/pkg1/C1.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/pkg1/C1.html\">" }, {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", "<a href=\"../../technotes/guides/index.html\">" }, {BUG_ID + "-1" + FS + "pkg2" + FS + "package-summary.html", - "<a href=\"http://download.oracle.com/javase/7/docs/pkg1/C1.html\">" + "<a href=\"https://docs.oracle.com/javase/7/docs/pkg1/C1.html\">" } }; private static final String[] ARGS1 = @@ -115,7 +115,7 @@ }; private static final String[] ARGS2 = new String[]{ - "-d", BUG_ID + "-1", "-Xdocrootparent", "http://download.oracle.com/javase/7/docs", "-sourcepath", SRC_DIR, "pkg1", "pkg2" + "-d", BUG_ID + "-1", "-Xdocrootparent", "https://docs.oracle.com/javase/7/docs", "-sourcepath", SRC_DIR, "pkg1", "pkg2" }; /**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8062359 + * @summary NullPointerException in Attr when type-annotating an anonymous + * inner class in an unresolvable class + * @compile/fail/ref=UnresolvableClassNPEInAttrTest.out -XDrawDiagnostics UnresolvableClassNPEInAttrTest.java + */ + +public class UnresolvableClassNPEInAttrTest { + public static void main(String[] args) { + new Undefined() { + void test() { + new Object() {}; + } + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,2 @@ +UnresolvableClassNPEInAttrTest.java:11:13: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, UnresolvableClassNPEInAttrTest, null) +1 error
--- a/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -138,7 +138,7 @@ checkClassFile(new File(Paths.get(System.getProperty("user.dir"), "Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT); checkClassFile(new File(Paths.get(System.getProperty("user.dir"), - "Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT); + "Foo.class").toUri()), "lambda$variablesInLambdas$3", lambdaBridgeExpectedLNT); checkClassFile(new File(Paths.get(System.getProperty("user.dir"), "Foo.class").toUri()), "assignLambda", assignmentExpectedLNT); checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8050386/WrongStackframeGenerationTest1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8050386 + * @summary Verification error due to a bad stackmap frame generated by javac + */ + +public class WrongStackframeGenerationTest1 { + public static void main(String[] args) {} + + static void foo(){ + while (true) { + int i = 0; + break; + } + switch (1) { + case 1: + int j = 0; + case 2: + bar(); + } + } + + static void bar() {} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8050386/WrongStackframeGenerationTest2.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8050386 + * @summary Verification error due to a bad stackmap frame generated by javac + */ + +public class WrongStackframeGenerationTest2 { + public static void main(String[] args) {} + + static void foo() { + int len; + for (;;) { + try { + len = 1; + break; + } catch (Exception e) { + } + } + + try { + if (len == -1) { + len = 0; + } + } finally { + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,31 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8059921 + * @summary Missing compile error in Java 8 mode for Interface.super.field access + * @compile/fail/ref=ForbidAccessToFieldUsingSuperTest.out -XDrawDiagnostics ForbidAccessToFieldUsingSuperTest.java + */ + +public class ForbidAccessToFieldUsingSuperTest { + class C { + int m() { return 0; } + } + + interface T { + int f = 0; + C c = null; + default int mm() { + return 0; + } + } + + interface T1 extends T {} + + class X implements T1 { + int i = T1.super.f; //fail + int j = T1.super.c.m(); //fail + + void foo(Runnable r) { + foo(T1.super::mm); //should'n fail + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,3 @@ +ForbidAccessToFieldUsingSuperTest.java:24:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1 +ForbidAccessToFieldUsingSuperTest.java:25:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1 +2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/FinalStringInNested.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8054448 + * @summary Verify that constant strings in nested classes in anonymous classes + * can be used in annotations. + * @compile FinalStringInNested.java + */ + +public class FinalStringInNested { + + public void f() { + Object o = new Object() { + @FinalStringInNested.Annotation(Nested.ID) + class Nested { + static final String ID = "B"; + } + }; + } + + @interface Annotation { + String value(); + } +}
--- a/test/tools/javac/flow/LVTHarness.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/flow/LVTHarness.java Mon Mar 02 12:13:35 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @bug 7047734 8027660 8037937 + * @bug 7047734 8027660 8037937 8047719 8058708 * @summary The LVT is not generated correctly during some try/catch scenarios * javac crash while creating LVT entry for a local variable defined in * an inner block
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/flow/T8042741/LambdaArgumentsTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8054210 + * @summary NullPointerException when compiling specific code + * @compile LambdaArgumentsTest.java + */ + +public class LambdaArgumentsTest { + interface Thrower<E extends Exception> { void apply() throws E; } + interface Consumer<E> { void take(E arg); } + + <E extends Exception> + void m1(Thrower<E> a1, Consumer<E> a2) {} + + <E extends Exception> + void m2(Thrower<E> a1, Consumer<RuntimeException> a2) {} + + void test() { + m1(() -> {}, e -> {}); + m2(() -> {}, (RuntimeException e) -> {}); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/flow/T8062747.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,24 @@ +/** + * @test + * @bug 8062747 + * @summary Avoiding an error for lambdas with thrown types inference inside an anonymous class. + * @compile T8062747.java + */ +public class T8062747 { + + public interface Throwing<Y extends Exception> { + void canThrow() throws Y; + } + + public static <Y extends Exception> void wrap(Throwing<Y> action) { + } + + public static void invoke(String a) { + Runnable r = new Runnable() { + @Override + public void run() { + wrap(() -> System.out.println(a)); + } + }; + } +}
--- a/test/tools/javac/flow/tests/TestCaseIf.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/flow/tests/TestCaseIf.java Mon Mar 02 12:13:35 2015 -0800 @@ -58,4 +58,18 @@ } o = ""; } + + @AliveRange(varName="finalLocal", bytecodeStart=11, bytecodeLength=6) + @AliveRange(varName="used", bytecodeStart=13, bytecodeLength=4) + void m5(Object o) { + if (o != null) { + Object notUsed; + Object used; + if (o != null) { + final Object finalLocal = null; + used = null; + if (o == null) {} + } + } + } }
--- a/test/tools/javac/flow/tests/TestCaseSwitch.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/flow/tests/TestCaseSwitch.java Mon Mar 02 12:13:35 2015 -0800 @@ -5,7 +5,7 @@ @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=16) @AliveRange(varName="o", bytecodeStart=50, bytecodeLength=15) @AliveRange(varName="o", bytecodeStart=68, bytecodeLength=1) - @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=26) + @AliveRange(varName="oo", bytecodeStart=39, bytecodeLength=8) @AliveRange(varName="uu", bytecodeStart=59, bytecodeLength=6) void m1(String[] args) { Object o; @@ -29,7 +29,7 @@ @AliveRange(varName="o", bytecodeStart=95, bytecodeLength=18) @AliveRange(varName="o", bytecodeStart=116, bytecodeLength=15) @AliveRange(varName="o", bytecodeStart=134, bytecodeLength=1) - @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=27) + @AliveRange(varName="oo", bytecodeStart=104, bytecodeLength=9) @AliveRange(varName="uu", bytecodeStart=125, bytecodeLength=6) void m2(String[] args) { Object o; @@ -50,12 +50,14 @@ o = "return"; } - @AliveRange(varName="o", bytecodeStart=31, bytecodeLength=8) - @AliveRange(varName="o", bytecodeStart=42, bytecodeLength=8) - @AliveRange(varName="o", bytecodeStart=53, bytecodeLength=9) - void m3(String[] args) { + @AliveRange(varName="o", bytecodeStart=35, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=46, bytecodeLength=8) + @AliveRange(varName="o", bytecodeStart=78, bytecodeLength=5) + @AliveRange(varName="o", bytecodeStart=86, bytecodeLength=1) + @AliveRange(varName="oo", bytecodeStart=56, bytecodeLength=16) + void m3(int i) { Object o; - switch (args.length) { + switch (i) { case 0: o = "0"; o.hashCode(); @@ -64,10 +66,19 @@ o = "1"; o.hashCode(); break; + case 2: + int oo = i; + if (oo > 1) { + System.out.println("greater"); + } + break; + case 3: + int uu = i; default: o = "default"; o.hashCode(); } o = "finish"; } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/8043926/T8043926.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8043926 + * @summary javac, code valid in 7 is not compiling for 8 + * @compile T8043926.java + */ +class T8043926 { + interface Iface<T1> {} + + static class Impl implements Iface<Impl> {} + + static class Acceptor<T2 extends Iface<T2>> { + public Acceptor(T2 obj) {} + } + + void test(Impl impl) { + Acceptor<?> acceptor1 = new Acceptor<>(impl); + Acceptor<? extends Object> acceptor2 = new Acceptor<>(impl); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/8058511/T8058511a.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058511 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub + * @compile T8058511a.java + */ +class T8058511a { + <Z> void choose(Z z1, Z z2) { } + + void test(Class<Double> cd, Class<? extends double[]> cdarr) { + choose(cd, cdarr); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/8058511/T8058511b.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058511 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub + * @compile T8058511b.java + */ +class T8058511b { + void test(Class<Double> cd, Class<? extends double[]> cdarr) { + ((false) ? cd : cdarr).toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/8058511/T8058511c.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058511 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub + * @compile T8058511c.java + */ +import java.util.List; + +class T8058511c { + void test(List<? extends double[]> l) { + (true ? l.get(0) : l.get(0)).toString(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/T8044546/CrashImplicitLambdaTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8044546 + * @summary Crash on faulty reduce/lambda + * @compile CrashImplicitLambdaTest.java + */ + +abstract class CrashImplicitLambdaTest { + boolean foo() { + return bar(true, a -> {}); + } + + abstract <T1> T1 bar(T1 t1, S<T1> s); + + interface S<S1> { + void baz(S1 s1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/T8044546/NestedInvocationsTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8044546 + * @summary Crash on faulty reduce/lambda + * @compile NestedInvocationsTest.java + */ + +class NestedInvocationsTest<T> { + boolean foo(I<T> i) { + return baz(zas(i)); + } + + <U> J<U, Boolean> zas(I<U> i) { + return null; + } + + <R> R baz(J<T, R> j) { + return null; + } + + interface I<I1> {} + + interface J<J1, J2> {} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/wildcards/T8051402/WildcardAndCAPSubtypeTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8051402 + * @summary javac, type containment should accept that CAP <= ? extends CAP and CAP <= ? super CAP + * @compile WildcardAndCAPSubtypeTest.java + */ + +import java.util.List; + +public abstract class WildcardAndCAPSubtypeTest { + abstract <T> List<T> copyOf(List<? extends T> lx); + abstract <E> List<E> filter(List<E> lx); + + void g(List<?> lx) { + copyOf(filter(lx)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/8051958/T8051958.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8051958 + * @summary Cannot assign a value to final variable in lambda + * @compile T8051958.java + */ + +class T8051958 { + Runnable inst_r = ()-> { + final int x; + x = 1; + }; + + Runnable static_r = ()-> { + final int x; + x = 1; + }; + + { + Runnable inst_r = ()-> { + final int x; + x = 1; + }; + } + + static { + Runnable static_r = ()-> { + final int x; + x = 1; + }; + } + + void instTest() { + Runnable static_r = ()-> { + final int x; + x = 1; + }; + } + + static void staticTest() { + Runnable static_r = ()-> { + final int x; + x = 1; + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/LambdaTestStrictFP.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046060 + * @summary Different results of floating point multiplication for lambda code block + */ + +strictfp +public class LambdaTestStrictFP { + + static double fld = eval(() -> { + double x = Double.longBitsToDouble(0x1e7ee00000000000L); + double y = Double.longBitsToDouble(0x2180101010101010L); + + return x * y; + }); + + public static void main(String args[]) { + double result = eval(() -> { + double x = Double.longBitsToDouble(0x1e7ee00000000000L); + double y = Double.longBitsToDouble(0x2180101010101010L); + + return x * y; + }); + { + double x = Double.longBitsToDouble(0x1e7ee00000000000L); + double y = Double.longBitsToDouble(0x2180101010101010L); + + double z = x * y; + check(z, result, "method"); + check(z, fld, "field"); + } + } + + private static void check(double expected, double got, String where) { + if (got != expected) { + throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected); + } + } + + private static double eval(Face arg) { + return arg.m(); + } + + private interface Face { + double m(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/LambdaTestStrictFPFlag.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046060 + * @summary Different results of floating point multiplication for lambda code block + */ + +import java.io.*; +import java.net.URL; +import com.sun.tools.classfile.*; +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT; + +public class LambdaTestStrictFPFlag { + public static void main(String[] args) throws Exception { + new LambdaTestStrictFPFlag().run(); + } + + void run() throws Exception { + ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class"); + ConstantPool cp = cf.constant_pool; + boolean found = false; + for (Method meth: cf.methods) { + if (meth.getName(cp).startsWith("lambda$")) { + if ((meth.access_flags.flags & ACC_STRICT) == 0) { + throw new Exception("strict flag missing from lambda"); + } + found = true; + } + } + if (!found) { + throw new Exception("did not find lambda method"); + } + } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { + URL url = getClass().getResource(name); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); + } + } + + class Test { + strictfp void test() { + Face itf = () -> { }; + } + } + + interface Face { + void m(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/LambdaTestStrictFPMethod.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8046060 + * @summary Different results of floating point multiplication for lambda code block + */ + +public class LambdaTestStrictFPMethod { + + public static void main(String args[]) { + new LambdaTestStrictFPMethod().test(); + } + + strictfp void test() { + double result = eval(() -> { + double x = Double.longBitsToDouble(0x1e7ee00000000000L); + double y = Double.longBitsToDouble(0x2180101010101010L); + + return x * y; + }); + { + double x = Double.longBitsToDouble(0x1e7ee00000000000L); + double y = Double.longBitsToDouble(0x2180101010101010L); + + double z = x * y; + check(z, result, "method"); + } + } + + strictfp void check(double expected, double got, String where) { + if (got != expected) { + throw new AssertionError(where + ": Non-strictfp " + got + " != " + expected); + } + } + + static double eval(Face arg) { + return arg.m(); + } + + interface Face { + double m(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MethodReferenceArrayClone.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8056051 + * @summary int[]::clone causes "java.lang.NoClassDefFoundError: Array" + * @run main MethodReferenceArrayClone + */ + +import java.util.Arrays; +import java.util.function.Function; +import java.util.function.Supplier; + +public class MethodReferenceArrayClone { + public static void main(String[] args) { + int[] intArgs = new int[] {1, 2, 3, 4, 5}; + checkInt("int[]::clone", int[]::clone, intArgs); + checkInt("a -> a.clone()", a -> a.clone(), intArgs); + checkInt("intArgs::clone", intArgs::clone, intArgs); + + String[] stringArgs = new String[] {"hi", "de", "ho"}; + checkString("String[]::clone", String[]::clone, stringArgs); + checkString("a -> a.clone()", a -> a.clone(), stringArgs); + checkString("args::clone", stringArgs::clone, stringArgs); + } + + private static void checkInt(String label, Supplier<int[]> s, int[] expected) { + if (!Arrays.equals(s.get(), expected)) { + throw new RuntimeException("Unexpected value " + label + ": " + Arrays.toString(s.get())); + } + } + + private static void checkInt(String label, Function<int[], int[]> f, int[] a) { + checkInt(label, () -> f.apply(a), a); + } + + private static void checkString(String label, Supplier<String[]> s, String[] expected) { + if (!Arrays.equals(s.get(), expected)) { + throw new RuntimeException("Unexpected value " + label + ": " + Arrays.toString(s.get())); + } + } + + private static void checkString(String label, Function<String[], String[]> f, String[] a) { + checkString(label, () -> f.apply(a), a); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,31 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8033483 + * @summary Should ignore nested lambda bodies during overload resolution + * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java + */ + +class IgnoreLambdaBodyDuringResolutionTest1 { + interface SAM<T> { + T action(T t); + } + + <T> T m(SAM<T> op) { + return null; + } + + class B { + B x() { + return this; + } + } + + class C {} + + void foo(B arg) {} + void foo(C arg) {} + + void bar() { + foo(m(arg -> new B())); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,2 @@ +IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1 +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,34 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8033483 + * @summary Should ignore nested lambda bodies during overload resolution + * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java + */ + +class IgnoreLambdaBodyDuringResolutionTest2 { + interface SAM<S> { + boolean test(S t); + } + + <I, T extends I> I bar(final T l) { + return null; + } + + class D<D1, D2> { + void foo() { + m(bar(e -> false)); + } + + void m(Class<D1> arg) {} + void m(SAM<D2> arg) {} + } + + class F { + void foo() { + m(bar((String e) -> false)); + } + + <F1> void m(Class<F1> arg) {} + <F2> void m(SAM<F2> arg) {} + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,6 @@ +IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D +IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object)) +IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))) +IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F +IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)) +5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8056014.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8056014 + * @summary Verify that full type inference is used when calling a method on a type variable. + * @compile T8056014.java + * @run main T8056014 + */ + +import java.util.*; + +public class T8056014 { + public static void main(String[] args) { + new T8056014().run(); + } + + void run() { + List<S> l = Arrays.asList(new S()); + C<S> c = new C<>(new S()); + foo(l.get(0).copy(1)); + foo(c.get(0).copy(1)); + } + + void foo(S d) { + } +} + +class B { + public B copy(long j) { + throw new AssertionError("Should not get here."); + } +} + +class S extends B { + public <T> T copy(int i) { + return null; + } +} + +class C<T extends B> { + final T t; + public C(T t) { + this.t = t; + } + public T get(int i) { + return t; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8056984.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8056984 + * @summary Ensure that method resolution runs over a captured type variables when checking if + * deferred attribution is needed + * @compile T8056984.java + */ +class T8056984<T1 extends B&C, T2 extends T1> { + public T8056984(T1 t1, T2 t2) { + System.err.println(t1.hashCode()); + System.err.println(t2.hashCode()); + } +} +class B { +} +interface C { + public int hashCode(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8057794.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,12 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8057794 + * @summary The tree for TypeVar.class does not have a type set, which leads to an NPE when + * checking if deferred attribution is needed + * @compile/fail/ref=T8057794.out -XDrawDiagnostics T8057794.java + */ +class T8057794<T> { + void t() { + System.out.println(T.class.getSimpleName()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8057794.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,2 @@ +T8057794.java:10:29: compiler.err.type.var.cant.be.deref +1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8057800/NPEMethodReferenceAndGenericsTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8057800 + * @summary Method reference with generic type creates NPE when compiling + * @compile NPEMethodReferenceAndGenericsTest.java + */ + +public class NPEMethodReferenceAndGenericsTest { + public <T> void foo(java.util.Comparator<? super T> comparator) {} + + public <C extends Comparable<? super C>> void foo() { + foo(C::compareTo); + } +}
--- a/test/tools/javac/lambda/TargetType61.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/lambda/TargetType61.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8007464 + * @bug 8007464 8051402 * @summary Add graph inference support * check that new wildcards inference strategy doesn't run into 7190296 * @compile TargetType61.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRef8.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8063052 + * @summary Inference chokes on wildcard derived from method reference + * @compile MethodRef8.java + */ + +public class MethodRef8 { + void test(Box<? extends Box<? extends Number>> b) { + Number n1 = b.map(Box::get).get(); + Number n2 = b.<Number>map(Box::get).get(); + } + + interface Func<S,T> { T apply(S arg); } + + interface Box<T> { + T get(); + <R> Box<R> map(Func<T,R> f); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerBootstrap.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8044748 + * @summary JVM cannot access constructor though ::new reference although can call it directly + */ + +public class MethodRefNewInnerBootstrap { + + interface Constructor { + public MyTest execute(int i); + } + + public class MyTest { + public MyTest(int i) { System.out.println("Constructor executed " + i); } + } + + public Constructor getConstructor() { + return MyTest::new; + } + + public static void main(String argv[]) { + new MethodRefNewInnerBootstrap().call(); + } + + public void call() { + MyTest mt = new MyTest(0); + + Constructor c1 = MyTest::new; + c1.execute(1); + + Constructor c2 = getConstructor(); + c2.execute(2); + + Constructor c3 = new Constructor() { + public MyTest execute(int i) { + return new MyTest(3); + } + }; + c3.execute(3); + + Constructor c4 = new Constructor() { + public MyTest execute(int i) { + Constructor c = MyTest::new; + return c.execute(i); + } + }; + c4.execute(4); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8037404 + * @summary javac NPE or VerifyError for code with constructor reference of inner class + */ + +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class MethodRefNewInnerInLambdaNPE1 { + public static void main(String[] args) { + if (new MethodRefNewInnerInLambdaNPE1().getList().get().getClass() != TT.class) + throw new AssertionError("sanity failed"); + } + + Supplier<TT> getList() { + return () -> Stream.of(1).map(TT::new).findFirst().get(); + } + + class TT { + public TT(int i) { + + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaNPE2.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8044737 + * @summary Lambda: NPE while obtaining method reference through lambda expression + * @compile MethodRefNewInnerInLambdaNPE2.java + */ + +public class MethodRefNewInnerInLambdaNPE2 { + + interface Constructor { + MyTest execute(); + } + + class MyTest { + MyTest() { System.out.println("Constructor executed"); } + } + + public Constructor getConstructor() { + return getConstructor(() -> { return MyTest::new; }); + } + + public static void main(String argv[]) { + MethodRefNewInnerInLambdaNPE2 t = new MethodRefNewInnerInLambdaNPE2(); + MyTest mytest = t.getConstructor().execute(); + } + + Constructor getConstructor(Wrapper arg) { + return arg.unwrap(); + } + + interface Wrapper { + Constructor unwrap(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8037404 + * @summary javac NPE or VerifyError for code with constructor reference of inner class + */ + +import java.util.function.Function; +import java.util.stream.Stream; + +public class MethodRefNewInnerInLambdaVerify1 { + public static void main(String[] args) { + if (new MethodRefNewInnerInLambdaVerify1().map().apply(1).getClass() != TT.class) + throw new AssertionError("sanity failed"); + } + + Function<Integer,TT> map() { + return (i) -> Stream.of(i).map(TT::new).findFirst().get(); + } + + class TT { + public TT(int i) { + + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8038776 + * @summary VerifyError when running successfully compiled java class + */ + +import java.util.function.Function; + +/** + * Derived from code by: + * @author Yawkat + */ +public class MethodRefNewInnerInLambdaVerify2 { + public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2().runTest(); } + + private void runTest() { + Worker worker = new Worker(); + run(() -> worker.check(field -> new SomeClass(field))); + run(() -> worker.check(SomeClass::new)); + } + + private void run(Runnable runnable) { + runnable.run(); + } + + private class SomeClass { + final Object field; + + SomeClass(Object field) { + this.field = field; + } + } + + private static class Worker { + void check(Function<Object, SomeClass> i) { + if (!i.apply("frank").field.equals("frank")) throw new AssertionError("sanity failed"); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefNewInnerInLambdaVerify2simple.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8038776 + * @summary VerifyError when running successfully compiled java class + */ + +import java.util.function.Function; + +/** + * Derived from code by: + * @author Yawkat + */ +public class MethodRefNewInnerInLambdaVerify2simple { + public static void main(String[] args) { new MethodRefNewInnerInLambdaVerify2simple().runTest(); } + + private void runTest() { + Runnable r = (() -> { Sup w = SomeClass::new; } ); + } + + private class SomeClass { + SomeClass() { } + } +} + +interface Sup { + Object get(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefQualifier1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8048121 + * @summary javac complex method references: revamp and simplify + */ + +public class MethodRefQualifier1 { + + interface SAM { + void m(); + } + + static int count = 0; + + static void assertTrue(boolean cond, String msg) { + if (!cond) + throw new AssertionError(msg); + } + + MethodRefQualifier1 check() { + count++; + return this; + } + + void ido(Object... args) { } + + public static void main(String[] args) { + new MethodRefQualifier1().test(); + } + + void test() { + count = 0; + SAM s = check()::ido; + assertTrue(count == 1, "creation: unexpected: " + count); + count = 0; + s.m(); + assertTrue(count == 0, "evaluation: unexpected: " + count); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefSingleRefEvalBridge.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8048121 + * @summary javac complex method references: revamp and simplify + * + * Make sure that the method reference receiver is evaluated exactly once + * even in this bridging case. + */ + + public class MethodRefSingleRefEvalBridge { + + interface SAM { + int m(); + } + + class ZZ { + // private to force bridging + private int four() { return 4; } + } + + static int count = 0; + ZZ azz = new ZZ(); + + static void assertEqual(int expected, int got) { + if (got != expected) + throw new AssertionError("Expected " + expected + " got " + got); + } + + public static void main(String[] args) { + new MethodRefSingleRefEvalBridge().test(); + } + + ZZ check() { + count++; + return azz; + } + + void test() { + count = 0; + SAM s = check()::four; + assertEqual(1, count); + + count = 0; + assertEqual(4, s.m()); + assertEqual(0, count); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodRefToInner.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8047341 + * @summary lambda reference to inner class in base class causes LambdaConversionException + */ + +import java.util.List; +import java.util.ArrayList; + +class MethodRefToInnerBase { + class TestString { + String str; + TestString(String strin) { + str = strin; + } + } +} +public class MethodRefToInner extends MethodRefToInnerBase { + public static void main(String[] args) { + new MethodRefToInner().run(); + } + MethodRefToInner() { + super(); + } + void run() { + List<String> list = new ArrayList<>(); + list.stream().forEach(TestString::new); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReference/MethodReferenceComplexNullCheckTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8048121 + * @summary javac complex method references: revamp and simplify + * + * Make sure NPE check is done even in the convert to Lambda case + */ + +public class MethodReferenceComplexNullCheckTest { + public static void main(String[] args) { + F fr = null; + boolean npeFired = false; + try { + IForm frf = fr::doit; + } catch (NullPointerException npe) { + npeFired = true; + } finally { + if (!npeFired) throw new AssertionError( "NPE should have been thrown"); + } + } + + interface IForm { + void xyz(Object... args); + } + + class F { + private void doit(Object... args) { } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection1.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058112 + * @summary Invalid BootstrapMethod for constructor/method reference + */ + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import static java.util.stream.Collectors.toList; + +public class MethodReferenceIntersection1 { + + public static void main(String[] args) { + MethodReferenceIntersection1 main = new MethodReferenceIntersection1(); + List<Info_MRI1> list = main.toInfoListError(Arrays.asList(new Base_MRI1())); + System.out.printf("result %d\n", list.size()); + } + + public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListError(List<H> list) { + Comparator<B_MRI1> byNameComparator = + (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB()); + return list.stream().sorted(byNameComparator).map(Info_MRI1::new).collect(toList()); + } + + public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListWorks(List<H> list) { + Comparator<B_MRI1> byNameComparator = + (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB()); + return list.stream().sorted(byNameComparator).map(s -> new Info_MRI1(s)).collect(toList()); + } +} + +interface B_MRI1 { + public String getB(); +} + +interface A_MRI1 { + public long getA(); +} + +class Info_MRI1 { + private final long a; + private final String b; + + <H extends A_MRI1 & B_MRI1> Info_MRI1(H h) { + a = h.getA(); + b = h.getB(); + } +} + +class Base_MRI1 implements A_MRI1, B_MRI1 { + + @Override + public long getA() { + return 7L; + } + + @Override + public String getB() { + return "hello"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection2.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058112 + * @summary Invalid BootstrapMethod for constructor/method reference + */ + +import java.util.function.Function; + +public class MethodReferenceIntersection2 { + + interface B { } + + interface A { } + + static class C implements A, B { } + + static class Info { + <H extends A & B> Info(H h) { } + + static <H extends A & B> Info info(H h) { + return new Info(h); + } + } + + public static void main(String[] args) { + test(); + } + + // Note the switch in order compared to that on Info + static <H extends B & A> void test() { + Function<H, Info> f1L = _h -> new Info(_h); + Function<H, Info> f1 = Info::new; + Function<H, Info> f2L = _h -> Info.info(_h); + Function<H, Info> f2 = Info::info; + H c = (H) new C(); + if(f1.apply(c) instanceof Info && + f2.apply(c) instanceof Info) { + System.out.println("Passes."); + } else { + throw new AssertionError(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection3.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8058112 + * @summary Invalid BootstrapMethod for constructor/method reference + */ + +/** + * @author Remi Forax + */ + +public class MethodReferenceIntersection3 { + interface A {} + + interface Foo { + <T extends Object & A> void foo(T t); + } + + static <T extends A> void bar(T t) { + } + + public static void main(String[] args) { + Foo foo = MethodReferenceIntersection3::bar; + foo.foo(new A(){}); + } +}
--- a/test/tools/javac/varargs/6313164/T6313164.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/varargs/6313164/T6313164.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,18 +1,26 @@ /* * @test /nodynamiccopyright/ - * @bug 6313164 + * @bug 6313164 8036953 * @author mcimadamore * @summary javac generates code that fails byte code verification for the varargs feature - * @compile/fail/ref=T6313164.out -XDrawDiagnostics T6313164.java + * @compile/fail/ref=T6313164Source7.out -source 7 -XDrawDiagnostics T6313164.java + * @compile/fail/ref=T6313164Source8AndHigher.out -XDrawDiagnostics T6313164.java */ import p1.*; class T6313164 { - { B b = new B(); - b.foo1(new B(), new B()); //error - A not accesible - b.foo2(new B(), new B()); //ok - A not accessible, but foo2(Object...) applicable - b.foo3(null, null); //error - A (inferred) not accesible - b.foo4(null, null); //error - A (inferred in 15.12.2.8 - no resolution backtrack) not accesible - b.foo4(new B(), new C()); //ok - A (inferred in 15.12.2.7) not accessible, but foo4(Object...) applicable + { + B b = new B(); + b.foo1(new B(), new B()); //error - A not accessible + /* 7 : ok - A not accessible, but foo2(Object...) applicable + * 8+ : error - A not accessible + */ + b.foo2(new B(), new B()); + b.foo3(null, null); //error - A (inferred) not accessible + b.foo4(null, null); //error - A not accesible + /* 7 : ok - A not accessible, but foo4(Object...) applicable + * 8+ : error - A not accessible + */ + b.foo4(new B(), new C()); } }
--- a/test/tools/javac/varargs/6313164/T6313164.out Tue Feb 10 15:02:50 2015 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -T6313164.java:12:8: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) -T6313164.java:14:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) -T6313164.java:15:13: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) -- compiler.note.unchecked.filename: B.java -- compiler.note.unchecked.recompile -3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/6313164/T6313164Source7.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,6 @@ +- compiler.warn.source.no.bootclasspath: 1.7 +T6313164.java:14:10: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +3 errors +1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/6313164/T6313164Source8AndHigher.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,6 @@ +T6313164.java:14:15: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:18:15: compiler.err.cant.apply.symbol: kindname.method, foo2, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +T6313164.java:24:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164) +5 errors
--- a/test/tools/javac/varargs/6313164/T7175433.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/varargs/6313164/T7175433.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,31 +1,8 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test + * @test /nodynamiccopyright/ * @bug 7175433 6313164 * @summary Inference cleanup: add helper class to handle inference variables - * + * @compile/fail/ref=T7175433.out -XDrawDiagnostics T7175433.java */ import java.util.List; @@ -34,26 +11,16 @@ private class Foo { } - <Z> List<Z> m(Object... o) { T7175433.assertTrue(true); return null; } - <Z> List<Z> m(Foo... o) { T7175433.assertTrue(false); return null; } + <Z> List<Z> m(Object... o) { return null; } + <Z> List<Z> m(Foo... o) { return null; } Foo getFoo() { return null; } } public class T7175433 { - static int assertionCount; - - static void assertTrue(boolean b) { - assertionCount++; - if (!b) { - throw new AssertionError(); - } - } - public static void main(String[] args) { Bar b = new Bar(); b.m(b.getFoo()); - assertTrue(assertionCount == 1); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/6313164/T7175433.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,2 @@ +T7175433.java:24:12: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: Bar.Foo, kindname.class, T7175433) +1 error
--- a/test/tools/javac/varargs/6313164/p1/B.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/javac/varargs/6313164/p1/B.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,12 @@ package p1; +@SuppressWarnings("unchecked") public class B extends A { - public B() {} public void foo1(A... args) { } public void foo2(A... args) { } public void foo2(Object... args) { } public <X extends A> void foo3(X... args) { } public <X extends A> void foo4(X... args) { } public void foo4(Object... args) { } - }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/8055514/T8055514.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,26 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8055514 + * @summary Wrong, confusing error when non-static varargs referenced in static context + * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java + */ +class T8055514 { + void m(int... args) { } + + void m2(int... args) { } + static void m2(String s) { } + + void m3(int... args) { } + static void m3(String s) { } + static void m3(Runnable r) { } + + void m4(int... args) { } + void m4(int i1, int i2, int i3) { } + + static void test() { + m(1,2,3); //only one candidate (varargs) - varargs error wins + m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins + m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins + m4(1,2,3); //two candidates - both applicable - basic error wins + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/8055514/T8055514.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,5 @@ +T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...) +T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...) +T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...) +T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int) +4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/varargs/T8049075/VarargsAndWildcardParameterizedTypeTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8049075 + * @summary javac, wildcards and generic vararg method invocation not accepted + * @compile VarargsAndWildcardParameterizedTypeTest.java + */ + +class VarargsAndWildcardParameterizedTypeTest { + interface I<T> { + String m(T... t); + } + + void m() { + I<? super Integer> i = null; + i.m(Integer.valueOf(1), Integer.valueOf(1)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/warnings/suppress/Overridden.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,16 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8033421 + * @summary Check that \\@SuppressWarnings works properly when overriding deprecated method. + * @build VerifySuppressWarnings + * @compile/ref=Overridden.out -XDrawDiagnostics -Xlint:deprecation Overridden.java + * @run main VerifySuppressWarnings Overridden.java + */ + +public class Overridden implements Interface { + public void test() { } +} + +interface Interface { + @Deprecated void test(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/warnings/suppress/Overridden.out Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,2 @@ +Overridden.java:11:17: compiler.warn.has.been.deprecated: test(), Interface +1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/warnings/suppress/OverriddenSuppressed.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8033421 + * @summary Check that \\@SuppressWarnings works properly when overriding deprecated method. + * @compile -Werror -Xlint:deprecation OverriddenSuppressed.java + */ + +public class OverriddenSuppressed implements Interface { + @SuppressWarnings("deprecation") + public void test() { } +} + +interface Interface { + @Deprecated void test(); +}
--- a/test/tools/jdeps/APIDeps.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/jdeps/APIDeps.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8015912 8029216 + * @bug 8015912 8029216 8048063 8050804 * @summary Test -apionly and -jdkinternals options * @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G * @run main APIDeps @@ -81,27 +81,39 @@ new String[] {"compact1", "compact3", testDirBasename}, new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"}); test(new File(mDir, "Foo.class"), + new String[] {"c.I", "e.E", "f.F"}, + new String[] {testDirBasename}, + new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P"}); + test(new File(mDir, "Foo.class"), new String[] {"c.I", "e.E", "f.F", "m.Bar"}, new String[] {testDirBasename}, - new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"}); + new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none", "-P"}); test(new File(mDir, "Gee.class"), - new String[] {"g.G", "sun.misc.Lock"}, - new String[] {testDirBasename, "JDK internal API"}, - new String[] {"-classpath", testDir.getPath(), "-verbose"}); + new String[] {"g.G", "sun.misc.Lock", "com.sun.tools.classfile.ClassFile", + "com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree"}, + new String[] {testDirBasename, "JDK internal API", "compact3", ""}, + new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"}); // -jdkinternals test(new File(mDir, "Gee.class"), - new String[] {"sun.misc.Lock"}, + new String[] {"sun.misc.Lock", "com.sun.tools.classfile.ClassFile"}, new String[] {"JDK internal API"}, new String[] {"-jdkinternals"}); // -jdkinternals parses all classes on -classpath and the input arguments test(new File(mDir, "Gee.class"), - new String[] {"sun.misc.Lock", "sun.misc.Unsafe"}, + new String[] {"com.sun.tools.jdeps.Main", "com.sun.tools.classfile.ClassFile", + "sun.misc.Lock", "sun.misc.Unsafe"}, new String[] {"JDK internal API"}, new String[] {"-classpath", testDir.getPath(), "-jdkinternals"}); // parse only APIs - // parse only APIs + test(mDir, + new String[] {"java.lang.Object", "java.lang.String", + "java.util.Set", + "c.C", "d.D", "c.I", "e.E"}, + new String[] {"compact1", testDirBasename}, + new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P", "-apionly"}); + test(mDir, new String[] {"java.lang.Object", "java.lang.String", "java.util.Set",
--- a/test/tools/jdeps/Basic.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/jdeps/Basic.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8003562 8005428 8015912 8027481 + * @bug 8003562 8005428 8015912 8027481 8048063 * @summary Basic tests for jdeps tool * @build Test p.Foo p.Bar javax.activity.NotCompactProfile * @run main Basic @@ -86,6 +86,16 @@ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, new String[] {"compact1", "compact1", "not found", "not found"}, new String[] {"-verbose:class"}); + // test -filter:none option + test(new File(testDir, "p"), + new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"}, + new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"}); + // test -filter:archive option + test(new File(testDir, "p"), + new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, + new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"}); // test -p option test(new File(testDir, "Test.class"), new String[] {"p.Foo", "p.Bar"}, @@ -100,11 +110,12 @@ new String[] {"java.lang"}, new String[] {"compact1"}, new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); + // test -classpath and -include options test(null, - new String[] {"java.lang", "java.util", - "java.lang.management", "javax.crypto"}, - new String[] {"compact1", "compact1", "compact3", "compact1"}, + new String[] {"java.lang", "java.util", "java.lang.management", + "javax.activity", "javax.crypto"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"}); test(new File(testDir, "Test.class"), new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/jdeps/DotFileTest.java Mon Mar 02 12:13:35 2015 -0800 @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8003562 + * @summary Basic tests for jdeps -dotoutput option + * @build Test p.Foo p.Bar javax.activity.NotCompactProfile + * @run main DotFileTest + */ + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.*; + +public class DotFileTest { + private static boolean symbolFileExist = initProfiles(); + private static boolean initProfiles() { + // check if ct.sym exists; if not use the profiles.properties file + Path home = Paths.get(System.getProperty("java.home")); + if (home.endsWith("jre")) { + home = home.getParent(); + } + Path ctsym = home.resolve("lib").resolve("ct.sym"); + boolean symbolExists = ctsym.toFile().exists(); + if (!symbolExists) { + Path testSrcProfiles = + Paths.get(System.getProperty("test.src", "."), "profiles.properties"); + if (!testSrcProfiles.toFile().exists()) + throw new Error(testSrcProfiles + " does not exist"); + System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n", + ctsym, testSrcProfiles); + System.setProperty("jdeps.profiles", testSrcProfiles.toString()); + } + return symbolExists; + } + + public static void main(String... args) throws Exception { + int errors = 0; + errors += new DotFileTest().run(); + if (errors > 0) + throw new Exception(errors + " errors found"); + } + + final Path dir; + final Path dotoutput; + DotFileTest() { + this.dir = Paths.get(System.getProperty("test.classes", ".")); + this.dotoutput = dir.resolve("dots"); + } + + int run() throws IOException { + File testDir = dir.toFile(); + // test a .class file + test(new File(testDir, "Test.class"), + new String[] {"java.lang", "p"}, + new String[] {"compact1", "not found"}); + // test a directory + // also test non-SE javax.activity class dependency + test(new File(testDir, "p"), + new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, + new String[] {"-classpath", testDir.getPath()}); + // test class-level dependency output + test(new File(testDir, "Test.class"), + new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, + new String[] {"compact1", "compact1", "not found", "not found"}, + new String[] {"-verbose:class"}); + // test -filter:none option + test(new File(testDir, "p"), + new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"}, + new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"}); + // test -filter:archive option + test(new File(testDir, "p"), + new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, + new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, + new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"}); + // test -p option + test(new File(testDir, "Test.class"), + new String[] {"p.Foo", "p.Bar"}, + new String[] {"not found", "not found"}, + new String[] {"-verbose:class", "-p", "p"}); + // test -e option + test(new File(testDir, "Test.class"), + new String[] {"p.Foo", "p.Bar"}, + new String[] {"not found", "not found"}, + new String[] {"-verbose:class", "-e", "p\\..*"}); + test(new File(testDir, "Test.class"), + new String[] {"java.lang"}, + new String[] {"compact1"}, + new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); + // test -classpath options + test(new File(testDir, "Test.class"), + new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, + new String[] {"compact1", "compact1", testDir.getName(), testDir.getName()}, + new String[] {"-v", "-classpath", testDir.getPath()}); + + testSummary(new File(testDir, "Test.class"), + new String[] {"rt.jar", testDir.getName()}, + new String[] {"compact1", ""}, + new String[] {"-classpath", testDir.getPath()}); + testSummary(new File(testDir, "Test.class"), + new String[] {"java.lang", "p"}, + new String[] {"compact1", testDir.getName()}, + new String[] {"-v", "-classpath", testDir.getPath()}); + return errors; + } + + void test(File file, String[] expect, String[] profiles) throws IOException { + test(file, expect, profiles, new String[0]); + } + + void test(File file, String[] expect, String[] profiles, String[] options) + throws IOException + { + Path dotfile = dotoutput.resolve(file.toPath().getFileName().toString() + ".dot"); + + List<String> args = new ArrayList<>(Arrays.asList(options)); + args.add("-dotoutput"); + args.add(dotoutput.toString()); + if (file != null) { + args.add(file.getPath()); + } + + Map<String,String> result = jdeps(args, dotfile); + checkResult("dependencies", expect, result.keySet()); + + // with -P option + List<String> argsWithDashP = new ArrayList<>(); + argsWithDashP.add("-dotoutput"); + argsWithDashP.add(dotoutput.toString()); + argsWithDashP.add("-P"); + argsWithDashP.addAll(args); + + result = jdeps(argsWithDashP, dotfile); + checkResult("profiles", expect, profiles, result); + } + + void testSummary(File file, String[] expect, String[] profiles, String[] options) + throws IOException + { + Path dotfile = dotoutput.resolve("summary.dot"); + + List<String> args = new ArrayList<>(Arrays.asList(options)); + args.add("-dotoutput"); + args.add(dotoutput.toString()); + if (file != null) { + args.add(file.getPath()); + } + + Map<String,String> result = jdeps(args, dotfile); + checkResult("dependencies", expect, result.keySet()); + + // with -P option + List<String> argsWithDashP = new ArrayList<>(); + argsWithDashP.add("-dotoutput"); + argsWithDashP.add(dotoutput.toString()); + argsWithDashP.add("-P"); + argsWithDashP.addAll(args); + + result = jdeps(argsWithDashP, dotfile); + checkResult("profiles", expect, profiles, result); + } + + Map<String,String> jdeps(List<String> args, Path dotfile) throws IOException { + if (Files.exists(dotoutput)) { + try (DirectoryStream<Path> stream = Files.newDirectoryStream(dotoutput)) { + for (Path p : stream) { + Files.delete(p); + } + } + Files.delete(dotoutput); + } + // invoke jdeps + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + System.err.println("jdeps " + args); + int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[0]), pw); + pw.close(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + if (rc != 0) + throw new Error("jdeps failed: rc=" + rc); + + // check output files + if (Files.notExists(dotfile)) { + throw new RuntimeException(dotfile + " doesn't exist"); + } + return parse(dotfile); + } + private static Pattern pattern = Pattern.compile("(.*) -> +([^ ]*) (.*)"); + private Map<String,String> parse(Path outfile) throws IOException { + Map<String,String> result = new LinkedHashMap<>(); + for (String line : Files.readAllLines(outfile)) { + line = line.replace('"', ' ').replace(';', ' '); + Matcher pm = pattern.matcher(line); + if (pm.find()) { + String origin = pm.group(1).trim(); + String target = pm.group(2).trim(); + String module = pm.group(3).replace('(', ' ').replace(')', ' ').trim(); + result.put(target, module); + } + } + return result; + } + + void checkResult(String label, String[] expect, Collection<String> found) { + List<String> list = Arrays.asList(expect); + if (!isEqual(list, found)) + error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); + } + + void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) { + if (expect.length != profiles.length) + error("Invalid expected names and profiles"); + + // check the dependencies + checkResult(label, expect, result.keySet()); + // check profile information + checkResult(label, profiles, result.values()); + for (int i=0; i < expect.length; i++) { + String profile = result.get(expect[i]); + if (!profile.equals(profiles[i])) + error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'"); + } + } + + boolean isEqual(List<String> expected, Collection<String> found) { + if (expected.size() != found.size()) + return false; + + List<String> list = new ArrayList<>(found); + list.removeAll(expected); + return list.isEmpty(); + } + + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +}
--- a/test/tools/jdeps/m/Gee.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/jdeps/m/Gee.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,5 +26,7 @@ class Gee extends g.G { public sun.misc.Lock lock; + public com.sun.tools.classfile.ClassFile cf; // @jdk.Exported(false) + public com.sun.source.tree.BinaryTree tree; // @jdk.Exported + public com.sun.management.ThreadMXBean mxbean; // @jdk.Exported on package-info } -
--- a/test/tools/jdeps/p/Bar.java Tue Feb 10 15:02:50 2015 -0800 +++ b/test/tools/jdeps/p/Bar.java Mon Mar 02 12:13:35 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,4 +30,8 @@ public javax.crypto.Cipher getCiper() { return null; } + + public Foo foo() { + return new Foo(); + } }