# HG changeset patch # User kizune # Date 1386065595 -14400 # Node ID aaea3a69fa6c4fd23911ab8228808d194b052c92 # Parent 53dd31d3c5d7f62f8bd9ff3bfc6c0044c73c74ab# Parent 1f6ffcd56363122654cb08aa486db590c5b6d8b1 Merge diff -r 53dd31d3c5d7 -r aaea3a69fa6c .hgtags --- a/.hgtags Sun Nov 03 07:33:31 2013 +0000 +++ b/.hgtags Tue Dec 03 14:13:15 2013 +0400 @@ -236,3 +236,7 @@ 954dd199d6ff3e4cfc42b894c1f611150526eecd jdk8-b112 54150586ba785e1eb0c0de8d13906f643f640644 jdk8-b113 850d2602ae9811687b0f404d05ec3e55df91d9cb jdk8-b114 +6b4d6205366c1170ebefea95b1b9ae1d69add036 jdk8-b115 +3c040b04af05646878798216ebf939d27e6fe687 jdk8-b116 +19de039a03a619b99f1a8b454e1618c9fa9dae66 jdk8-b117 +4fd6a7ff8c068eceaaaf8bf12a394195203b99b3 jdk8-b118 diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/code/Kinds.java --- a/src/share/classes/com/sun/tools/javac/code/Kinds.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java Tue Dec 03 14:13:15 2013 +0400 @@ -87,16 +87,17 @@ /** Kinds for erroneous symbols that complement the above */ - public static final int ERRONEOUS = 1 << 7; - public static final int AMBIGUOUS = ERRONEOUS+1; // ambiguous reference - public static final int HIDDEN = ERRONEOUS+2; // hidden method or field - public static final int STATICERR = ERRONEOUS+3; // nonstatic member from static context - public static final int MISSING_ENCL = ERRONEOUS+4; // missing enclosing class - public static final int ABSENT_VAR = ERRONEOUS+5; // missing variable - public static final int WRONG_MTHS = ERRONEOUS+6; // methods with wrong arguments - public static final int WRONG_MTH = ERRONEOUS+7; // one method with wrong arguments - public static final int ABSENT_MTH = ERRONEOUS+8; // missing method - public static final int ABSENT_TYP = ERRONEOUS+9; // missing type + public static final int ERRONEOUS = 1 << 7; + public static final int AMBIGUOUS = ERRONEOUS + 1; // ambiguous reference + public static final int HIDDEN = ERRONEOUS + 2; // hidden method or field + public static final int STATICERR = ERRONEOUS + 3; // nonstatic member from static context + public static final int MISSING_ENCL = ERRONEOUS + 4; // missing enclosing class + public static final int ABSENT_VAR = ERRONEOUS + 5; // missing variable + public static final int WRONG_MTHS = ERRONEOUS + 6; // methods with wrong arguments + public static final int WRONG_MTH = ERRONEOUS + 7; // one method with wrong arguments + public static final int ABSENT_MTH = ERRONEOUS + 8; // missing method + public static final int ABSENT_TYP = ERRONEOUS + 9; // missing type + public static final int WRONG_STATICNESS = ERRONEOUS + 10; // wrong staticness for method references public enum KindName implements Formattable { ANNOTATION("kindname.annotation"), @@ -231,14 +232,14 @@ return KindName.CLASS; } - /** A KindName representing the kind of a a missing symbol, given an + /** A KindName representing the kind of a missing symbol, given an * error kind. * */ public static KindName absentKind(int kind) { switch (kind) { case ABSENT_VAR: return KindName.VAR; - case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: + case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS: return KindName.METHOD; case ABSENT_TYP: return KindName.CLASS; diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Dec 03 14:13:15 2013 +0400 @@ -244,7 +244,7 @@ public Type visitClassType(ClassType t, Symbol sym) { if (t.tsym == sym) return t; - Type base = asSuper(sym.type, t); + Type base = asSuper(sym.type, t.tsym); if (base == null) return null; ListBuffer from = new ListBuffer(); @@ -687,7 +687,7 @@ (t.flags() & SYNTHETIC) == 0; } }; - private boolean pendingBridges(ClassSymbol origin, TypeSymbol sym) { + private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { //a symbol will be completed from a classfile if (a) symbol has //an associated file object with CLASS kind and (b) the symbol has //not been entered @@ -696,11 +696,11 @@ enter.getEnv(origin) == null) { return false; } - if (origin == sym) { + if (origin == s) { return true; } for (Type t : interfaces(origin.type)) { - if (pendingBridges((ClassSymbol)t.tsym, sym)) { + if (pendingBridges((ClassSymbol)t.tsym, s)) { return true; } } @@ -761,7 +761,7 @@ } else if (t.hasTag(TYPEVAR)) { return isSubtypeUnchecked(t.getUpperBound(), s, warn); } else if (!s.isRaw()) { - Type t2 = asSuper(t, s); + Type t2 = asSuper(t, s.tsym); if (t2 != null && t2.isRaw()) { if (isReifiable(s)) { warn.silentWarn(LintCategory.UNCHECKED); @@ -914,7 +914,7 @@ @Override public Boolean visitClassType(ClassType t, Type s) { - Type sup = asSuper(t, s); + Type sup = asSuper(t, s.tsym); return sup != null && sup.tsym == s.tsym // You're not allowed to write @@ -1935,42 +1935,30 @@ * @param t a type * @param sym a symbol */ - public Type asSuper(Type t, Symbol s) { - return asSuper(t, s.type); - } - - public Type asSuper(Type t, Type s) { - return asSuper.visit(t, s); + public Type asSuper(Type t, Symbol sym) { + return asSuper.visit(t, sym); } // where - private SimpleVisitor asSuper = new SimpleVisitor() { - - public Type visitType(Type t, Type s) { + private SimpleVisitor asSuper = new SimpleVisitor() { + + public Type visitType(Type t, Symbol sym) { return null; } @Override - public Type visitClassType(ClassType t, Type s) { - if (t.tsym == s.tsym) + public Type visitClassType(ClassType t, Symbol sym) { + if (t.tsym == sym) return t; Type st = supertype(t); - - switch(st.getTag()) { - default: break; - case CLASS: - case ARRAY: - case TYPEVAR: - case ERROR: { - Type x = asSuper(st, s); + if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) { + Type x = asSuper(st, sym); if (x != null) return x; - } break; } - - if ((s.tsym.flags() & INTERFACE) != 0) { + if ((sym.flags() & INTERFACE) != 0) { for (List l = interfaces(t); l.nonEmpty(); l = l.tail) { - Type x = asSuper(l.head, s); + Type x = asSuper(l.head, sym); if (x != null) return x; } @@ -1979,20 +1967,22 @@ } @Override - public Type visitArrayType(ArrayType t, Type s) { - return isSubtype(t, s) ? s : null; + public Type visitArrayType(ArrayType t, Symbol sym) { + return isSubtype(t, sym.type) ? sym.type : null; } @Override - public Type visitTypeVar(TypeVar t, Type s) { - if (t.tsym == s.tsym) + public Type visitTypeVar(TypeVar t, Symbol sym) { + if (t.tsym == sym) return t; else - return asSuper(t.bound, s); + return asSuper(t.bound, sym); } @Override - public Type visitErrorType(ErrorType t, Type s) { return t; } + public Type visitErrorType(ErrorType t, Symbol sym) { + return t; + } }; /** @@ -3573,9 +3563,9 @@ //step 3 - for each element G in MEC, compute lci(Inv(G)) List candidates = List.nil(); for (Type erasedSupertype : mec) { - List lci = List.of(asSuper(ts.head, erasedSupertype)); + List lci = List.of(asSuper(ts.head, erasedSupertype.tsym)); for (Type t : ts) { - lci = intersect(lci, List.of(asSuper(t, erasedSupertype))); + lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym))); } candidates = candidates.appendList(lci); } @@ -3995,7 +3985,7 @@ // The arguments to the supers could be unified here to // get a more accurate analysis while (commonSupers.nonEmpty()) { - Type t1 = asSuper(from, commonSupers.head); + Type t1 = asSuper(from, commonSupers.head.tsym); Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) return false; @@ -4026,7 +4016,7 @@ from = target; } Assert.check((from.tsym.flags() & FINAL) != 0); - Type t1 = asSuper(from, to); + Type t1 = asSuper(from, to.tsym); if (t1 == null) return false; Type t2 = to; if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/Annotate.java --- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Dec 03 14:13:15 2013 +0400 @@ -255,6 +255,9 @@ : attr.attribType(a.annotationType, env)); a.type = chk.checkType(a.annotationType.pos(), at, expected); if (a.type.isErroneous()) { + // Need to make sure nested (anno)trees does not have null as .type + attr.postAttr(a); + if (typeAnnotation) { return new Attribute.TypeCompound(a.type, List.>nil(), new TypeAnnotationPosition()); @@ -265,6 +268,10 @@ if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) { log.error(a.annotationType.pos(), "not.annotation.type", a.type.toString()); + + // Need to make sure nested (anno)trees does not have null as .type + attr.postAttr(a); + if (typeAnnotation) { return new Attribute.TypeCompound(a.type, List.>nil(), null); } else { @@ -278,7 +285,7 @@ Assign(make.Ident(names.value), args.head); } ListBuffer> buf = - new ListBuffer>(); + new ListBuffer<>(); for (List tl = args; tl.nonEmpty(); tl = tl.tail) { JCExpression t = tl.head; if (!t.hasTag(ASSIGN)) { @@ -304,8 +311,7 @@ Type result = method.type.getReturnType(); Attribute value = enterAttributeValue(result, assign.rhs, env); if (!method.type.isErroneous()) - buf.append(new Pair - ((MethodSymbol)method, value)); + buf.append(new Pair<>((MethodSymbol)method, value)); t.type = result; } if (typeAnnotation) { diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 03 14:13:15 2013 +0400 @@ -58,7 +58,6 @@ import static com.sun.tools.javac.code.Kinds.ERRONEOUS; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.code.TypeTag.WILDCARD; -import static com.sun.tools.javac.code.TypeTag.ARRAY; import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This is the main context-dependent analysis phase in GJC. It @@ -806,44 +805,33 @@ Type t = tree.type != null ? tree.type : attribType(tree, env); - return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible); + return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); } Type checkBase(Type t, JCTree tree, Env env, boolean classExpected, - boolean interfacesOnlyExpected, - boolean interfacesOrArraysExpected, + boolean interfaceExpected, boolean checkExtensible) { if (t.isErroneous()) return t; - if (t.hasTag(TYPEVAR) && !classExpected && - !interfacesOrArraysExpected && !interfacesOnlyExpected) { + if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) { // check that type variable is already visible if (t.getUpperBound() == null) { log.error(tree.pos(), "illegal.forward.ref"); return types.createErrorType(t); } - } else if (classExpected) { + } else { t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); - } else { - t = chk.checkClassOrArrayType(tree.pos(), t, - checkExtensible|!allowGenerics); } - if (interfacesOnlyExpected && !t.tsym.isInterface()) { + if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) { log.error(tree.pos(), "intf.expected.here"); // return errType is necessary since otherwise there might // be undetected cycles which cause attribution to loop return types.createErrorType(t); - } else if (interfacesOrArraysExpected && - !(t.tsym.isInterface() || t.getTag() == ARRAY)) { - log.error(tree.pos(), "intf.or.array.expected.here"); - // return errType is necessary since otherwise there might - // be undetected cycles which cause attribution to loop - return types.createErrorType(t); } else if (checkExtensible && classExpected && - t.tsym.isInterface()) { + (t.tsym.flags() & INTERFACE) != 0) { log.error(tree.pos(), "no.intf.expected.here"); return types.createErrorType(t); } @@ -855,12 +843,6 @@ chk.checkNonCyclic(tree.pos(), t); return t; } - //where - private Object asTypeParam(Type t) { - return (t.hasTag(TYPEVAR)) - ? diags.fragment("type.parameter", t) - : t; - } Type attribIdentAsEnumType(Env env, JCIdent id) { Assert.check((env.enclClass.sym.flags() & ENUM) != 0); @@ -2254,7 +2236,8 @@ // empty annotations, if only declaration annotations were given. // This method will raise an error for such a type. for (JCAnnotation ai : annotations) { - if (typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { + if (!ai.type.isErroneous() && + typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) { log.error(ai.pos(), "annotation.type.not.applicable"); } } @@ -2714,9 +2697,10 @@ Pair refResult = null; List saved_undet = resultInfo.checkContext.inferenceContext().save(); try { - refResult = rs.resolveMemberReference(that.pos(), localEnv, that, that.expr.type, - that.name, argtypes, typeargtypes, true, referenceCheck, - resultInfo.checkContext.inferenceContext()); + refResult = rs.resolveMemberReference(localEnv, that, that.expr.type, + that.name, argtypes, typeargtypes, referenceCheck, + resultInfo.checkContext.inferenceContext(), + resultInfo.checkContext.deferredAttrContext().mode); } finally { resultInfo.checkContext.inferenceContext().rollback(saved_undet); } @@ -2736,6 +2720,7 @@ case HIDDEN: case STATICERR: case MISSING_ENCL: + case WRONG_STATICNESS: targetError = true; break; default: @@ -2787,26 +2772,6 @@ chk.checkRaw(that.expr, localEnv); } - if (!that.kind.isUnbound() && - that.getMode() == ReferenceMode.INVOKE && - TreeInfo.isStaticSelector(that.expr, names) && - !that.sym.isStatic()) { - log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), - diags.fragment("non-static.cant.be.ref", Kinds.kindName(refSym), refSym)); - result = that.type = types.createErrorType(target); - return; - } - - if (that.kind.isUnbound() && - that.getMode() == ReferenceMode.INVOKE && - TreeInfo.isStaticSelector(that.expr, names) && - that.sym.isStatic()) { - log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()), - diags.fragment("static.method.in.unbound.lookup", Kinds.kindName(refSym), refSym)); - result = that.type = types.createErrorType(target); - return; - } - if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) && exprType.getTypeArguments().nonEmpty()) { //static ref with class type-args @@ -3984,7 +3949,7 @@ Set boundSet = new HashSet(); if (bounds.nonEmpty()) { // accept class or interface or typevar as first bound. - bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false); + bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); boundSet.add(types.erasure(bounds.head.type)); if (bounds.head.type.isErroneous()) { return bounds.head.type; @@ -4000,7 +3965,7 @@ // if first bound was a class or interface, accept only interfaces // as further bounds. for (JCExpression bound : bounds.tail) { - bound.type = checkBase(bound.type, bound, env, false, false, true, false); + bound.type = checkBase(bound.type, bound, env, false, true, false); if (bound.type.isErroneous()) { bounds = List.of(bound); } @@ -4619,9 +4584,8 @@ validateAnnotatedType(t, t.type); } repeat = false; - } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE) { - // This happens in test TargetTypeTest52.java - // Is there anything to do? + } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE || + enclTr.getKind() == JCTree.Kind.ERRONEOUS) { repeat = false; } else { Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() + diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 03 14:13:15 2013 +0400 @@ -707,37 +707,6 @@ return t; } - // Analog of checkClassType that calls checkClassOrArrayType instead - Type checkClassOrArrayType(DiagnosticPosition pos, - Type t, boolean noBounds) { - t = checkClassOrArrayType(pos, t); - if (noBounds && t.isParameterized()) { - List args = t.getTypeArguments(); - while (args.nonEmpty()) { - if (args.head.hasTag(WILDCARD)) - return typeTagError(pos, - diags.fragment("type.req.exact"), - args.head); - args = args.tail; - } - } - return t; - } - - /** Check that type is a reifiable class, interface or array type. - * @param pos Position to be used for error reporting. - * @param t The type to be checked. - */ - Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { - t = checkClassOrArrayType(pos, t); - if (!t.isErroneous() && !types.isReifiable(t)) { - log.error(pos, "illegal.generic.type.for.instof"); - return types.createErrorType(t); - } else { - return t; - } - } - /** Check that type is a reference type, i.e. a class, interface or array type * or a type variable. * @param pos Position to be used for error reporting. @@ -2253,9 +2222,6 @@ seen = seen.prepend(tv); for (Type b : types.getBounds(tv)) checkNonCyclic1(pos, b, seen); - } else if (t.hasTag(ARRAY)) { - final ArrayType at = (ArrayType)t.unannotatedType(); - checkNonCyclic1(pos, at.elemtype, seen); } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Dec 03 14:13:15 2013 +0400 @@ -643,15 +643,16 @@ } JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; - Pair lookupRes = - rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, - tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext); - switch (lookupRes.fst.kind) { + Symbol lookupSym = + rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type, + tree.name, argtypes.toList(), inferenceContext); + switch (lookupSym.kind) { //note: as argtypes are erroneous types, type-errors must //have been caused by arity mismatch case Kinds.ABSENT_MTH: case Kinds.WRONG_MTH: case Kinds.WRONG_MTHS: + case Kinds.WRONG_STATICNESS: checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref")); } } @@ -1037,11 +1038,10 @@ attr.memberReferenceQualifierResult(tree)); JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; - Pair lookupRes = - rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type, - tree.name, List.nil(), null, true, rs.nilMethodCheck, - infer.emptyContext); - Symbol res = tree.sym = lookupRes.fst; + Symbol res = + rs.getMemberReference(tree, localEnv, mref2, + exprTree.type, tree.name); + tree.sym = res; if (res.kind >= Kinds.ERRONEOUS || res.type.hasTag(FORALL) || (res.flags() & Flags.VARARGS) != 0 || diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Dec 03 14:13:15 2013 +0400 @@ -1378,7 +1378,11 @@ ref = make.Ident(sym); args = make.Idents(md.params); } else { - ref = make.Select(make.Ident(md.params.head), sym); + Symbol msym = sym; + if (sym.owner.isInterface()) { + msym = msym.clone(types.supertype(accessor.owner.type).tsym); + } + ref = make.Select(make.Ident(md.params.head), msym); args = make.Idents(md.params.tail); } JCStatement stat; // The statement accessing the private symbol. diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Dec 03 14:13:15 2013 +0400 @@ -25,6 +25,7 @@ package com.sun.tools.javac.comp; +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.tools.javac.api.Formattable.LocalizedString; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Symbol.*; @@ -110,6 +111,9 @@ SymbolNotFoundError(ABSENT_VAR); methodNotFound = new SymbolNotFoundError(ABSENT_MTH); + methodWithCorrectStaticnessNotFound = new + SymbolNotFoundError(WRONG_STATICNESS, + "method found has incorrect staticness"); typeNotFound = new SymbolNotFoundError(ABSENT_TYP); @@ -144,6 +148,7 @@ */ private final SymbolNotFoundError varNotFound; private final SymbolNotFoundError methodNotFound; + private final SymbolNotFoundError methodWithCorrectStaticnessNotFound; private final SymbolNotFoundError typeNotFound; public static Resolve instance(Context context) { @@ -868,6 +873,12 @@ } }; + /** + * This class handles method reference applicability checks; since during + * these checks it's sometime possible to have inference variables on + * the actual argument types list, the method applicability check must be + * extended so that inference variables are 'opened' as needed. + */ class MethodReferenceCheck extends AbstractMethodCheck { InferenceContext pendingInferenceContext; @@ -2674,6 +2685,97 @@ return resolveOperator(pos, optag, env, List.of(left, right)); } + Symbol getMemberReference(DiagnosticPosition pos, + Env env, + JCMemberReference referenceTree, + Type site, + Name name) { + + site = types.capture(site); + + ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper( + referenceTree, site, name, List.nil(), null, VARARITY); + + Env newEnv = env.dup(env.tree, env.info.dup()); + Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym, + nilMethodCheck, lookupHelper); + + env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase; + + return sym; + } + + ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree, + Type site, + Name name, + List argtypes, + List typeargtypes, + MethodResolutionPhase maxPhase) { + ReferenceLookupHelper result; + if (!name.equals(names.init)) { + //method reference + result = + new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); + } else { + if (site.hasTag(ARRAY)) { + //array constructor reference + result = + new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); + } else { + //class constructor reference + result = + new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); + } + } + return result; + } + + Symbol resolveMemberReferenceByArity(Env env, + JCMemberReference referenceTree, + Type site, + Name name, + List argtypes, + InferenceContext inferenceContext) { + + boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names); + site = types.capture(site); + + ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( + referenceTree, site, name, argtypes, null, VARARITY); + //step 1 - bound lookup + Env boundEnv = env.dup(env.tree, env.info.dup()); + Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, + arityMethodCheck, boundLookupHelper); + if (isStaticSelector && + !name.equals(names.init) && + !boundSym.isStatic() && + boundSym.kind < ERRONEOUS) { + boundSym = methodNotFound; + } + + //step 2 - unbound lookup + Symbol unboundSym = methodNotFound; + ReferenceLookupHelper unboundLookupHelper = null; + Env unboundEnv = env.dup(env.tree, env.info.dup()); + if (isStaticSelector) { + unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, + arityMethodCheck, unboundLookupHelper); + if (unboundSym.isStatic() && + unboundSym.kind < ERRONEOUS) { + unboundSym = methodNotFound; + } + } + + //merge results + Symbol bestSym = choose(boundSym, unboundSym); + env.info.pendingResolutionPhase = bestSym == unboundSym ? + unboundEnv.info.pendingResolutionPhase : + boundEnv.info.pendingResolutionPhase; + + return bestSym; + } + /** * Resolution of member references is typically done as a single * overload resolution step, where the argument types A are inferred from @@ -2700,47 +2802,118 @@ * the type T might be dynamically inferred (i.e. if constructor reference * has a raw qualifier). */ - Pair resolveMemberReference(DiagnosticPosition pos, - Env env, + Pair resolveMemberReference(Env env, JCMemberReference referenceTree, Type site, - Name name, List argtypes, + Name name, + List argtypes, List typeargtypes, - boolean boxingAllowed, MethodCheck methodCheck, - InferenceContext inferenceContext) { - MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; + InferenceContext inferenceContext, + AttrMode mode) { site = types.capture(site); - - ReferenceLookupHelper boundLookupHelper; - if (!name.equals(names.init)) { - //method reference - boundLookupHelper = - new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); - } else if (site.hasTag(ARRAY)) { - //array constructor reference - boundLookupHelper = - new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } else { - //class constructor reference - boundLookupHelper = - new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase); - } + ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper( + referenceTree, site, name, argtypes, typeargtypes, VARARITY); //step 1 - bound lookup Env boundEnv = env.dup(env.tree, env.info.dup()); - Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); + Symbol origBoundSym; + boolean staticErrorForBound = false; + MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext(); + boundSearchResolveContext.methodCheck = methodCheck; + Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(), + site.tsym, boundSearchResolveContext, boundLookupHelper); + SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH; + boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names); + boolean shouldCheckForStaticness = isStaticSelector && + referenceTree.getMode() == ReferenceMode.INVOKE; + if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) { + if (shouldCheckForStaticness) { + if (!boundSym.isStatic()) { + staticErrorForBound = true; + if (hasAnotherApplicableMethod( + boundSearchResolveContext, boundSym, true)) { + boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC; + } else { + boundSearchResultKind = SearchResultKind.BAD_MATCH; + if (boundSym.kind < ERRONEOUS) { + boundSym = methodWithCorrectStaticnessNotFound; + } + } + } else if (boundSym.kind < ERRONEOUS) { + boundSearchResultKind = SearchResultKind.GOOD_MATCH; + } + } + } //step 2 - unbound lookup - ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + Symbol origUnboundSym = null; + Symbol unboundSym = methodNotFound; + ReferenceLookupHelper unboundLookupHelper = null; Env unboundEnv = env.dup(env.tree, env.info.dup()); - Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); + SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH; + boolean staticErrorForUnbound = false; + if (isStaticSelector) { + unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext); + MethodResolutionContext unboundSearchResolveContext = + new MethodResolutionContext(); + unboundSearchResolveContext.methodCheck = methodCheck; + unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(), + site.tsym, unboundSearchResolveContext, unboundLookupHelper); + + if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) { + if (shouldCheckForStaticness) { + if (unboundSym.isStatic()) { + staticErrorForUnbound = true; + if (hasAnotherApplicableMethod( + unboundSearchResolveContext, unboundSym, false)) { + unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC; + } else { + unboundSearchResultKind = SearchResultKind.BAD_MATCH; + if (unboundSym.kind < ERRONEOUS) { + unboundSym = methodWithCorrectStaticnessNotFound; + } + } + } else if (unboundSym.kind < ERRONEOUS) { + unboundSearchResultKind = SearchResultKind.GOOD_MATCH; + } + } + } + } //merge results Pair res; Symbol bestSym = choose(boundSym, unboundSym); - res = new Pair(bestSym, + if (bestSym.kind < ERRONEOUS && (staticErrorForBound || staticErrorForUnbound)) { + if (staticErrorForBound) { + boundSym = methodWithCorrectStaticnessNotFound; + } + if (staticErrorForUnbound) { + unboundSym = methodWithCorrectStaticnessNotFound; + } + bestSym = choose(boundSym, unboundSym); + } + if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) { + Symbol symToPrint = origBoundSym; + String errorFragmentToPrint = "non-static.cant.be.ref"; + if (staticErrorForBound && staticErrorForUnbound) { + if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) { + symToPrint = origUnboundSym; + errorFragmentToPrint = "static.method.in.unbound.lookup"; + } + } else { + if (!staticErrorForBound) { + symToPrint = origUnboundSym; + errorFragmentToPrint = "static.method.in.unbound.lookup"; + } + } + log.error(referenceTree.expr.pos(), "invalid.mref", + Kinds.kindName(referenceTree.getMode()), + diags.fragment(errorFragmentToPrint, + Kinds.kindName(symToPrint), symToPrint)); + } + res = new Pair<>(bestSym, bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper); env.info.pendingResolutionPhase = bestSym == unboundSym ? unboundEnv.info.pendingResolutionPhase : @@ -2748,18 +2921,42 @@ return res; } + + enum SearchResultKind { + GOOD_MATCH, //type I + BAD_MATCH_MORE_SPECIFIC, //type II + BAD_MATCH, //type III + NOT_APPLICABLE_MATCH //type IV + } + + boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext, + Symbol bestSoFar, boolean staticMth) { + for (Candidate c : resolutionContext.candidates) { + if (resolutionContext.step != c.step || + !c.isApplicable() || + c.sym == bestSoFar) { + continue; + } else { + if (c.sym.isStatic() == staticMth) { + return true; + } + } + } + return false; + } + //where - private Symbol choose(Symbol s1, Symbol s2) { - if (lookupSuccess(s1) && lookupSuccess(s2)) { - return ambiguityError(s1, s2); - } else if (lookupSuccess(s1) || - (canIgnore(s2) && !canIgnore(s1))) { - return s1; - } else if (lookupSuccess(s2) || - (canIgnore(s1) && !canIgnore(s2))) { - return s2; + private Symbol choose(Symbol boundSym, Symbol unboundSym) { + if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) { + return ambiguityError(boundSym, unboundSym); + } else if (lookupSuccess(boundSym) || + (canIgnore(unboundSym) && !canIgnore(boundSym))) { + return boundSym; + } else if (lookupSuccess(unboundSym) || + (canIgnore(boundSym) && !canIgnore(unboundSym))) { + return unboundSym; } else { - return s1; + return boundSym; } } @@ -2780,6 +2977,8 @@ InapplicableSymbolsError errSyms = (InapplicableSymbolsError)s; return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); + case WRONG_STATICNESS: + return false; default: return false; } @@ -2894,7 +3093,6 @@ List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) { super(name, site, argtypes, typeargtypes, maxPhase); this.referenceTree = referenceTree; - } /** @@ -3324,6 +3522,11 @@ return false; } + @Override + public boolean isStatic() { + return false; + } + /** * Create an external representation for this erroneous symbol to be * used during attribution - by default this returns the symbol of a @@ -3398,7 +3601,11 @@ class SymbolNotFoundError extends ResolveError { SymbolNotFoundError(int kind) { - super(kind, "symbol not found error"); + this(kind, "symbol not found error"); + } + + SymbolNotFoundError(int kind, String debugName) { + super(kind, debugName); } @Override @@ -3436,7 +3643,8 @@ hasLocation = !location.name.equals(names._this) && !location.name.equals(names._super); } - boolean isConstructor = kind == ABSENT_MTH && name == names.init; + boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) && + name == names.init; KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind); Name idname = isConstructor ? site.tsym.name : name; String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation); diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Dec 03 14:13:15 2013 +0400 @@ -483,17 +483,8 @@ /** Emit an invokedynamic instruction. */ public void emitInvokedynamic(int desc, Type mtype) { - // N.B. this format is under consideration by the JSR 292 EG int argsize = width(mtype.getParameterTypes()); - int prevPos = pendingStatPos; - try { - //disable line number generation (we could have used 'emit1', that - //bypasses stackmap generation - which is needed for indy calls) - pendingStatPos = Position.NOPOS; - emitop(invokedynamic); - } finally { - pendingStatPos = prevPos; - } + emitop(invokedynamic); if (!alive) return; emit2(desc); emit2(0); @@ -1790,8 +1781,9 @@ void markInitialized(UninitializedType old) { Type newtype = old.initializedType(); - for (int i=0; i results = new HashMap<>(); - private final Map map = new HashMap<>(); + private final Map map = new HashMap<>(); private final Archive NOT_FOUND = new Archive(JdepsTask.getMessage("artifact.not.found")); @@ -69,6 +71,17 @@ * Performs the dependency analysis on the given archives. */ public void run(List archives) { + // build a map from Location to Archive + for (Archive archive: archives) { + for (Location l: archive.getClasses()) { + if (!map.containsKey(l)) { + map.put(l, archive); + } else { + // duplicated class warning? + } + } + } + // traverse and analyze all dependencies for (Archive archive : archives) { ArchiveDeps deps; if (type == Type.CLASS || type == Type.VERBOSE) { @@ -76,33 +89,9 @@ } else { deps = new PackageVisitor(archive); } - archive.visit(deps); + archive.visitDependences(deps); results.put(archive, deps); } - - // set the required dependencies - for (ArchiveDeps result: results.values()) { - for (Set set : result.deps.values()) { - for (String target : set) { - Archive source = getArchive(target); - if (result.archive != source) { - String profile = ""; - if (source instanceof JDKArchive) { - profile = result.profile != null ? result.profile.toString() : ""; - if (result.getTargetProfile(target) == null) { - profile += ", JDK internal API"; - // override the value if it accesses any JDK internal - result.requireArchives.put(source, profile); - continue; - } - } - if (!result.requireArchives.containsKey(source)) { - result.requireArchives.put(source, profile); - } - } - } - } - } } public boolean hasDependences(Archive archive) { @@ -117,94 +106,143 @@ * Visits the source archive to its destination archive of * a recorded dependency. */ - void visitArchiveDependence(Archive origin, Archive target, String profile); + 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 * archive name depending on the Analyzer's type. */ - void visitDependence(String origin, Archive source, String target, Archive archive, String profile); + void visitDependence(String origin, Archive source, String target, Archive archive, Profile profile); } public void visitArchiveDependences(Archive source, Visitor v) { ArchiveDeps r = results.get(source); - for (Map.Entry e : r.requireArchives.entrySet()) { - v.visitArchiveDependence(r.archive, e.getKey(), e.getValue()); + 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 (String origin : r.deps.keySet()) { - for (String target : r.deps.get(origin)) { - Archive archive = getArchive(target); - assert source == getArchive(origin); - Profile profile = r.getTargetProfile(target); - + for (Map.Entry> 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 || archive != source) { - v.visitDependence(origin, source, target, archive, - profile != null ? profile.toString() : ""); + if (type == Type.VERBOSE || d.archive != source) { + v.visitDependence(origin, source, d.target, d.archive, d.profile); } } } } - public Archive getArchive(String name) { - return map.containsKey(name) ? map.get(name) : NOT_FOUND; - } - + /** + * 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 Map requireArchives; - final SortedMap> deps; - Profile profile = null; + final SortedMap> deps; ArchiveDeps(Archive archive) { this.archive = archive; - this.requireArchives = new HashMap<>(); this.deps = new TreeMap<>(); } - void add(String loc) { - Archive a = map.get(loc); - if (a == null) { - map.put(loc, archive); - } else if (a != archive) { - // duplicated class warning? - } - } - - void add(String origin, String target) { - SortedSet set = deps.get(origin); + void add(String origin, String target, Archive targetArchive, String pkgName) { + SortedSet set = deps.get(origin); if (set == null) { deps.put(origin, set = new TreeSet<>()); } - if (!set.contains(target)) { - set.add(target); - // find the corresponding profile - Profile p = getTargetProfile(target); - if (profile == null || (p != null && profile.profile < p.profile)) { - profile = p; + Profile p = targetArchive instanceof JDKArchive + ? Profile.getProfile(pkgName) : null; + set.add(new Dep(target, targetArchive, p)); + } + + /** + * 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 requireArchives() { + Map map = new HashMap<>(); + for (Set 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); + } + } } } + List list = new ArrayList<>(); + for (Map.Entry e: map.entrySet()) { + list.add(new Dep("", e.getKey(), e.getValue())); + } + return list; + } + + /** + * 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 { + 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; + } + + @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; + } + + @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()); + } + } + return this.target.compareTo(o.target); + } } public abstract void visit(Location o, Location t); - public abstract Profile getTargetProfile(String target); } private class ClassVisitor extends ArchiveDeps { ClassVisitor(Archive archive) { super(archive); } - public void visit(Location l) { - add(l.getClassName()); - } + @Override public void visit(Location o, Location t) { - add(o.getClassName(), t.getClassName()); - } - public Profile getTargetProfile(String target) { - int i = target.lastIndexOf('.'); - return (i > 0) ? Profile.getProfile(target.substring(0, i)) : null; + 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()); } } @@ -212,18 +250,21 @@ PackageVisitor(Archive archive) { super(archive); } + @Override public void visit(Location o, Location t) { - add(packageOf(o), packageOf(t)); - } - public void visit(Location l) { - add(packageOf(l)); + Archive targetArchive = + this.archive.getClasses().contains(t) ? this.archive : map.get(t); + if (targetArchive == null) { + map.put(t, targetArchive = NOT_FOUND); + } + + String origin = packageOf(o); + String target = packageOf(t); + add(origin, target, targetArchive, t.getPackageName()); } - private String packageOf(Location loc) { - String pkg = loc.getPackageName(); + public String packageOf(Location o) { + String pkg = o.getPackageName(); return pkg.isEmpty() ? "" : pkg; } - public Profile getTargetProfile(String target) { - return Profile.getProfile(target); - } } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/jdeps/Archive.java --- a/src/share/classes/com/sun/tools/jdeps/Archive.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/jdeps/Archive.java Tue Dec 03 14:13:15 2013 +0400 @@ -67,6 +67,7 @@ deps.put(origin, set); } } + public void addClass(Location origin, Location target) { Set set = deps.get(origin); if (set == null) { @@ -76,21 +77,27 @@ set.add(target); } - public void visit(Visitor v) { + public Set getClasses() { + return deps.keySet(); + } + + public void visitDependences(Visitor v) { for (Map.Entry> e: deps.entrySet()) { - v.visit(e.getKey()); for (Location target : e.getValue()) { v.visit(e.getKey(), target); } } } + public String getPathName() { + return path != null ? path.toString() : filename; + } + public String toString() { - return path != null ? path.toString() : filename; + return filename; } interface Visitor { - void visit(Location loc); void visit(Location origin, Location target); } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/jdeps/JdepsTask.java --- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Tue Dec 03 14:13:15 2013 +0400 @@ -190,6 +190,11 @@ task.options.fullVersion = true; } }, + new HiddenOption(false, "-showlabel") { + void process(JdepsTask task, String opt, String arg) { + task.options.showLabel = true; + } + }, new HiddenOption(true, "-depth") { void process(JdepsTask task, String opt, String arg) throws BadArgs { try { @@ -279,12 +284,21 @@ private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException { Path summary = dir.resolve("summary.dot"); - try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary)); - DotFileFormatter formatter = new DotFileFormatter(sw, "summary")) { - for (Archive archive : sourceLocations) { - analyzer.visitArchiveDependences(archive, formatter); + 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) { for (Archive archive : sourceLocations) { if (analyzer.hasDependences(archive)) { @@ -365,17 +379,16 @@ } } } + sourceLocations.addAll(archives); List classpaths = new ArrayList<>(); // for class file lookup + classpaths.addAll(getClassPathArchives(options.classpath)); if (options.includePattern != null) { - archives.addAll(getClassPathArchives(options.classpath)); - } else { - classpaths.addAll(getClassPathArchives(options.classpath)); + archives.addAll(classpaths); } classpaths.addAll(PlatformClassPath.getArchives()); - // add all archives to the source locations for reporting - sourceLocations.addAll(archives); + // add all classpath archives to the source locations for reporting sourceLocations.addAll(classpaths); // Work queue of names of classfiles to be searched. @@ -557,6 +570,7 @@ boolean showSummary; boolean wildcard; boolean apiOnly; + boolean showLabel; String dotOutputDir; String classpath = ""; int depth = 1; @@ -627,16 +641,34 @@ 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 file name of the archive for non-JRE class or - * internal JRE classes. It returns empty string for SE API. + * Returns the profile name or "JDK internal API" for JDK archive; + * otherwise empty string. */ - private static String getArchiveName(Archive source, String profile) { - String name = source.getFileName(); - if (source instanceof JDKArchive) - return profile.isEmpty() ? "JDK internal API (" + name + ")" : ""; - return name; + 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 { @@ -648,21 +680,18 @@ private String pkg = ""; @Override public void visitDependence(String origin, Archive source, - String target, Archive archive, String profile) { + String target, Archive archive, Profile profile) { if (!origin.equals(pkg)) { pkg = origin; writer.format(" %s (%s)%n", origin, source.getFileName()); } - String name = (options.showProfile && !profile.isEmpty()) - ? profile - : getArchiveName(archive, profile); - writer.format(" -> %-50s %s%n", target, name); + writer.format(" -> %-50s %s%n", target, getProfileArchiveInfo(archive, profile)); } @Override - public void visitArchiveDependence(Archive origin, Archive target, String profile) { - writer.format("%s -> %s", origin, target); - if (options.showProfile && !profile.isEmpty()) { + 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"); @@ -670,19 +699,14 @@ } } - class DotFileFormatter implements Analyzer.Visitor, AutoCloseable { + class DotFileFormatter extends DotGraph implements AutoCloseable { private final PrintWriter writer; private final String name; - DotFileFormatter(PrintWriter writer, String name) { - this.writer = writer; - this.name = name; - writer.format("digraph \"%s\" {%n", name); - } DotFileFormatter(PrintWriter writer, Archive archive) { this.writer = writer; this.name = archive.getFileName(); writer.format("digraph \"%s\" {%n", name); - writer.format(" // Path: %s%n", archive.toString()); + writer.format(" // Path: %s%n", archive.getPathName()); } @Override @@ -690,39 +714,169 @@ writer.println("}"); } - private final Set edges = new HashSet<>(); - private String node = ""; @Override public void visitDependence(String origin, Archive source, - String target, Archive archive, String profile) { - if (!node.equals(origin)) { - edges.clear(); - node = origin; - } + String target, Archive archive, Profile profile) { // if -P option is specified, package name -> profile will // be shown and filter out multiple same edges. - if (!edges.contains(target)) { - StringBuilder sb = new StringBuilder(); - String name = options.showProfile && !profile.isEmpty() - ? profile - : getArchiveName(archive, profile); - writer.format(" %-50s -> %s;%n", - String.format("\"%s\"", origin), - name.isEmpty() ? String.format("\"%s\"", target) - : String.format("\"%s (%s)\"", target, name)); - edges.add(target); + 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(); + } + } + + class DotSummaryForArchive extends DotGraph { + @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)); + } + @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()); + } } } + } + // 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 { + private String packageOf(String cn) { + int i = cn.lastIndexOf('.'); + return i > 0 ? cn.substring(0, i) : ""; + } + @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; + } + + // 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, String profile) { - String name = options.showProfile && !profile.isEmpty() - ? profile : ""; - writer.format(" %-30s -> \"%s\";%n", - String.format("\"%s\"", origin.getFileName()), - name.isEmpty() - ? target.getFileName() - : String.format("%s (%s)", target.getFileName(), name)); + public void visitArchiveDependence(Archive origin, Archive target, Profile profile) { + // nop + } + } + abstract class DotGraph implements Analyzer.Visitor { + private final Set 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)); + } + + Edge addEdge(T origin, T target, String tag) { + Edge e = new Edge(origin, target, tag); + if (e.equals(curEdge)) { + return curEdge; + } + + if (edges.contains(e)) { + for (Edge e1 : edges) { + if (e.equals(e1)) { + curEdge = e1; + } + } + } else { + edges.add(e); + curEdge = e; + } + return curEdge; + } + + Edge findEdge(T origin, T target) { + for (Edge e : edges) { + if (e.from.equals(origin) && e.to.equals(target)) { + return e; + } + } + return null; + } + + String getLabel(Edge e) { + String label = e.label.toString(); + return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label); + } + + 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; + } } } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/com/sun/tools/jdeps/Profile.java --- a/src/share/classes/com/sun/tools/jdeps/Profile.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/com/sun/tools/jdeps/Profile.java Tue Dec 03 14:13:15 2013 +0400 @@ -81,8 +81,12 @@ } static class PackageToProfile { + static String[] JAVAX_CRYPTO_PKGS = new String[] { + "javax.crypto", + "javax.crypto.interfaces", + "javax.crypto.spec" + }; static Map map = initProfiles(); - private static Map initProfiles() { try { String profilesProps = System.getProperty("jdeps.profiles"); @@ -103,6 +107,9 @@ findProfile(cf); } } + // special case for javax.crypto.* classes that are not + // included in ct.sym since they are in jce.jar + Collections.addAll(Profile.COMPACT1.packages, JAVAX_CRYPTO_PKGS); } } } catch (IOException | ConstantPoolException e) { diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java --- a/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/javax/lang/model/util/SimpleTypeVisitor8.java Tue Dec 03 14:13:15 2013 +0400 @@ -27,6 +27,7 @@ import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; +import javax.lang.model.type.IntersectionType; import static javax.lang.model.SourceVersion.*; /** @@ -98,4 +99,17 @@ protected SimpleTypeVisitor8(R defaultValue){ super(defaultValue); } + + /** + * This implementation visits an {@code IntersectionType} by calling + * {@code defaultAction}. + * + * @param t {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override + public R visitIntersection(IntersectionType t, P p){ + return defaultAction(t, p); + } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c src/share/classes/javax/lang/model/util/TypeKindVisitor8.java --- a/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java Sun Nov 03 07:33:31 2013 +0000 +++ b/src/share/classes/javax/lang/model/util/TypeKindVisitor8.java Tue Dec 03 14:13:15 2013 +0400 @@ -101,4 +101,17 @@ protected TypeKindVisitor8(R defaultValue) { super(defaultValue); } + + /** + * This implementation visits an {@code IntersectionType} by calling + * {@code defaultAction}. + * + * @param t {@inheritDoc} + * @param p {@inheritDoc} + * @return the result of {@code defaultAction} + */ + @Override + public R visitIntersection(IntersectionType t, P p) { + return defaultAction(t, p); + } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java --- a/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/com/sun/javadoc/testAnchorNames/TestAnchorNames.java Tue Dec 03 14:13:15 2013 +0400 @@ -23,7 +23,7 @@ /* * @test - * @bug 8025633 + * @bug 8025633 8025524 * @summary Test for valid name attribute in HTML anchors. * @author Bhavesh Patel * @library ../lib/ @@ -196,10 +196,10 @@ //Test nested class {BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html", - "" + "" }, {BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html", - "" + "" }, //Test class use page diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/com/sun/javadoc/testConstructors/TestConstructors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/javadoc/testConstructors/TestConstructors.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025524 + * @summary Test for constructor name which should be a non-qualified name. + * @author Bhavesh Patel + * @library ../lib/ + * @build JavadocTester TestConstructors + * @run main TestConstructors + */ + +public class TestConstructors extends JavadocTester { + + private static final String BUG_ID = "8025524"; + + //Input for string search tests. + private static final String[][] TEST = { + {BUG_ID + FS + "pkg1" + FS + "Outer.html", + "Outer()" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.html", + "Outer(int i)" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "Inner()" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "Inner(int i)" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "NestedInner()" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "NestedInner(int i)" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "" + } + }; + + private static final String[][] NEGATED_TEST = { + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "Outer.Inner--" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html", + "Outer.Inner-int-" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "Outer.Inner.NestedInner--" + }, + {BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html", + "Outer.Inner.NestedInner-int-" + } + }; + + private static final String[] ARGS = new String[] { + "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1" + }; + + /** + * The entry point of the test. + * @param args the array of command line arguments. + */ + public static void main(String[] args) throws Exception { + TestConstructors tester = new TestConstructors(); + run(tester, ARGS, TEST, NEGATED_TEST); + tester.printSummary(); + } + + /** + * {@inheritDoc} + */ + public String getBugId() { + return BUG_ID; + } + + /** + * {@inheritDoc} + */ + public String getBugName() { + return getClass().getName(); + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/com/sun/javadoc/testConstructors/pkg1/Outer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/com/sun/javadoc/testConstructors/pkg1/Outer.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +public class Outer { + + /** + * An outer constructor. + */ + public Outer() { + } + + /** + * Another outer constructor. + */ + public Outer(int i) { + } + + /** + * A nested class. + */ + public class Inner { + + /** + * An inner constructor. + */ + public Inner() { + } + + /** + * Another inner constructor. + */ + public Inner(int i) { + } + + /** + * A nested inner class. + */ + public class NestedInner { + + /** + * A nested inner constructor. + */ + public NestedInner() { + } + + /** + * Another nested inner constructor. + */ + public NestedInner(int i) { + } + } + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ArraysInIntersections.java --- a/test/tools/javac/ArraysInIntersections.java Sun Nov 03 07:33:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8021339 - * @summary Allow arrays in intersection types - * @compile ArraysInIntersections.java - */ - -import java.io.Serializable; - -public class ArraysInIntersections { - - public Object m() { - return (Serializable & Integer[]) new Integer[1]; - } - -} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ExtDirs/ExtDirTest.java --- a/test/tools/javac/ExtDirs/ExtDirTest.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/ExtDirs/ExtDirTest.java Tue Dec 03 14:13:15 2013 +0400 @@ -112,11 +112,6 @@ } void createJars() throws Exception { - -// for i in 1 2 3; do -// if test ! -d ext${i}; then mkdir ext${i}; fi -// cp ${TESTSRC}${FS}ext${i}${FS}*.jar ext${i} -// done sun.tools.jar.Main jarGenerator = new sun.tools.jar.Main(System.out, System.err, "jar"); @@ -155,19 +150,19 @@ void compileWithExtDirs() throws Exception { -//"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext1 "${TESTSRC}${FS}ExtDirTest_1.java" +//javac -extdirs ext1 ExtDirTest_1.java ToolBox.JavaToolArgs params = new ToolBox.JavaToolArgs() .setOptions("-d", ".", "-extdirs", "ext1") .setSources(ExtDirTest_1Src); ToolBox.javac(params); -//"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext1${PS}ext2 "${TESTSRC}${FS}ExtDirTest_2.java" +//javac -extdirs ext1:ext2 ExtDirTest_2.java params.setOptions("-d", ".", "-extdirs", "ext1" + File.pathSeparator + "ext2") .setSources(ExtDirTest_2Src); ToolBox.javac(params); -//"$javac" ${TESTTOOLVMOPTS} -d . -extdirs ext3 "${TESTSRC}${FS}ExtDirTest_3.java" +//javac -extdirs ext3 ExtDirTest_3.java params.setOptions("-d", ".", "-extdirs", "ext3") .setSources(ExtDirTest_3Src); ToolBox.javac(params); diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ExtDirs/ext1/pkg1.jar Binary file test/tools/javac/ExtDirs/ext1/pkg1.jar has changed diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ExtDirs/ext2/pkg2.jar Binary file test/tools/javac/ExtDirs/ext2/pkg2.jar has changed diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ExtDirs/ext3/pkg1.jar Binary file test/tools/javac/ExtDirs/ext3/pkg1.jar has changed diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/ExtDirs/ext3/pkg2.jar Binary file test/tools/javac/ExtDirs/ext3/pkg2.jar has changed diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/InferArraysInIntersections.java --- a/test/tools/javac/InferArraysInIntersections.java Sun Nov 03 07:33:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8021339 - * @summary Allow arrays in intersection types - * @compile -doe -XDrawDiagnostics InferArraysInIntersections.java - */ -import java.util.*; - -class InferArraysInIntersections { - T m(List t) { return null; } - - void test(List lc) { - Runnable r = m(lc); //inference fails here - } -} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/T7042623.java --- a/test/tools/javac/T7042623.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/T7042623.java Tue Dec 03 14:13:15 2013 +0400 @@ -2,7 +2,6 @@ * @test /nodynamiccopyright/ * @bug 7042623 * @summary Regression: javac silently crash when attributing non-existent annotation - * @ignore * @compile/fail/ref=T7042623.out -XDrawDiagnostics -XDdev T7042623.java */ diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/T8019486/WrongLNTForLambdaTest.java --- a/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/T8019486/WrongLNTForLambdaTest.java Tue Dec 03 14:13:15 2013 +0400 @@ -25,7 +25,7 @@ /* * @test - * @bug 8019486 8026861 + * @bug 8019486 8026861 8027142 * @summary javac, generates erroneous LVT for a test case with lambda code * @library /tools/javac/lib * @build ToolBox @@ -68,7 +68,14 @@ /* 22 */ " Runnable r4 = super :: notify;\n" + /* 23 */ " }\n" + /* 24 */ " private void foo() {}\n" + - /* 25 */ "}"; + /* 25 */ " void assignLambda() {\n" + + /* 26 */ " Runnable r = () -> { };\n" + + /* 27 */ " }\n" + + /* 28 */ " void callLambda(int i, Runnable r) {\n" + + /* 29 */ " callLambda(0,\n" + + /* 30 */ " () -> { });\n" + + /* 31 */ " }\n" + + /* 32 */ "}"; static final int[][] simpleLambdaExpectedLNT = { // {line-number, start-pc}, @@ -102,6 +109,18 @@ {22, 0}, //number -> number / 1 }; + static final int[][] assignmentExpectedLNT = { + // {line-number, start-pc}, + {26, 0}, //number -> number / 1 + {27, 6}, //number -> number / 1 + }; + + static final int[][] callExpectedLNT = { + // {line-number, start-pc}, + {29, 0}, //number -> number / 1 + {31, 10}, //number -> number / 1 + }; + public static void main(String[] args) throws Exception { new WrongLNTForLambdaTest().run(); } @@ -120,6 +139,10 @@ "Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT); checkClassFile(new File(Paths.get(System.getProperty("user.dir"), "Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT); + checkClassFile(new File(Paths.get(System.getProperty("user.dir"), + "Foo.class").toUri()), "assignLambda", assignmentExpectedLNT); + checkClassFile(new File(Paths.get(System.getProperty("user.dir"), + "Foo.class").toUri()), "callLambda", callExpectedLNT); } void compileTestClass() throws Exception { diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/T8026963/TypeAnnotationsCrashWithErroneousTreeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8026963/TypeAnnotationsCrashWithErroneousTreeTest.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,10 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8026963 + * @summary type annotations code crashes for lambdas with void argument + * @compile/fail/ref=TypeAnnotationsCrashWithErroneousTreeTest.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW TypeAnnotationsCrashWithErroneousTreeTest.java + */ + +public class TypeAnnotationsCrashWithErroneousTreeTest { + private void t(this) {} +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/T8026963/TypeAnnotationsCrashWithErroneousTreeTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8026963/TypeAnnotationsCrashWithErroneousTreeTest.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,2 @@ +TypeAnnotationsCrashWithErroneousTreeTest.java:9:20: compiler.err.illegal.start.of.type +1 error diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResDeclOutsideTry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResDeclOutsideTry.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,18 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8025113 + * @author sogoel + * @summary Resources cannot be declared outside t-w-r block + * @compile/fail/ref=ResDeclOutsideTry.out -XDrawDiagnostics ResDeclOutsideTry.java + */ + +public class ResDeclOutsideTry implements AutoCloseable { + ResDeclOutsideTry tr1; + ResDeclOutsideTry tr2 = new ResDeclOutsideTry(); + + String test1() { + try (tr1 = new ResDeclOutsideTry(); tr2;) { + } + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResDeclOutsideTry.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResDeclOutsideTry.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,3 @@ +ResDeclOutsideTry.java:14:17: compiler.err.expected: token.identifier +ResDeclOutsideTry.java:14:48: compiler.err.expected: token.identifier +2 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResInNestedExpr.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResInNestedExpr.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025113 + * @author sogoel + * @summary Resource creation in nested expressions + */ + +/** + * This test checks for resource creation in nested expressions. + * test1() - Create 3 resource in nested new expressions, style 1 + * test2() - Create 3 resource in nested new expressions, style 2 + * test3() - Create 4 resources with resources as parameters: new expression; typeid & new expression + */ + +public class ResInNestedExpr { + + static final int expected = 5; + static int closed = 0; + + static void closing(String clazz) { + closed++; + } + + static void checkClosedCount() { + if (expected != closed) { + throw new RuntimeException("Did not find enough closed resources." + + "Expected " + expected + ", but found " + closed); + } + } + /** + * The "expected output" is each class name gotten with getSimpleName() to unclutter things. + * Each test method returns a classname of the resource and that is compared with + * values in this array. + */ + static String[] expectedOutput = { + "aResource::bResource::cResource", //test1 + "aResource::bResource::cResource&aResource::cResource", //test3 + "aResource::bResource::cResource&aResource::cResource"}; //test2 + + static void compare(String s1, String s2) { + if (s1.compareTo(s2) != 0) { + throw new RuntimeException(s1 + "!=" + s2); + } + } + + String test1() { + String ret = null; + try (bResource br = new bResource(new cResource()); + aResource ar = new aResource(br)) { + ret = ar.getClass().getSimpleName() + "::" + + ar.getB().getClass().getSimpleName() + "::" + + ar.getB().getC().getClass().getSimpleName(); + } + return ret; + } + + String test2() { + String ret = null; + try (aResource ar = new aResource(new bResource(new cResource()), new cResource())) { + String abc = ar.getClass().getSimpleName() + "::" + + ar.getB().getClass().getSimpleName() + "::" + + ar.getB().getC().getClass().getSimpleName(); + String ac = ar.getClass().getSimpleName() + "::" + + ar.getC().getClass().getSimpleName(); + ret = abc + "&" + ac; + } + return ret; + } + + String test3() { + String ret = null; + try (bResource br = new bResource(new cResource()); + aResource ar = new aResource(br, new cResource())) { + String abc = ar.getClass().getSimpleName() + "::" + + ar.getB().getClass().getSimpleName() + "::" + + ar.getB().getC().getClass().getSimpleName(); + String ac = ar.getClass().getSimpleName() + "::" + + ar.getC().getClass().getSimpleName(); + ret = abc + "&" + ac; + } + return ret; + } + + public static void main(String... args) { + ResInNestedExpr t = new ResInNestedExpr(); + int eo = 0; + compare(expectedOutput[eo++], t.test1()); + compare(expectedOutput[eo++], t.test3()); + compare(expectedOutput[eo++], t.test2()); + ResInNestedExpr.checkClosedCount(); + } + + /** + * A resource to implement AutoCloseable + * Contains two other resources as data items. + */ + static class aResource implements AutoCloseable { + + bResource bR; + cResource cR; + + public aResource() { + bR = null; + cR = null; + } + + public aResource(bResource br) { + bR = br; + } + + public aResource(cResource cr) { + cR = cr; + } + + public aResource(bResource br, cResource cr) { + bR = br; + cR = cr; + } + + public bResource getB() { + return bR; + } + + public cResource getC() { + return cR; + } + + @Override + public void close() { + ResInNestedExpr.closing(this.getClass().getName()); + } + } + + /** + * A resource to implement AutoCloseable + * Contains one other resources as a data item. + */ + static class bResource implements AutoCloseable { + + cResource cR; + + public bResource() { + cR = null; + } + + public bResource(cResource cr) { + cR = cr; + } + + public cResource getC() { + return cR; + } + + @Override + public void close() { + ResInNestedExpr.closing(this.getClass().getName()); + } + } + + /** A resource to implement AutoCloseable */ + static class cResource implements AutoCloseable { + + public cResource() { + } + + @Override + public void close() { + ResInNestedExpr.closing(this.getClass().getName()); + } + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResourceNameConflict.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResourceNameConflict.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,36 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8025113 + * @author sogoel + * @summary Resource var cannot have same name as local variable + * @compile/fail/ref=ResourceNameConflict.out -XDrawDiagnostics ResourceNameConflict.java + */ + +/** + * Test methods and their description + * test1() - negative test - local variable used as test resource + * test2() - negative test - test resource already defined in an enclosing for statement + */ + +public class ResourceNameConflict implements AutoCloseable { + + static final String str = "asdf"; + + void test1() { + String tr = "A resource spec var cannot have same name as local var."; + try (ResourceNameConflict tr = new ResourceNameConflict()) { + } + } + + void test2(String... strArray) { + for (String str : strArray) { + try (ResourceNameConflict str = new ResourceNameConflict()) { + } + } + } + + @Override + public void close() { + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResourceNameConflict.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResourceNameConflict.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,3 @@ +ResourceNameConflict.java:21:35: compiler.err.already.defined: kindname.variable, tr, kindname.method, test1() +ResourceNameConflict.java:27:39: compiler.err.already.defined: kindname.variable, str, kindname.method, test2(java.lang.String...) +2 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResourceRedecl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResourceRedecl.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,37 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8025113 + * @author sogoel + * @summary Redeclaration of resource variables + * @compile/fail/ref=ResourceRedecl.out -XDrawDiagnostics ResourceRedecl.java + */ + +import java.io.*; + +public class ResourceRedecl { + + public void test() { + // compiler error if name of an exception param is redeclared within the Block of the catch clause as a local var; + // or as an exception param of a catch clause in a try statement; + // or as a resource in a try-with-resources statement + try { + } catch (Exception exParam1) { + Object exParam1 = new Object(); + try (java.io.FileInputStream exParam1 = new java.io.FileInputStream("foo.txt")) { + Object exParam1 = new Object(); + } catch (IOException exParam1) { + } + } + + // compiler error if resource is redeclared within the try Block as a local var + // or as an exception param of a catch clause in a try statement + try (java.io.FileInputStream exParam2 = new java.io.FileInputStream("bar.txt")) { + Object exParam2 = new Object(); + try (BufferedReader br = new BufferedReader(new FileReader("zee.txt"))) { + } catch (IOException exParam2) { + } + } catch (Exception ex) { + } + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResourceRedecl.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResourceRedecl.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,7 @@ +ResourceRedecl.java:19:20: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test() +ResourceRedecl.java:20:42: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test() +ResourceRedecl.java:21:24: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test() +ResourceRedecl.java:22:34: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test() +ResourceRedecl.java:29:20: compiler.err.already.defined: kindname.variable, exParam2, kindname.method, test() +ResourceRedecl.java:31:34: compiler.err.already.defined: kindname.variable, exParam2, kindname.method, test() +6 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/ResourceShadow.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/ResourceShadow.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025113 + * @author sogoel + * @summary Test shadowing of resource variable + */ + +/* + * "...a variable declared in a resource specification + * may be shadowed (6.3.1) anywhere inside a class declaration nested + * within the Block of the try." + */ +public class ResourceShadow { + + static final String str = "asdf"; //this is okay + + /** + * Resource variable shadows switch and case variables + */ + String test1() { + String ret = null; + switch (str) { + case str: //this is okay + try (SilentCloseable str = new SilentCloseable()) { + SilentCloseable tr = new SilentCloseable(str); + ret = str.getClass().getSimpleName(); + } + break; + default: + ret = ""; + } + return ret; + } + + /** + * Resource variable may be shadowed (6.3.1) anywhere inside a class + * declaration nested within the Block of the try + */ + String test2() { + String ret = null; + try (SilentCloseable str = new SilentCloseable()) { + class temp { + + String str = "I am not a SilentCloseable"; + + public void printSTR() { + System.out.println(str); + } + + public String getSTR() { + return str; + } + } + temp tmp = new temp(); + SilentCloseable tr = new SilentCloseable(tmp.getSTR()); + ret = tr.getMsg(); + } + return ret; + } + + public static void main(String... args) { + ResourceShadow t = new ResourceShadow(); + if (t.test1().compareTo("SilentCloseable") != 0) { + throw new RuntimeException("FAIL-test1"); + } + if (t.test2().compareTo("I am not a SilentCloseable") != 0) { + throw new RuntimeException("FAIL-test2"); + } + } +} + +class SilentCloseable implements AutoCloseable { + + SilentCloseable testres = null; + String msg = "default"; + + @Override + public void close() { + } + + public SilentCloseable() { + } + + public SilentCloseable(String s) { + msg = s; + } + + public SilentCloseable(SilentCloseable tr) { + testres = tr; + } + + public String getMsg() { + return msg; + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/TryWithResources/TestTwr09.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/TryWithResources/TestTwr09.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025113 + * @author sogoel + * @summary t-w-r completes abruptly if the initialization of resource completes abruptly + */ + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.File; + +/* + * If the initialization of the resource completes abruptly because of a + * throw of a value V ... and the automatic ->closing of the resource completes normally, + * then the try-with-resources statement completes abruptly because of the throw of value V. + */ +public class TestTwr09 { + + /** + * throw from ctor of nested resource + * Check first resource is not open. + */ + String test1() { + String ret = null; + try (ResCloseable tr = new ResCloseable(new ResCloseable("throw from inner resource ctor",3))) { + ret = "FAIL"; + } catch (RuntimeException re) { + ret = re.getMessage(); + } + return ret; + } + + /** + * throw from ctor of 2nd resource. + * 1st resource, FileInputStream should be automatically closed. + */ + String test2() { + String ret = null; + byte[] buf = new byte[1]; + try (java.io.ByteArrayInputStream tr = new java.io.ByteArrayInputStream(buf); + ResCloseable str = new ResCloseable("throw from inner resource ctor",3)) { + ret = "FAIL"; + } catch (final IOException fe) { + ret = "FAIL test2"; + } catch (RuntimeException re) { + ret = "PASS test2"; + } + System.out.println("Ret = " + ret); + return ret; + } + + public static void main(String... args) { + TestTwr09 t = new TestTwr09(); + if (t.test1().compareTo("throw from inner resource ctor") != 0) { + throw new RuntimeException("FAIL-test1"); + } + if (t.test2().compareTo("PASS test2") != 0) { + throw new RuntimeException("FAIL-test2"); + } + } +} + +/** a simple resource the implements AutoCloseable so it can be used + * in twr's resource specification block. + */ +class ResCloseable implements AutoCloseable { + + ResCloseable testres = null; + String msg = "default"; + boolean bOpen = false; + + public ResCloseable() { + bOpen = true; + } + + public ResCloseable(ResCloseable tr) { + bOpen = true; + msg = tr.getMsg(); + } + + public ResCloseable(String s) { + bOpen = true; + msg = s; + } + + public ResCloseable(String msg, int c) { + bOpen = true; + if (c == 3) { + throw new RuntimeException(msg); + } + } + + @Override + public void close() { + bOpen = false; + } + + public boolean isOpen() { + return bOpen; + } + + public String getMsg() { + return msg; + } +} + diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/annotations/testCrashNestedAnnos/TestCrashNestedAnnos.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/testCrashNestedAnnos/TestCrashNestedAnnos.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,14 @@ +/* @test /nodynamiccopyright/ + * @bug 8027375 + * @summary Test that javac doesn't assert/crash when there are what looks to + * be annotations nested inside erroneous annotations. + * @compile/fail/ref=TestCrashNestedAnnos.out -XDrawDiagnostics TestCrashNestedAnnos.java + */ +public class TestCrashNestedAnnos { + // A and B are not annotation types + @A(@A1()) int foo() {} + @B(@B1()) int bar() {} +} + +class B {} +class B1 {} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/annotations/testCrashNestedAnnos/TestCrashNestedAnnos.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/testCrashNestedAnnos/TestCrashNestedAnnos.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,3 @@ +TestCrashNestedAnnos.java:9:6: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, TestCrashNestedAnnos, null) +TestCrashNestedAnnos.java:10:6: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: B, java.lang.annotation.Annotation) +2 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8027281 + * @summary As per JVMS 4.9.2, invokespecial can only refer to direct superinterfaces + * @compile TestDirectSuperInterfaceInvoke.java + * @run main TestDirectSuperInterfaceInvoke + */ + +import java.io.File; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPool.CPRefInfo; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; +import com.sun.tools.classfile.Opcode; + +interface BaseInterface { + public default int testedMethod(){ return 1; } +} + +interface IntermediateInterface extends BaseInterface { +} + +interface TestInterface extends IntermediateInterface { + public default void test() { + IntermediateInterface.super.testedMethod(); + } +} + +abstract class BaseClass implements BaseInterface { } + +class TestClass extends BaseClass implements BaseInterface { + public int testedMethod() {return 9;} + public void test() { + if (super.testedMethod() != 1) + throw new IllegalStateException(); + if (TestClass.super.testedMethod() != 1) + throw new IllegalStateException(); + new Runnable() { + public void run() { + if (TestClass.super.testedMethod() != 1) + throw new IllegalStateException(); + } + }.run(); + } +} + +public class TestDirectSuperInterfaceInvoke { + public static void main(String... args) throws Exception { + new TestDirectSuperInterfaceInvoke().run(); + } + + public void run() throws Exception { + new TestClass().test(); + verifyDefaultBody("TestClass.class"); + new TestInterface() {}.test(); + verifyDefaultBody("TestInterface.class"); + } + + void verifyDefaultBody(String classFile) { + String workDir = System.getProperty("test.classes"); + File file = new File(workDir, classFile); + try { + final ClassFile cf = ClassFile.read(file); + for (Method m : cf.methods) { + Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); + for (Instruction instr : codeAttr.getInstructions()) { + if (instr.getOpcode() == Opcode.INVOKESPECIAL) { + int pc_index = instr.getShort(1); + CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index); + String className = ref.getClassName(); + if (className.equals("BaseInterface")) + throw new IllegalStateException("Must not directly refer to TestedInterface"); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + file +": " + e); + } + } + +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/diags/examples/InterfaceOrArrayExpected.java --- a/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java Sun Nov 03 07:33:31 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// key: compiler.err.intf.or.array.expected.here - -import java.util.List; - -class InterfaceExpected { } diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/flow/LVTHarness.java --- a/test/tools/javac/flow/LVTHarness.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/flow/LVTHarness.java Tue Dec 03 14:13:15 2013 +0400 @@ -23,8 +23,10 @@ /* * @test - * @bug 7047734 - * @summary The LVT is not generated correctly during some try/catch scenarios + * @bug 7047734 8027660 + * @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 * @library /tools/javac/lib * @build JavacTestingAbstractProcessor LVTHarness * @run main LVTHarness diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class TestCaseLocalInInnerBlock { + + @AliveRange(varName="fm", bytecodeStart=23, bytecodeLength=10) + @AliveRange(varName="newWidth", bytecodeStart=2, bytecodeLength=33) + @AliveRange(varName="tc", bytecodeStart=5, bytecodeLength=30) + int m() { + int newWidth = 0; + String tc = "b"; + if (tc != null) { + String fm; + if (tc.trim() != null) { + } else if ((fm = "b") != null) { + newWidth += fm.length(); + } + } + return newWidth; + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/generics/typevars/6680106/T6680106.out --- a/test/tools/javac/generics/typevars/6680106/T6680106.out Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/generics/typevars/6680106/T6680106.out Tue Dec 03 14:13:15 2013 +0400 @@ -1,7 +1,13 @@ -T6680106.java:11:14: compiler.err.cyclic.inheritance: T -T6680106.java:12:14: compiler.err.cyclic.inheritance: T -T6680106.java:13:14: compiler.err.cyclic.inheritance: T -T6680106.java:14:14: compiler.err.cyclic.inheritance: T -T6680106.java:15:14: compiler.err.cyclic.inheritance: T -T6680106.java:16:14: compiler.err.cyclic.inheritance: T -6 errors +T6680106.java:11:25: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +T6680106.java:12:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) +T6680106.java:12:40: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +T6680106.java:13:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) +T6680106.java:13:40: compiler.err.type.found.req: U[], (compiler.misc.type.req.class) +T6680106.java:13:55: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +T6680106.java:14:30: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +T6680106.java:15:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) +T6680106.java:15:50: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +T6680106.java:16:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) +T6680106.java:16:50: compiler.err.type.found.req: U[], (compiler.misc.type.req.class) +T6680106.java:16:70: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) +12 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference22.java --- a/test/tools/javac/lambda/MethodReference22.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/MethodReference22.java Tue Dec 03 14:13:15 2013 +0400 @@ -48,19 +48,19 @@ } static void test2() { - SAM2 s1 = MethodReference22::m1; //ambiguous - call2(MethodReference22::m1); //ambiguous - SAM2 s2 = MethodReference22::m2; //ambiguous - call2(MethodReference22::m2); //ambiguous - SAM2 s3 = MethodReference22::m3; //ambiguous - call2(MethodReference22::m3); //ambiguous - SAM2 s4 = MethodReference22::m4; //ambiguous - call2(MethodReference22::m4); //ambiguous + SAM2 s1 = MethodReference22::m1; //ok + call2(MethodReference22::m1); //ok + SAM2 s2 = MethodReference22::m2; //ok + call2(MethodReference22::m2); //ok + SAM2 s3 = MethodReference22::m3; //fail + call2(MethodReference22::m3); //fail + SAM2 s4 = MethodReference22::m4; //fail + call2(MethodReference22::m4); //fail } static void test3() { - call3(MethodReference22::m1); //fail - call3(MethodReference22::m2); //ok + call3(MethodReference22::m1); //ok + call3(MethodReference22::m2); //ambiguous call3(MethodReference22::m3); //ok call3(MethodReference22::m4); //fail } diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference22.out --- a/test/tools/javac/lambda/MethodReference22.out Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/MethodReference22.out Tue Dec 03 14:13:15 2013 +0400 @@ -1,19 +1,11 @@ MethodReference22.java:40:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) -MethodReference22.java:41:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) +MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -MethodReference22.java:47:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)) -MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))) -MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)) -MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))) -MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)) -MethodReference22.java:56:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))) +MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) +MethodReference22.java:55:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String)) +MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref)) MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)) -MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) -MethodReference22.java:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)) +MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22 -MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)) -18 errors +MethodReference22.java:65:14: compiler.err.cant.apply.symbol: kindname.method, call3, MethodReference22.SAM2, @1881, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))) +10 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference51.java --- a/test/tools/javac/lambda/MethodReference51.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/MethodReference51.java Tue Dec 03 14:13:15 2013 +0400 @@ -36,11 +36,11 @@ static void test() { - IntSam s1 = MethodReference51::unknown; //method not found - IntSam s2 = MethodReference51::f; //inapplicable method - IntSam s3 = MethodReference51::g; //inapplicable methods - IntegerIntegerSam s4 = MethodReference51::g; //ambiguous - IntSam s5 = MethodReference51::h; //static error - IntSam s6 = MethodReference51.foo::j; //inaccessible method + IntSam s1 = MethodReference51::unknown; //fail + IntSam s2 = MethodReference51::f; //fail + IntSam s3 = MethodReference51::g; //fail + IntegerIntegerSam s4 = MethodReference51::g; //fail + IntSam s5 = MethodReference51::h; //fail + IntSam s6 = MethodReference51.foo::j; //fail } } diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference68.out --- a/test/tools/javac/lambda/MethodReference68.out Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/MethodReference68.out Tue Dec 03 14:13:15 2013 +0400 @@ -1,2 +1,3 @@ MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object) -1 error +MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName()) +2 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference73.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MethodReference73.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,110 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8026231 + * @summary Look at 'static' flag when checking method references + * @compile/fail/ref=MethodReference73.out -XDrawDiagnostics MethodReference73.java + */ + +public class MethodReference73 { + + interface SAM { + void m(MethodReference73 rec, String x); + } + + void m1(MethodReference73 rec, String x) {} + static void m1(MethodReference73 rec, Object x) {} + void m1(String x) {} + + static void m2(MethodReference73 rec, String x) {} + void m2(Object x) {} + static void m2(String x) {} + + static void m3(MethodReference73 rec, String x) {} + void m3(String x) {} + + void m4(MethodReference73 rec, String x) {} + static void m4(MethodReference73 rec, Object x) {} + static void m4(String x) {} + void m4(Object x) {} + + static void m5(MethodReference73 rec, String x) {} + static void m5(String x) {} + + static void m6(MethodReference73 rec, String x) {} + void m6(String x, int i) {} + + void m7(MethodReference73 rec, String x) {} + void m7(String x) {} + + static void m8(MethodReference73 rec, String x, int i) {} + void m8(String x) {} + + void m9(MethodReference73 rec, String x) {} + static void m9(MethodReference73 rec, Object x) {} + static void m9(String x) {} + + void m10(MethodReference73 rec, String x) {} + static void m10(MethodReference73 rec, Object x) {} + void m10(String x, int i) {} + + void m11(MethodReference73 rec, String x) {} + void m11(Object x) {} + static void m11(String x) {} + + static void m12(MethodReference73 rec, String x, int i) {} + void m12(Object x) {} + static void m12(String x) {} + + void m13(MethodReference73 rec, String x) {} + void m13(String x, int i) {} + + static void m14(MethodReference73 rec, String x, int i) {} + static void m14(String x) {} + + void m15(MethodReference73 rec, String x) {} + static void m15(String x) {} + + static void m16(MethodReference73 rec, String x, int i) {} + void m16(String x, int i) {} + + /** For method references with a type selector two searches are performed. + * Each of them may yield one of the following results: + * I) a good match + * II) a bad match more specific than a good match + * III) a bad match with no good matches + * IV) no applicable method found + * + * Whether a match is considered to be good or not depends on the staticness + * of the matched method. The expected result of the first search is a static + * method. The expected result of the second search is an instance method. + * + * If the most specific method has the wrong staticness but there is an + * applicable method with the right staticness then we have the (II) case. + * The (III) case is reserved for those cases when the most specific method + * has the wrong staticness but there is no applicable method with the right + * staticness. + */ + + static void test() { + SAM s1 = MethodReference73::m1; //(II, I) ambiguous + SAM s2 = MethodReference73::m2; //(I, II) ambiguous + SAM s3 = MethodReference73::m3; //(I, I) ambiguous + SAM s4 = MethodReference73::m4; //(II, II) ambiguous + + SAM s5 = MethodReference73::m5; //(I, III) first search's result gets selected + SAM s6 = MethodReference73::m6; //(I, IV) first search's result gets selected + + SAM s7 = MethodReference73::m7; //(III, I) second search's result gets selected + SAM s8 = MethodReference73::m8; //(IV, I) second search's result gets selected + + SAM s9 = MethodReference73::m9; //(II, III) method matched by first search has the wrong staticness + SAM s10 = MethodReference73::m10; //(II, IV) method matched by first search has the wrong staticness + SAM s11 = MethodReference73::m11; //(III, II) method matched by second search has the wrong staticness + SAM s12 = MethodReference73::m12; //(IV, II) method matched by second search has the wrong staticness + SAM s13 = MethodReference73::m13; //(III, IV) method matched by first search has the wrong staticness + SAM s14 = MethodReference73::m14; //(IV, III) method matched by second search has the wrong staticness + SAM s15 = MethodReference73::m15; //(III, III) method matched by first search has the wrong staticness + + SAM s16 = MethodReference73::m16; //(IV, IV) incompatible types, invalid method reference + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/MethodReference73.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MethodReference73.out Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,13 @@ +MethodReference73.java:89:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference73,java.lang.String), MethodReference73, kindname.method, m1(java.lang.String), MethodReference73)) +MethodReference73.java:90:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference73,java.lang.String), MethodReference73, kindname.method, m2(java.lang.String), MethodReference73)) +MethodReference73.java:91:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference73,java.lang.String), MethodReference73, kindname.method, m3(java.lang.String), MethodReference73)) +MethodReference73.java:92:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference73,java.lang.String), MethodReference73, kindname.method, m4(java.lang.String), MethodReference73)) +MethodReference73.java:100:18: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m9(MethodReference73,java.lang.String)) +MethodReference73.java:101:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m10(MethodReference73,java.lang.String)) +MethodReference73.java:102:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m11(java.lang.String)) +MethodReference73.java:103:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String)) +MethodReference73.java:104:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m13(MethodReference73,java.lang.String)) +MethodReference73.java:105:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String)) +MethodReference73.java:106:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m15(MethodReference73,java.lang.String)) +MethodReference73.java:108:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m16, MethodReference73,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(MethodReference73,java.lang.String,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(java.lang.String,int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference73, java.lang.String)))})) +12 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/TargetType60.java --- a/test/tools/javac/lambda/TargetType60.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/TargetType60.java Tue Dec 03 14:13:15 2013 +0400 @@ -57,7 +57,7 @@ static void testUnbound() { TargetType60 s1 = u(TargetType60::n0); //ok - resolves to u(Sam1) - TargetType60 s2 = u(TargetType60::n1); //ambiguous (u(Sam1), u(Sam2) apply) + TargetType60 s2 = u(TargetType60::n1); //ok - resolves to u(Sam2) TargetType60 s3 = u(TargetType60::n2); //none is applicable TargetType60 s4 = u(TargetType60::n01);//ambiguous (u(Sam1), u(Sam2) apply) TargetType60 s5 = u(TargetType60::n012);//ambiguous (u(Sam1), u(Sam2) apply) diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/TargetType60.out --- a/test/tools/javac/lambda/TargetType60.out Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/TargetType60.out Tue Dec 03 14:13:15 2013 +0400 @@ -1,8 +1,6 @@ TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, g(TargetType60.Sam1), TargetType60 TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam1), TargetType60, kindname.method, g(TargetType60.Sam2), TargetType60 -TargetType60.java:60:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 -TargetType60.java:60:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n1(java.lang.String)) -TargetType60.java:61:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n2(TargetType60,java.lang.String)) +TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam1), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, u(TargetType60.Sam2), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, n2, , U,java.lang.String, (compiler.misc.location: kindname.class, TargetType60, null)))))} TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, u(TargetType60.Sam1), TargetType60, kindname.method, u(TargetType60.Sam2), TargetType60 -7 errors +5 errors diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambda/TestInvokeDynamic.java --- a/test/tools/javac/lambda/TestInvokeDynamic.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambda/TestInvokeDynamic.java Tue Dec 03 14:13:15 2013 +0400 @@ -356,7 +356,7 @@ if (lnt == null) { throw new Error("No LineNumberTable attribute"); } - if (lnt.line_number_table_length != 2) { + if (lnt.line_number_table_length != 3) { throw new Error("Wrong number of entries in LineNumberTable"); } } catch (Exception e) { diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Tue Dec 03 14:13:15 2013 +0400 @@ -46,7 +46,7 @@ USECACHE // Keeps results around for reuse. Only use this is // you're sure that each compilation name maps to the // same source code - }; + } private static final AtomicInteger counter = new AtomicInteger(); private static final String targetDir = "gen-separate"; @@ -85,7 +85,7 @@ } public void setFlags(Flags ... flags) { - this.flags = new HashSet(Arrays.asList(flags)); + this.flags = new HashSet<>(Arrays.asList(flags)); } public void addPostprocessor(ClassFilePreprocessor cfp) { @@ -131,17 +131,10 @@ outputDirs.put(type.getName(), outDir); Class superClass = type.getSuperclass(); - if (superClass != null) { - for( Map.Entry each : compileHierarchy(superClass).entrySet()) { - outputDirs.put(each.getKey(), each.getValue()); - } - } - for (Extends ext : type.getSupertypes()) { - Type iface = ext.getType(); - for( Map.Entry each : compileHierarchy(iface).entrySet()) { - outputDirs.put(each.getKey(), each.getValue()); - } - } + if (superClass != null) + outputDirs.putAll(compileHierarchy(superClass)); + for (Extends ext : type.getSupertypes()) + outputDirs.putAll(compileHierarchy(ext.getType())); return outputDirs; } @@ -157,8 +150,12 @@ SourceProcessor accum = (name, src) -> { files.add(new SourceFile(name, src)); }; - for (Type dep : type.typeDependencies()) { - dep.generateAsDependency(accum, type.methodDependencies()); + Collection deps = type.typeDependencies(type.isFullCompilation()); + for (Type dep : deps) { + if (type.isFullCompilation()) + dep.generate(accum); + else + dep.generateAsDependency(accum, type.methodDependencies()); } type.generate(accum); @@ -185,7 +182,7 @@ StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir)); } catch (IOException e) { throw new RuntimeException( - "IOException encountered during compilation"); + "IOException encountered during compilation", e); } Boolean result = ct.call(); if (result == Boolean.FALSE) { diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Tue Dec 03 14:13:15 2013 +0400 @@ -48,7 +48,7 @@ generate(pw); return sw.toString(); } - }; + } public static class AccessFlag extends Element { private String flag; @@ -125,6 +125,7 @@ // (and thus will be present in stubs) private Set methodDependencies; private List typeDependencies; + private boolean fullCompilation; protected Type(String name, List flags, List params, @@ -214,6 +215,14 @@ methodDependencies.add(m); } + public boolean isFullCompilation() { + return fullCompilation; + } + + public void setFullCompilation(boolean fullCompilation) { + this.fullCompilation = fullCompilation; + } + // Convenience method for creating an Extends object using this // class and specified type arguments. public Extends with(String ... args) { @@ -255,14 +264,23 @@ pw.println("}"); } - public Collection typeDependencies() { + public Collection typeDependencies(boolean recursive) { HashMap dependencies = new HashMap<>(); Type superclass = getSuperclass(); if (superclass != null) { dependencies.put(superclass.getName(), superclass); + if (recursive) { + for (Type t : superclass.typeDependencies(true)) + dependencies.put(t.getName(), t); + } } - for (Extends e : getSupertypes()) + for (Extends e : getSupertypes()) { dependencies.put(e.getType().getName(), e.getType()); + if (recursive) { + for (Type t : e.getType().typeDependencies(true)) + dependencies.put(t.getName(), t); + } + } // Do these last so that they override for (Type t : this.typeDependencies) dependencies.put(t.getName(), t); diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Tue Dec 03 14:13:15 2013 +0400 @@ -198,7 +198,7 @@ assertEquals(res, value); } } catch (InvocationTargetException | IllegalAccessException e) { - fail("Unexpected exception thrown: " + e.getCause()); + fail("Unexpected exception thrown: " + e.getCause(), e.getCause()); } } @@ -227,8 +227,7 @@ * a return type of 'int', and no arguments. */ public void assertInvokeVirtualEquals(int value, Class target) { - assertInvokeVirtualEquals( - new Integer(value), target, stdCM, "-1"); + assertInvokeVirtualEquals(value, target, stdCM, "-1"); } /** @@ -260,12 +259,31 @@ Compiler compiler = compilerLocal.get(); compiler.setFlags(compilerFlags()); - assertInvokeInterfaceEquals( - new Integer(value), target, new Extends(iface), stdAM); + assertInvokeInterfaceEquals(value, target, new Extends(iface), stdAM); compiler.cleanup(); } + protected void assertInvokeInterfaceThrows(java.lang.Class errorClass, + Class target, Extends iface, AbstractMethod method, + String... args) { + try { + assertInvokeInterfaceEquals(0, target, iface, method, args); + fail("Expected exception: " + errorClass); + } + catch (AssertionError e) { + Throwable cause = e.getCause(); + if (cause == null) + throw e; + else if ((errorClass.isAssignableFrom(cause.getClass()))) { + // this is success + return; + } + else + throw e; + } + } + /** * Creates a class which calls target::method(args) via invokevirtual, * compiles and loads both the new class and 'target', and then invokes diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Tue Dec 03 14:13:15 2013 +0400 @@ -25,18 +25,22 @@ package org.openjdk.tests.vm; -import java.lang.reflect.*; -import java.util.*; -import java.io.File; -import java.io.IOException; - +import org.openjdk.tests.separate.Compiler; +import org.openjdk.tests.separate.TestHarness; import org.testng.annotations.Test; -import org.openjdk.tests.separate.*; -import org.openjdk.tests.separate.Compiler; -import static org.testng.Assert.*; -import static org.openjdk.tests.separate.SourceModel.*; +import static org.openjdk.tests.separate.SourceModel.AbstractMethod; +import static org.openjdk.tests.separate.SourceModel.AccessFlag; import static org.openjdk.tests.separate.SourceModel.Class; +import static org.openjdk.tests.separate.SourceModel.ConcreteMethod; +import static org.openjdk.tests.separate.SourceModel.DefaultMethod; +import static org.openjdk.tests.separate.SourceModel.Extends; +import static org.openjdk.tests.separate.SourceModel.Interface; +import static org.openjdk.tests.separate.SourceModel.MethodParameter; +import static org.openjdk.tests.separate.SourceModel.TypeParameter; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.fail; @Test(groups = "vm") public class DefaultMethodsTest extends TestHarness { @@ -186,7 +190,7 @@ * TEST: D d = new D(); d.m() == 22; * TEST: I i = new D(); i.m() == 22; */ - void testExistingInheritedOverride() { + public void testExistingInheritedOverride() { Interface I = new Interface("I", DefaultMethod.std("99")); Class C = new Class("C", I, ConcreteMethod.std("11")); Class D = new Class("D", C, ConcreteMethod.std("22")); @@ -258,7 +262,6 @@ * TEST: C c = new C(); c.m() throws ICCE */ public void testConflict() { - // debugTest(); Interface I = new Interface("I", DefaultMethod.std("99")); Interface J = new Interface("J", DefaultMethod.std("88")); Class C = new Class("C", I, J); @@ -390,19 +393,16 @@ /** * interface I { default int m(T t) { return 99; } } - * Class C implements I { public int m() { return 88; } } + * Class C implements I { public int m(String s) { return 88; } } * - * TEST: C c = new C(); c.m() == 88; - * TEST: I i = new C(); i.m() == 88; + * TEST: C c = new C(); c.m("string") == 88; + * TEST: I i = new C(); i.m("string") == 88; */ - @Test(enabled=false) public void testSelfFill() { // This test ensures that a concrete method overrides a default method // that matches at the language-level, but has a different method // signature due to erasure. - // debugTest(); - DefaultMethod dm = new DefaultMethod( "int", "m", "return 99;", new MethodParameter("T", "t")); ConcreteMethod cm = new ConcreteMethod( @@ -415,9 +415,11 @@ AbstractMethod pm = new AbstractMethod( "int", "m", new MethodParameter("T", "t")); - assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\""); - assertInvokeInterfaceEquals( - new Integer(88), C, I.with("String"), pm, "\"string\""); + assertInvokeVirtualEquals(88, C, cm, "-1", "\"string\""); + assertInvokeInterfaceEquals(99, C, I.with("String"), pm, "\"string\""); + + C.setFullCompilation(true); // Force full bridge generation + assertInvokeInterfaceEquals(88, C, I.with("String"), pm, "\"string\""); } /** @@ -485,7 +487,6 @@ * TEST: J j = new C(); j.m("A","B","C") == 88; * TEST: K k = new C(); k.m("A","B","C") == 88; */ - @Test(enabled=false) public void testBridges() { DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", new MethodParameter("T", "t"), new MethodParameter("V", "v"), @@ -518,13 +519,17 @@ J.with("String", "T"), pm2); Class C = new Class("C", K.with("String"), cm); + // First, without compiler bridges String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; - assertInvokeInterfaceEquals(new Integer(88), C, - I.with("String", "String", "String"), pm0, args); - assertInvokeInterfaceEquals(new Integer(88), C, - J.with("String", "String"), pm1, args); - assertInvokeInterfaceEquals(new Integer(88), C, - K.with("String"), pm2, args); + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), pm0, args); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, J.with("String", "String"), pm1, args); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, K.with("String"), pm2, args); + + // Then with compiler bridges + C.setFullCompilation(true); + assertInvokeInterfaceEquals(88, C, I.with("String", "String", "String"), pm0, args); + assertInvokeInterfaceEquals(88, C, J.with("String", "String"), pm1, args); + assertInvokeInterfaceEquals(88, C, K.with("String"), pm2, args); } /** @@ -536,8 +541,6 @@ * TEST: I i = new C(); i.m() == 88; */ public void testSuperBasic() { - // debugTest(); - Interface J = new Interface("J", DefaultMethod.std("88")); Interface I = new Interface("I", J, new DefaultMethod( "int", stdMethodName, "return J.super.m();")); @@ -559,8 +562,6 @@ * TODO: add case for K k = new C(); k.m() throws ICCE */ public void testSuperConflict() { - // debugTest(); - Interface K = new Interface("K", DefaultMethod.std("99")); Interface L = new Interface("L", DefaultMethod.std("101")); Interface J = new Interface("J", K, L); @@ -635,8 +636,7 @@ AbstractMethod pm = new AbstractMethod("int", stdMethodName, new MethodParameter("String", "s")); - assertInvokeInterfaceEquals( - new Integer(88), C, new Extends(I), pm, "\"\""); + assertInvokeInterfaceEquals(88, C, new Extends(I), pm, "\"\""); } /** @@ -674,7 +674,6 @@ * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; * TEST: S s = new S(); s.foo() == new Integer(99) */ - @Test(enabled=false) public void testCovarBridge() { Interface I = new Interface("I", new DefaultMethod( "Integer", "m", "return new Integer(88);")); @@ -692,7 +691,8 @@ S.addCompilationDependency(Dstub); S.addCompilationDependency(DstubMethod); - assertInvokeVirtualEquals(new Integer(99), S, toCall, "null"); + // NEGATIVE test for separate compilation -- dispatches to I, not C + assertInvokeVirtualEquals(88, S, toCall, "null"); } /** @@ -719,7 +719,7 @@ S.addCompilationDependency(Dstub); S.addCompilationDependency(DstubMethod); - assertInvokeVirtualEquals(new Integer(88), S, toCall, "null"); + assertInvokeVirtualEquals(88, S, toCall, "null"); } /** @@ -757,7 +757,6 @@ * Test that a erased-signature-matching method does not implement * non-language-level matching methods */ - @Test(enabled=false) public void testNonConcreteFill() { AbstractMethod ipm = new AbstractMethod("int", "m", new MethodParameter("T", "t"), @@ -781,13 +780,14 @@ new MethodParameter("T", "t"), new MethodParameter("String", "s"), new MethodParameter("String", "w")); + DefaultMethod kdm = new DefaultMethod("int", "m", "return 99;", + new MethodParameter("T", "t"), + new MethodParameter("String", "v"), + new MethodParameter("String", "w")); Interface K = new Interface("K", new TypeParameter("T"), J.with("T", "String"), - new DefaultMethod("int", "m", "return 99;", - new MethodParameter("T", "t"), - new MethodParameter("String", "v"), - new MethodParameter("String", "w"))); + kdm); Class C = new Class("C", K.with("String"), @@ -797,13 +797,18 @@ new MethodParameter("Object", "v"), new MethodParameter("String", "w"))); + // First, without compiler bridges String a = "\"\""; - assertInvokeInterfaceEquals(99, C, - K.with("String"), kpm, a, a, a); - assertInvokeInterfaceEquals(77, C, - J.with("String", "String"), jpm, a, a, a); - assertInvokeInterfaceEquals(99, C, - I.with("String", "String", "String"), ipm, a, a, a); + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); + assertInvokeInterfaceThrows(AbstractMethodError.class, C, I.with("String", "String", "String"), ipm, a, a, a); + + // Now, with bridges + J.setFullCompilation(true); + K.setFullCompilation(true); + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), ipm, a, a, a); } public void testStrictfpDefault() { diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.io.Writer; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.annotation.processing.SupportedOptions; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.TreeScanner; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.util.Assert; + +@SupportedAnnotationTypes("*") +@SupportedOptions("target") +public class Processor extends AbstractProcessor { + + private int round = 0; + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (round++ == 0) { + try (Writer out = processingEnv.getFiler() + .createSourceFile("Anno.java") + .openWriter()) { + String target = processingEnv.getOptions().get("target"); + String code = "import java.lang.annotation.ElementType;\n" + + "import java.lang.annotation.Target;\n" + + "@Target(ElementType." + target + ")\n" + + "@interface Anno { public String value(); }\n"; + out.write(code); + } catch (IOException exc) { + throw new IllegalStateException(exc); + } + } + return true; + } + + public static void main(String... args) throws IOException, URISyntaxException { + if (args.length != 1) throw new IllegalStateException("Must provide class name!"); + String testContent = null; + File testSrc = new File(System.getProperty("test.src")); + File testFile = new File(testSrc, args[0]); + if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source"); + JavacTool compiler = JavacTool.create(); + JavacFileManager fm = compiler.getStandardFileManager(null, null, null); + testContent = fm.getRegularFile(testFile).getCharContent(true).toString(); + JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent); + TestFM testFileManager = new TestFM(fm); + JavacTask task = compiler.getTask(null, + testFileManager, + new DiagnosticCollector(), + null, + null, + Arrays.asList(testFileObject)); + final Trees trees = Trees.instance(task); + final CompilationUnitTree cut = task.parse().iterator().next(); + + final Map annotation2Target = new TreeMap<>(new Comparator() { + @Override public int compare(int[] o1, int[] o2) { + return o2[0] - o1[0]; + } + }); + + new TreeScanner() { + @Override + public Void visitAnnotation(AnnotationTree node, Void p) { + int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node); + + Assert.check(endPos >= 0); + + int startPos = (int) trees.getSourcePositions().getStartPosition(cut, node); + String target = ((LiteralTree) node.getArguments().get(0)).getValue().toString(); + + annotation2Target.put(new int[] {startPos, endPos}, target); + + return super.visitAnnotation(node, p); + } + }.scan(cut.getTypeDecls().get(0), null); + + DiagnosticListener noErrors = new DiagnosticListener() { + @Override public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + throw new IllegalStateException(diagnostic.toString()); + } + } + }; + + for (Entry e : annotation2Target.entrySet()) { + StringBuilder updatedContent = new StringBuilder(); + int last = testContent.length(); + + for (int[] toRemove : annotation2Target.keySet()) { + if (toRemove == e.getKey()) continue; + updatedContent.insert(0, testContent.substring(toRemove[1], last)); + last = toRemove[0]; + } + + updatedContent.insert(0, testContent.substring(0, last)); + + JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]), + updatedContent.toString()); + JavacTask testTask = compiler.getTask(null, + testFileManager, + noErrors, + Arrays.asList("-processor", "Processor", + "-Atarget=" + e.getValue()), + null, + Arrays.asList(updatedFile)); + + try { + testTask.analyze(); + } catch (Throwable exc) { + System.out.println("error while processing:"); + System.out.println(updatedContent); + throw exc; + } + + JavacTask testTask2 = compiler.getTask(null, + testFileManager, + new DiagnosticCollector(), + null, + null, + Arrays.asList(updatedFile)); + + try { + testTask2.analyze(); + } catch (Throwable exc) { + System.out.println("error while processing:"); + System.out.println(updatedContent); + throw exc; + } + } + } + + private static final class TestFO extends SimpleJavaFileObject { + private final String content; + public TestFO(URI uri, String content) { + super(uri, Kind.SOURCE); + this.content = content; + } + + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return content; + } + + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return true; + } + } + + private static final class TestFM extends ForwardingJavaFileManager { + + public TestFM(JavaFileManager fileManager) { + super(fileManager); + } + + @Override + public boolean isSameFile(FileObject a, FileObject b) { + return a.equals(b); + } + + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test /nodynamiccopyright/ + * @bug 8027310 + * @summary Ensure no exceptions on unresolvable annotations + * @build Processor + * @run main Processor Source.java + */ + +import java.util.List; + +@Anno("TYPE") +public class Source { + @Anno("TYPE") + class Inner { + class InnerInner { + public @Anno("CONSTRUCTOR") InnerInner(@Anno("TYPE_USE") Source. @Anno("TYPE_USE") Inner Inner.this, + @Anno("PARAMETER") java.lang. @Anno("TYPE_USE") Runnable p) { + Runnable r = () -> { + @Anno("TYPE_USE") Object tested = null; + @Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String; + }; + + @Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null; + @Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String; + + tested = new java.lang. @Anno("TYPE_USE") Object(); + tested = new @Anno("TYPE_USE") Object(); + } + } + } + + { + Runnable r = () -> { + @Anno("TYPE_USE") Object tested = null; + @Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String; + }; + + @Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null; + @Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String; + + tested = new java.lang. @Anno("TYPE_USE") Object(); + tested = new @Anno("TYPE_USE") Object(); + } + + @Anno("TYPE") + @Anno("ANNOTATION_TYPE") + @interface A { } + abstract class Parameterized<@Anno("TYPE_PARAMETER") T extends @Anno("TYPE_USE") CharSequence & + @Anno("TYPE_USE") Runnable> + implements @Anno("TYPE_USE") List<@Anno("TYPE_USE") Runnable> { } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javac/processing/model/util/TestIntersectionTypeVisitors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/processing/model/util/TestIntersectionTypeVisitors.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8027730 + * @summary Test visitor support for intersection types + */ + +import java.lang.annotation.Annotation; +import java.util.List; +import javax.lang.model.element.*; +import javax.lang.model.type.*; +import javax.lang.model.util.*; + +public class TestIntersectionTypeVisitors { + public static void main(String... args) throws Exception { + IntersectionType it = new TestIntersectionType(); + + boolean result = it.accept(new TypeKindVisitor8Child(), null) && + it.accept(new SimpleTypeVisitor8Child(), null) && + it.accept(new SimpleTypeVisitor6Child(), null); + + if (!result) + throw new RuntimeException(); + } + + static class TestIntersectionType implements IntersectionType { + TestIntersectionType() {} + + @Override + public List getBounds() { + throw new UnsupportedOperationException(); + } + + @Override + public R accept(TypeVisitor v, + P p) { + return v.visitIntersection(this, p); + } + + @Override + public TypeKind getKind() { + return TypeKind.INTERSECTION; + } + + @Override + public A getAnnotation(Class annotationType) { + throw new UnsupportedOperationException(); + } + + @Override + public List getAnnotationMirrors() { + throw new UnsupportedOperationException(); + } + + @Override + public A[] getAnnotationsByType(Class annotationType) { + throw new UnsupportedOperationException(); + } + } + + static class TypeKindVisitor8Child extends TypeKindVisitor8 { + TypeKindVisitor8Child() { + super(false); + } + + @Override + public Boolean visitIntersection(IntersectionType t, Void p) { + super.visitIntersection(t, p); // Make sure overridden method doesn't throw an exception + return true; + } + } + + static class SimpleTypeVisitor8Child extends SimpleTypeVisitor8 { + SimpleTypeVisitor8Child() { + super(false); + } + + @Override + public Boolean visitIntersection(IntersectionType t, Void p) { + super.visitIntersection(t, p); // Make sure overridden method doesn't throw an exception + return true; + } + } + + static class SimpleTypeVisitor6Child extends SimpleTypeVisitor6 { + SimpleTypeVisitor6Child() { + super(false); + } + + @Override + public Boolean visitIntersection(IntersectionType t, Void p) { + try { + super.visitIntersection(t, p); + return false; + } catch (UnknownTypeException ute) { + return true; // Expected + } + } + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javadoc/api/basic/DocumentationToolLocationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javadoc/api/basic/DocumentationToolLocationTest.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8025844 + * @summary test DocumentationTool.Location methods + * @build APITest + * @run main DocumentationToolLocationTest + */ + +import javax.tools.DocumentationTool; +import java.util.Objects; + +/** + * Test for DocumentationTool.Location methods. + */ +public class DocumentationToolLocationTest extends APITest { + public static void main(String[] args) throws Exception { + new DocumentationToolLocationTest().run(); + } + + /** + * Test getName() method + */ + @Test + public void testGetName() throws Exception { + // getName() returns name(). This is for test coverage of getName. + for (DocumentationTool.Location dl: DocumentationTool.Location.values()) { + String expect = dl.name(); + String found = dl.getName(); + if (!Objects.equals(expect, found)) + throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found); + } + } + + /** + * Test generated enum methods values() and valueOf() + */ + @Test + public void testEnumMethods() throws Exception { + DocumentationTool.Location[] values = DocumentationTool.Location.values(); + if (values.length != 3) + throw new Exception("unexpected number of values returned"); + + for (DocumentationTool.Location dl: values) { + DocumentationTool.Location expect = dl; + DocumentationTool.Location found = DocumentationTool.Location.valueOf(dl.name()); + if (!Objects.equals(expect, found)) + throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found); + } + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javadoc/generics/genericInnerAndOuter/expected.out --- a/test/tools/javadoc/generics/genericInnerAndOuter/expected.out Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/javadoc/generics/genericInnerAndOuter/expected.out Tue Dec 03 14:13:15 2013 +0400 @@ -16,7 +16,7 @@ superclass: java.lang.Object constructors: - O.I() + I() methods: void m1(O.I) @@ -36,7 +36,7 @@ superclass: java.lang.Object constructors: - X.Y() + Y() class pkg1.X.Y.Z name: Z / X.Y.Z / pkg1.X.Y.Z @@ -47,7 +47,7 @@ superclass: java.lang.Object constructors: - X.Y.Z() + Z() methods: void m1(X.Y.Z) diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javap/AccessModifiers.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/AccessModifiers.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8027530 + * @summary test -public, -protected, -package, -private options + */ + +import java.io.*; +import java.util.*; +import java.lang.StringBuilder; + +public class AccessModifiers { + public int errorCount; + protected String protectedField; + String packageField; + private String privateField; + + public static void main(String[] args) throws Exception { + new AccessModifiers().run(); + } + + private void run() throws Exception { + List pubMembers = new ArrayList(); + pubMembers.add("public int errorCount"); + pubMembers.add("public AccessModifiers"); + pubMembers.add("public static void main"); + + List proMembers = new ArrayList(); + proMembers.add("protected java.lang.String protectedField"); + proMembers.add("protected java.lang.String runJavap"); + + List pkgMembers = new ArrayList(); + pkgMembers.add("java.lang.String packageField"); + pkgMembers.add("boolean verify"); + pkgMembers.add("void error"); + + List priMembers = new ArrayList(); + priMembers.add("private java.lang.String privateField"); + priMembers.add("private void run() throws java.lang.Exception"); + priMembers.add("private void test"); + + List expectedList = new ArrayList(); + + expectedList.addAll(pubMembers); + test("-public", expectedList); + + expectedList.addAll(proMembers); + test("-protected", expectedList); + + expectedList.addAll(pkgMembers); + test("-package", expectedList); + + expectedList.addAll(priMembers); + test("-private", expectedList); + + if (errorCount > 0) + throw new Exception(errorCount + " errors received"); + } + + private void test(String option, List expectedStrs) throws Exception { + String output = runJavap(0, option); + if (verify(output, expectedStrs)) + System.out.println(option + " test passed"); + } + + protected String runJavap(int expect, String... options) { + // convert the varargs to a list in order to add class name + List optlist = new ArrayList(); + optlist.addAll(Arrays.asList(options)); + optlist.add("AccessModifiers"); + String[] newoptions = optlist.toArray(new String[optlist.size()]); + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + System.out.printf("\nRun javap " + optlist + "\n\n"); + int rc = com.sun.tools.javap.Main.run(newoptions, pw); + pw.close(); + System.out.println(sw); + if (rc != expect) + throw new Error("Expect to return " + expect + ", but return " + rc); + return sw.toString(); + } + + boolean verify(String output, List expects) { + boolean pass = true; + for (String expect: expects) { + if (!output.contains(expect)) { + error(expect + " not found"); + pass = false; + } + } + return pass; + } + + void error(String msg) { + System.err.println(msg); + errorCount++; + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/javap/InvalidOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/InvalidOptions.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8027411 + * @summary test invalid options -h and -b + */ + +import java.io.*; +import java.util.zip.*; + +public class InvalidOptions { + int errorCount; + String log; + + public static void main(String[] args) throws Exception { + new InvalidOptions().run(); + } + + void run() throws Exception { + test(2, "-h", "Error: -h is no longer available - use the javah program"); + test(2, "-b", "Error: unknown option: -b", + "Usage: javap ", + "use -help for a list of possible options"); + if (errorCount > 0) + throw new Exception(errorCount + " errors received"); + } + + void test(int expect, String option, String ... expectedOutput) { + String output = runJavap(expect, option); + verify(output, expectedOutput); + } + + String runJavap(int expect, String... option) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javap.Main.run(option, pw); + pw.close(); + System.out.println("javap prints:"); + System.out.println(sw); + if (rc != expect) + throw new Error("Expect to return " + expect + ", but return " + rc); + return sw.toString(); + } + + void verify(String output, String... expects) { + for (String expect: expects) { + if (!output.contains(expect)) + error(expect + " not found"); + } + } + + void error(String msg) { + System.err.println(msg); + errorCount++; + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/jdeps/Basic.java --- a/test/tools/jdeps/Basic.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/jdeps/Basic.java Tue Dec 03 14:13:15 2013 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,9 @@ /* * @test - * @bug 8003562 8005428 8015912 + * @bug 8003562 8005428 8015912 8027481 * @summary Basic tests for jdeps tool - * @build Test p.Foo + * @build Test p.Foo p.Bar javax.activity.NotCompactProfile * @run main Basic */ @@ -33,10 +33,12 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import java.util.regex.*; +import static java.nio.file.StandardCopyOption.*; public class Basic { private static boolean symbolFileExist = initProfiles(); @@ -74,23 +76,25 @@ 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"}, - new String[] {"compact1", "compact1", "compact3"}); + 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"}, - new String[] {"compact1", "compact1", "not found"}, + 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 -p option test(new File(testDir, "Test.class"), - new String[] {"p.Foo"}, - new String[] {"not found"}, + 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"}, - new String[] {"not found"}, + 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"}, @@ -99,13 +103,34 @@ // test -classpath and -include options test(null, new String[] {"java.lang", "java.util", - "java.lang.management"}, - new String[] {"compact1", "compact1", "compact3"}, + "java.lang.management", "javax.crypto"}, + new String[] {"compact1", "compact1", "compact3", "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"}, - new String[] {"compact1", "compact1", testDir.getName()}, + 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(), "Test.class"}); + + // split package p - move p/Foo.class to dir1 and p/Bar.class to dir2 + Path testClassPath = testDir.toPath(); + Path dirP = testClassPath.resolve("p"); + Path dir1 = testClassPath.resolve("dir1"); + Path subdir1P = dir1.resolve("p"); + Path dir2 = testClassPath.resolve("dir2"); + Path subdir2P = dir2.resolve("p"); + if (!Files.exists(subdir1P)) + Files.createDirectories(subdir1P); + if (!Files.exists(subdir2P)) + Files.createDirectories(subdir2P); + Files.move(dirP.resolve("Foo.class"), subdir1P.resolve("Foo.class"), REPLACE_EXISTING); + Files.move(dirP.resolve("Bar.class"), subdir2P.resolve("Bar.class"), REPLACE_EXISTING); + StringBuilder cpath = new StringBuilder(testDir.toString()); + cpath.append(File.pathSeparator).append(dir1.toString()); + cpath.append(File.pathSeparator).append(dir2.toString()); + test(new File(testDir, "Test.class"), + new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, + new String[] {"compact1", "compact1", dir1.toFile().getName(), dir2.toFile().getName()}, + new String[] {"-v", "-classpath", cpath.toString(), "Test.class"}); return errors; } @@ -148,7 +173,7 @@ // Use the linePattern to break the given String into lines, applying // the pattern to each line to see if we have a match private static Map findDeps(String out) { - Map result = new HashMap<>(); + Map result = new LinkedHashMap<>(); Matcher lm = linePattern.matcher(out); // Line matcher Matcher pm = null; // Pattern matcher int lines = 0; diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/jdeps/Test.java --- a/test/tools/jdeps/Test.java Sun Nov 03 07:33:31 2013 +0000 +++ b/test/tools/jdeps/Test.java Tue Dec 03 14:13:15 2013 +0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ public class Test { public void test() { p.Foo f = new p.Foo(); + p.Bar b = new p.Bar(); } private String name() { return "this test"; diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/jdeps/javax/activity/NotCompactProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/jdeps/javax/activity/NotCompactProfile.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.activity; + +public class NotCompactProfile { + public static String name() { + return "not Java SE API"; + } +} diff -r 53dd31d3c5d7 -r aaea3a69fa6c test/tools/jdeps/p/Bar.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/jdeps/p/Bar.java Tue Dec 03 14:13:15 2013 +0400 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package p; + +public class Bar extends javax.activity.NotCompactProfile { + public String bar() { + return "bar"; + } + public javax.crypto.Cipher getCiper() { + return null; + } +}