# HG changeset patch # User lana # Date 1366125367 25200 # Node ID 1f19b84efa6dfdaefef6e525ba69ef580b905d13 # Parent 2c9acb17f41a67b089c88d904a7955b9071e3ff3# Parent 3f3cc8d3f13c429734afce4cf452c883f6b60863 Merge diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/doclint/Checker.java --- a/src/share/classes/com/sun/tools/doclint/Checker.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclint/Checker.java Tue Apr 16 08:16:07 2013 -0700 @@ -122,12 +122,15 @@ private Deque tagStack; // TODO: maybe want to record starting tree as well private HtmlTag currHeaderTag; + private final int implicitHeaderLevel; + // Checker(Env env) { env.getClass(); this.env = env; tagStack = new LinkedList(); + implicitHeaderLevel = env.implicitHeaderLevel; } public Void scan(DocCommentTree tree, TreePath p) { @@ -386,7 +389,7 @@ private int getHeaderLevel(HtmlTag tag) { if (tag == null) - return 0; + return implicitHeaderLevel; switch (tag) { case H1: return 1; case H2: return 2; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/doclint/DocLint.java --- a/src/share/classes/com/sun/tools/doclint/DocLint.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclint/DocLint.java Tue Apr 16 08:16:07 2013 -0700 @@ -30,6 +30,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import javax.lang.model.element.Name; import javax.tools.StandardLocation; @@ -72,6 +73,7 @@ public static final String XMSGS_OPTION = "-Xmsgs"; public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:"; private static final String STATS = "-stats"; + public static final String XIMPLICIT_HEADERS = "-XimplicitHeaders:"; // public static void main(String... args) { @@ -289,6 +291,9 @@ env.messages.setOptions(null); } else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) { env.messages.setOptions(arg.substring(arg.indexOf(":") + 1)); + } else if (arg.matches(XIMPLICIT_HEADERS + "[1-6]")) { + char ch = arg.charAt(arg.length() - 1); + env.setImplicitHeaders(Character.digit(ch, 10)); } else throw new IllegalArgumentException(arg); } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/doclint/Env.java --- a/src/share/classes/com/sun/tools/doclint/Env.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/doclint/Env.java Tue Apr 16 08:16:07 2013 -0700 @@ -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 @@ -83,6 +83,8 @@ /** Message handler. */ final Messages messages; + int implicitHeaderLevel = 0; + // Utility classes DocTrees trees; Elements elements; @@ -102,7 +104,7 @@ DocCommentTree currDocComment; /** * The access kind of the declaration containing the comment currently being analyzed. - * This is the minimum (most restrictive) access kind of the declaration iteself + * This is the minimum (most restrictive) access kind of the declaration itself * and that of its containers. For example, a public method in a private class is * noted as private. */ @@ -128,6 +130,10 @@ java_lang_Void = elements.getTypeElement("java.lang.Void").asType(); } + void setImplicitHeaders(int n) { + implicitHeaderLevel = n; + } + /** Set the current declaration and its doc comment. */ void setCurrent(TreePath path, DocCommentTree comment) { currPath = path; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/code/Flags.java --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Apr 16 08:16:07 2013 -0700 @@ -314,6 +314,7 @@ modifiers.add(Modifier.SYNCHRONIZED); if (0 != (flags & NATIVE)) modifiers.add(Modifier.NATIVE); if (0 != (flags & STRICTFP)) modifiers.add(Modifier.STRICTFP); + if (0 != (flags & DEFAULT)) modifiers.add(Modifier.DEFAULT); modifiers = Collections.unmodifiableSet(modifiers); modifierSets.put(flags, modifiers); } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Tue Apr 16 08:16:07 2013 -0700 @@ -908,6 +908,12 @@ return interfaces_field.prepend(supertype_field); } + public List getExplicitComponents() { + return allInterfaces ? + interfaces_field : + getComponents(); + } + @Override public TypeKind getKind() { return TypeKind.INTERSECTION; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Apr 16 08:16:07 2013 -0700 @@ -610,7 +610,7 @@ /** * Scope filter used to skip methods that should be ignored (such as methods - * overridden by j.l.Object) during function interface conversion/marker interface checks + * overridden by j.l.Object) during function interface conversion interface check */ class DescriptorFilter implements Filter { @@ -629,64 +629,6 @@ } }; - // - - /** - * A cache that keeps track of marker interfaces - */ - class MarkerCache { - - private WeakHashMap _map = new WeakHashMap(); - - class Entry { - final boolean isMarkerIntf; - final int prevMark; - - public Entry(boolean isMarkerIntf, - int prevMark) { - this.isMarkerIntf = isMarkerIntf; - this.prevMark = prevMark; - } - - boolean matches(int mark) { - return this.prevMark == mark; - } - } - - boolean get(TypeSymbol origin) throws FunctionDescriptorLookupError { - Entry e = _map.get(origin); - CompoundScope members = membersClosure(origin.type, false); - if (e == null || - !e.matches(members.getMark())) { - boolean isMarkerIntf = isMarkerInterfaceInternal(origin, members); - _map.put(origin, new Entry(isMarkerIntf, members.getMark())); - return isMarkerIntf; - } - else { - return e.isMarkerIntf; - } - } - - /** - * Is given symbol a marker interface - */ - public boolean isMarkerInterfaceInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { - return !origin.isInterface() ? - false : - !membersCache.getElements(new DescriptorFilter(origin)).iterator().hasNext(); - } - } - - private MarkerCache markerCache = new MarkerCache(); - - /** - * Is given type a marker interface? - */ - public boolean isMarkerInterface(Type site) { - return markerCache.get(site.tsym); - } - // - // /** * Is t an unchecked subtype of s? @@ -2625,15 +2567,15 @@ public List interfaceCandidates(Type site, MethodSymbol ms) { Filter filter = new MethodFilter(ms, site); List candidates = List.nil(); - for (Symbol s : membersClosure(site, false).getElements(filter)) { - if (!site.tsym.isInterface() && !s.owner.isInterface()) { - return List.of((MethodSymbol)s); - } else if (!candidates.contains(s)) { - candidates = candidates.prepend((MethodSymbol)s); + for (Symbol s : membersClosure(site, false).getElements(filter)) { + if (!site.tsym.isInterface() && !s.owner.isInterface()) { + return List.of((MethodSymbol)s); + } else if (!candidates.contains(s)) { + candidates = candidates.prepend((MethodSymbol)s); + } } + return prune(candidates); } - return prune(candidates); - } public List prune(List methods) { ListBuffer methodsMin = ListBuffer.lb(); diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Apr 16 08:16:07 2013 -0700 @@ -2273,7 +2273,7 @@ Type lambdaType; if (pt() != Type.recoveryType) { - target = checkIntersectionTarget(that, target, resultInfo.checkContext); + target = targetChecker.visit(target, that); lambdaType = types.findDescriptorType(target); chk.checkFunctionalInterface(that, target); } else { @@ -2281,7 +2281,7 @@ lambdaType = fallbackDescriptorType(that); } - setFunctionalInfo(that, pt(), lambdaType, resultInfo.checkContext.inferenceContext()); + setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext()); if (lambdaType.hasTag(FORALL)) { //lambda expression target desc cannot be a generic method @@ -2340,11 +2340,34 @@ new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); localEnv.info.returnResult = bodyResultInfo; - if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { - attribTree(that.getBody(), localEnv, bodyResultInfo); - } else { - JCBlock body = (JCBlock)that.body; - attribStats(body.stats, localEnv); + Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log); + try { + if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { + attribTree(that.getBody(), localEnv, bodyResultInfo); + } else { + JCBlock body = (JCBlock)that.body; + attribStats(body.stats, localEnv); + } + + if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) { + //check for errors in lambda body + for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) { + if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) { + resultInfo.checkContext + .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params))); + //we mark the lambda as erroneous - this is crucial in the recovery step + //as parameter-dependent type error won't be reported in that stage, + //meaning that a lambda will be deemed erroeneous only if there is + //a target-independent error (which will cause method diagnostic + //to be skipped). + result = that.type = types.createErrorType(target); + return; + } + } + } + } finally { + lambdaDeferredHandler.reportDeferredDiagnostics(); + log.popDiagnosticHandler(lambdaDeferredHandler); } result = check(that, target, VAL, resultInfo); @@ -2373,26 +2396,55 @@ } } } - - private Type checkIntersectionTarget(DiagnosticPosition pos, Type pt, CheckContext checkContext) { - if (pt != Type.recoveryType && pt.isCompound()) { - IntersectionClassType ict = (IntersectionClassType)pt; - List bounds = ict.allInterfaces ? - ict.getComponents().tail : - ict.getComponents(); - types.findDescriptorType(bounds.head); //propagate exception outwards! - for (Type bound : bounds.tail) { - if (!types.isMarkerInterface(bound)) { - checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound)); + //where + Types.MapVisitor targetChecker = new Types.MapVisitor() { + + @Override + public Type visitClassType(ClassType t, DiagnosticPosition pos) { + return t.isCompound() ? + visitIntersectionClassType((IntersectionClassType)t, pos) : t; + } + + public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) { + Symbol desc = types.findDescriptorSymbol(makeNotionalInterface(ict)); + Type target = null; + for (Type bound : ict.getExplicitComponents()) { + TypeSymbol boundSym = bound.tsym; + if (types.isFunctionalInterface(boundSym) && + types.findDescriptorSymbol(boundSym) == desc) { + target = bound; + } else if (!boundSym.isInterface() || (boundSym.flags() & ANNOTATION) != 0) { + //bound must be an interface + reportIntersectionError(pos, "not.an.intf.component", boundSym); + } } + return target != null ? + target : + ict.getExplicitComponents().head; //error recovery } - //for now (translation doesn't support intersection types) - return bounds.head; - } else { - return pt; - } - } - //where + + private TypeSymbol makeNotionalInterface(IntersectionClassType ict) { + ListBuffer targs = ListBuffer.lb(); + ListBuffer supertypes = ListBuffer.lb(); + for (Type i : ict.interfaces_field) { + if (i.isParameterized()) { + targs.appendList(i.tsym.type.allparams()); + } + supertypes.append(i.tsym.type); + } + IntersectionClassType notionalIntf = + (IntersectionClassType)types.makeCompoundType(supertypes.toList()); + notionalIntf.allparams_field = targs.toList(); + notionalIntf.tsym.flags_field |= INTERFACE; + return notionalIntf.tsym; + } + + private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) { + resultInfo.checkContext.report(pos, diags.fragment("bad.intersection.target.for.functional.expr", + diags.fragment(key, args))); + } + }; + private Type fallbackDescriptorType(JCExpression tree) { switch (tree.getTag()) { case LAMBDA: @@ -2563,7 +2615,7 @@ Type target; Type desc; if (pt() != Type.recoveryType) { - target = checkIntersectionTarget(that, pt(), resultInfo.checkContext); + target = targetChecker.visit(pt(), that); desc = types.findDescriptorType(target); chk.checkFunctionalInterface(that, target); } else { @@ -2571,11 +2623,12 @@ desc = fallbackDescriptorType(that); } - setFunctionalInfo(that, pt(), desc, resultInfo.checkContext.inferenceContext()); + setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext()); List argtypes = desc.getParameterTypes(); - Pair refResult = rs.resolveMemberReference(that.pos(), localEnv, that, - that.expr.type, that.name, argtypes, typeargtypes, true); + Pair refResult = + rs.resolveMemberReference(that.pos(), localEnv, that, + that.expr.type, that.name, argtypes, typeargtypes, true, rs.resolveMethodCheck); Symbol refSym = refResult.fst; Resolve.ReferenceLookupHelper lookupHelper = refResult.snd; @@ -2765,19 +2818,24 @@ * might contain inference variables, we might need to register an hook in the * current inference context. */ - private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) { + private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, + final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) { if (inferenceContext.free(descriptorType)) { inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { public void typesInferred(InferenceContext inferenceContext) { - setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext); + setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), + inferenceContext.asInstType(primaryTarget), inferenceContext); } }); } else { ListBuffer targets = ListBuffer.lb(); if (pt.hasTag(CLASS)) { if (pt.isCompound()) { + targets.append(primaryTarget.tsym); //this goes first for (Type t : ((IntersectionClassType)pt()).interfaces_field) { - targets.append(t.tsym); + if (t != primaryTarget) { + targets.append(t.tsym); + } } } else { targets.append(pt.tsym); diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Apr 16 08:16:07 2013 -0700 @@ -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 @@ -28,6 +28,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.comp.Attr.ResultInfo; @@ -531,12 +532,13 @@ attr.memberReferenceQualifierResult(tree)); ListBuffer argtypes = ListBuffer.lb(); for (Type t : types.findDescriptorType(pt).getParameterTypes()) { - argtypes.append(syms.errType); + argtypes.append(Type.noType); } JCMemberReference mref2 = new TreeCopier(make).copy(tree); mref2.expr = exprTree; Pair lookupRes = - rs.resolveMemberReference(tree, env, mref2, exprTree.type, tree.name, argtypes.toList(), null, true); + rs.resolveMemberReference(tree, env, mref2, exprTree.type, + tree.name, argtypes.toList(), null, true, rs.arityMethodCheck); switch (lookupRes.fst.kind) { //note: as argtypes are erroneous types, type-errors must //have been caused by arity mismatch diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Apr 16 08:16:07 2013 -0700 @@ -143,7 +143,6 @@ boolean allowBoxing, boolean useVarargs, Resolve.MethodResolutionContext resolveContext, - Resolve.MethodCheck methodCheck, Warner warn) throws InferenceException { //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG final InferenceContext inferenceContext = new InferenceContext(tvars); @@ -152,7 +151,7 @@ DeferredAttr.DeferredAttrContext deferredAttrContext = resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn); - methodCheck.argumentsAcceptable(env, deferredAttrContext, + resolveContext.methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn); if (allowGraphInference && diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Apr 16 08:16:07 2013 -0700 @@ -384,18 +384,6 @@ Symbol translatedSym = lambdaContext.getSymbolMap(CAPTURED_VAR).get(tree.sym); result = make.Ident(translatedSym).setType(tree.type); } else { - if (tree.sym.owner.kind == Kinds.TYP) { - for (Map.Entry encl_entry : lambdaContext.getSymbolMap(CAPTURED_THIS).entrySet()) { - if (tree.sym.isMemberOf((ClassSymbol) encl_entry.getKey(), types)) { - JCExpression enclRef = make.Ident(encl_entry.getValue()); - result = tree.sym.name == names._this - ? enclRef.setType(tree.type) - : make.Select(enclRef, tree.sym).setType(tree.type); - result = tree; - return; - } - } - } //access to untranslated symbols (i.e. compile-time constants, //members defined inside the lambda body, etc.) ) super.visitIdent(tree); @@ -1315,6 +1303,7 @@ // the generated lambda method will not have type yet, but the // enclosing method's name will have been generated with this same // method, so it will be unique and never be overloaded. + Assert.check(owner.type != null || directlyEnclosingLambda() != null); if (owner.type != null) { int methTypeHash = methodSig(owner.type).hashCode(); buf.append(Integer.toHexString(methTypeHash)); diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Apr 16 08:16:07 2013 -0700 @@ -508,7 +508,6 @@ List typeargtypes, boolean allowBoxing, boolean useVarargs, - MethodCheck methodCheck, Warner warn) throws Infer.InferenceException { Type mt = types.memberType(site, m); @@ -561,10 +560,9 @@ allowBoxing, useVarargs, currentResolutionContext, - methodCheck, warn); - methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn), + currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn), argtypes, mt.getParameterTypes(), warn); return mt; } @@ -582,7 +580,7 @@ currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK; MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase; return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, - step.isBoxingRequired(), step.isVarargsRequired(), resolveMethodCheck, warn); + step.isBoxingRequired(), step.isVarargsRequired(), warn); } finally { currentResolutionContext = prevContext; @@ -599,11 +597,10 @@ List typeargtypes, boolean allowBoxing, boolean useVarargs, - MethodCheck methodCheck, Warner warn) { try { return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes, - allowBoxing, useVarargs, methodCheck, warn); + allowBoxing, useVarargs, warn); } catch (InapplicableMethodException ex) { return null; } @@ -628,6 +625,12 @@ List argtypes, List formals, Warner warn); + + /** + * Retrieve the method check object that will be used during a + * most specific check. + */ + MethodCheck mostSpecificCheck(List actuals, boolean strict); } /** @@ -661,24 +664,25 @@ } /** - * Main method applicability routine. Given a list of actual types A, - * a list of formal types F, determines whether the types in A are - * compatible (by method invocation conversion) with the types in F. - * - * Since this routine is shared between overload resolution and method - * type-inference, a (possibly empty) inference context is used to convert - * formal types to the corresponding 'undet' form ahead of a compatibility - * check so that constraints can be propagated and collected. - * - * Moreover, if one or more types in A is a deferred type, this routine uses - * DeferredAttr in order to perform deferred attribution. If one or more actual - * deferred types are stuck, they are placed in a queue and revisited later - * after the remainder of the arguments have been seen. If this is not sufficient - * to 'unstuck' the argument, a cyclic inference error is called out. - * - * A method check handler (see above) is used in order to report errors. + * Dummy method check object. All methods are deemed applicable, regardless + * of their formal parameter types. */ - MethodCheck resolveMethodCheck = new MethodCheck() { + MethodCheck nilMethodCheck = new MethodCheck() { + public void argumentsAcceptable(Env env, DeferredAttrContext deferredAttrContext, List argtypes, List formals, Warner warn) { + //do nothing - method always applicable regardless of actuals + } + + public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + return this; + } + }; + + /** + * Base class for 'real' method checks. The class defines the logic for + * iterating through formals and actuals and provides and entry point + * that can be used by subclasses in order to define the actual check logic. + */ + abstract class AbstractMethodCheck implements MethodCheck { @Override public void argumentsAcceptable(final Env env, DeferredAttrContext deferredAttrContext, @@ -699,8 +703,7 @@ } while (argtypes.nonEmpty() && formals.head != varargsFormal) { - ResultInfo mresult = methodCheckResult(false, formals.head, deferredAttrContext, warn); - mresult.check(null, argtypes.head); + checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn); argtypes = argtypes.tail; formals = formals.tail; } @@ -713,17 +716,19 @@ //note: if applicability check is triggered by most specific test, //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) final Type elt = types.elemtype(varargsFormal); - ResultInfo mresult = methodCheckResult(true, elt, deferredAttrContext, warn); while (argtypes.nonEmpty()) { - mresult.check(null, argtypes.head); + checkArg(true, argtypes.head, elt, deferredAttrContext, warn); argtypes = argtypes.tail; } - //check varargs element type accessibility - varargsAccessible(env, elt, inferenceContext); } } - private void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { + /** + * Does the actual argument conforms to the corresponding formal? + */ + abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); + + protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { boolean inferDiag = inferenceContext != infer.emptyContext; InapplicableMethodException ex = inferDiag ? infer.inferenceException : inapplicableMethodException; @@ -736,6 +741,63 @@ throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args); } + public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + return nilMethodCheck; + } + } + + /** + * Arity-based method check. A method is applicable if the number of actuals + * supplied conforms to the method signature. + */ + MethodCheck arityMethodCheck = new AbstractMethodCheck() { + @Override + void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { + //do nothing - actual always compatible to formals + } + }; + + /** + * Main method applicability routine. Given a list of actual types A, + * a list of formal types F, determines whether the types in A are + * compatible (by method invocation conversion) with the types in F. + * + * Since this routine is shared between overload resolution and method + * type-inference, a (possibly empty) inference context is used to convert + * formal types to the corresponding 'undet' form ahead of a compatibility + * check so that constraints can be propagated and collected. + * + * Moreover, if one or more types in A is a deferred type, this routine uses + * DeferredAttr in order to perform deferred attribution. If one or more actual + * deferred types are stuck, they are placed in a queue and revisited later + * after the remainder of the arguments have been seen. If this is not sufficient + * to 'unstuck' the argument, a cyclic inference error is called out. + * + * A method check handler (see above) is used in order to report errors. + */ + MethodCheck resolveMethodCheck = new AbstractMethodCheck() { + + @Override + void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { + ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); + mresult.check(null, actual); + } + + @Override + public void argumentsAcceptable(final Env env, + DeferredAttrContext deferredAttrContext, + List argtypes, + List formals, + Warner warn) { + super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn); + //should we expand formals? + if (deferredAttrContext.phase.isVarargsRequired()) { + //check varargs element type accessibility + varargsAccessible(env, types.elemtype(formals.last()), + deferredAttrContext.inferenceContext); + } + } + private void varargsAccessible(final Env env, final Type t, final InferenceContext inferenceContext) { if (inferenceContext.free(t)) { inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() { @@ -765,6 +827,11 @@ }; return new MethodResultInfo(to, checkContext); } + + @Override + public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + return new MostSpecificCheck(strict, actuals); + } }; /** @@ -1042,6 +1109,11 @@ } } } + + public MethodCheck mostSpecificCheck(List actuals, boolean strict) { + Assert.error("Cannot get here!"); + return null; + } } public static class InapplicableMethodException extends RuntimeException { @@ -1254,7 +1326,7 @@ Assert.check(sym.kind < AMBIGUOUS); try { Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, - allowBoxing, useVarargs, resolveMethodCheck, types.noWarnings); + allowBoxing, useVarargs, types.noWarnings); if (!operator) currentResolutionContext.addApplicableCandidate(sym, mt); } catch (InapplicableMethodException ex) { @@ -1358,11 +1430,20 @@ int maxLength = Math.max( Math.max(m1.type.getParameterTypes().length(), actuals.length()), m2.type.getParameterTypes().length()); - Type mst = instantiate(env, site, m2, null, - adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, - allowBoxing, useVarargs, new MostSpecificCheck(!allowBoxing, actuals), noteWarner); - return mst != null && - !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = new MethodResolutionContext(); + currentResolutionContext.step = prevResolutionContext.step; + currentResolutionContext.methodCheck = + prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing); + Type mst = instantiate(env, site, m2, null, + adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null, + allowBoxing, useVarargs, noteWarner); + return mst != null && + !noteWarner.hasLint(Lint.LintCategory.UNCHECKED); + } finally { + currentResolutionContext = prevResolutionContext; + } } private List adjustArgs(List args, Symbol msym, int length, boolean allowVarargs) { if ((msym.flags() & VARARGS) != 0 && allowVarargs) { @@ -2124,14 +2205,14 @@ Name name, List argtypes, List typeargtypes) { - return lookupMethod(env, pos, env.enclClass.sym, new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { - @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { - return findFun(env, name, argtypes, typeargtypes, - phase.isBoxingRequired(), - phase.isVarargsRequired()); - } - }); + return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck, + new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { + @Override + Symbol lookup(Env env, MethodResolutionPhase phase) { + return findFun(env, name, argtypes, typeargtypes, + phase.isBoxingRequired(), + phase.isVarargsRequired()); + }}); } /** Resolve a qualified method identifier @@ -2313,36 +2394,36 @@ Type site, List argtypes, List typeargtypes) { - return lookupMethod(env, pos, site.tsym, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { - @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { - return findDiamond(env, site, argtypes, typeargtypes, - phase.isBoxingRequired(), - phase.isVarargsRequired()); - } - @Override - Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { - if (sym.kind >= AMBIGUOUS) { - final JCDiagnostic details = sym.kind == WRONG_MTH ? - ((InapplicableSymbolError)sym).errCandidate().details : - null; - sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, - Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - String key = details == null ? - "cant.apply.diamond" : - "cant.apply.diamond.1"; - return diags.create(dkind, log.currentSource(), pos, key, - diags.fragment("diamond", site.tsym), details); + return lookupMethod(env, pos, site.tsym, resolveMethodCheck, + new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { + @Override + Symbol lookup(Env env, MethodResolutionPhase phase) { + return findDiamond(env, site, argtypes, typeargtypes, + phase.isBoxingRequired(), + phase.isVarargsRequired()); + } + @Override + Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { + if (sym.kind >= AMBIGUOUS) { + final JCDiagnostic details = sym.kind == WRONG_MTH ? + ((InapplicableSymbolError)sym).errCandidate().details : + null; + sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { + @Override + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, + Symbol location, Type site, Name name, List argtypes, List typeargtypes) { + String key = details == null ? + "cant.apply.diamond" : + "cant.apply.diamond.1"; + return diags.create(dkind, log.currentSource(), pos, key, + diags.fragment("diamond", site.tsym), details); + } + }; + sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); + env.info.pendingResolutionPhase = currentResolutionContext.step; } - }; - sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); - env.info.pendingResolutionPhase = currentResolutionContext.step; - } - return sym; - } - }); + return sym; + }}); } /** This method scans all the constructor symbol in a given class scope - @@ -2475,7 +2556,8 @@ Type site, Name name, List argtypes, List typeargtypes, - boolean boxingAllowed) { + boolean boxingAllowed, + MethodCheck methodCheck) { MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; ReferenceLookupHelper boundLookupHelper; @@ -2495,12 +2577,12 @@ //step 1 - bound lookup Env boundEnv = env.dup(env.tree, env.info.dup()); - Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper); + Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper); //step 2 - unbound lookup ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(); Env unboundEnv = env.dup(env.tree, env.info.dup()); - Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundLookupHelper); + Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper); //merge results Pair res; @@ -2671,7 +2753,7 @@ ReferenceLookupHelper unboundLookup() { if (TreeInfo.isStaticSelector(referenceTree.expr, names) && argtypes.nonEmpty() && - types.isSubtypeUnchecked(argtypes.head, site)) { + (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) { return new UnboundMethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); } else { @@ -2704,8 +2786,8 @@ UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) { super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase); - Type asSuperSite = types.asSuper(argtypes.head, site.tsym); - if (site.isRaw() && !asSuperSite.isErroneous()) { + if (site.isRaw() && !argtypes.head.hasTag(NONE)) { + Type asSuperSite = types.asSuper(argtypes.head, site.tsym); this.site = asSuperSite; } } @@ -2800,8 +2882,10 @@ * at the end of the lookup, the helper is used to validate the results * (this last step might trigger overload resolution diagnostics). */ - Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol location, LookupHelper lookupHelper) { - return lookupMethod(env, pos, location, new MethodResolutionContext(), lookupHelper); + Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) { + MethodResolutionContext resolveContext = new MethodResolutionContext(); + resolveContext.methodCheck = methodCheck; + return lookupMethod(env, pos, location, resolveContext, lookupHelper); } Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol location, @@ -3595,6 +3679,8 @@ MethodResolutionPhase step = null; + MethodCheck methodCheck = resolveMethodCheck; + private boolean internalResolution = false; private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/jvm/Code.java --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Apr 16 08:16:07 2013 -0700 @@ -373,6 +373,17 @@ Assert.check(alive || state.stacksize == 0); } + /** Emit a ldc (or ldc_w) instruction, taking into account operand size + */ + public void emitLdc(int od) { + if (od <= 255) { + emitop1(ldc1, od); + } + else { + emitop2(ldc2, od); + } + } + /** Emit a multinewarray instruction. */ public void emitMultianewarray(int ndims, int type, Type arrayType) { @@ -459,7 +470,15 @@ public void emitInvokedynamic(int desc, Type mtype) { // N.B. this format is under consideration by the JSR 292 EG int argsize = width(mtype.getParameterTypes()); - emitop(invokedynamic); + 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; + } if (!alive) return; emit2(desc); emit2(0); diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Apr 16 08:16:07 2013 -0700 @@ -1748,10 +1748,13 @@ // Generate code for all arguments, where the expected types are // the parameters of the method's external type (that is, any implicit // outer instance of a super(...) call appears as first parameter). + MethodSymbol msym = (MethodSymbol)TreeInfo.symbol(tree.meth); genArgs(tree.args, - TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes()); - code.statBegin(tree.pos); - code.markStatBegin(); + msym.externalType(types).getParameterTypes()); + if (!msym.isDynamic()) { + code.statBegin(tree.pos); + code.markStatBegin(); + } result = m.invoke(); } @@ -2227,7 +2230,7 @@ if (tree.name == names._class) { Assert.check(target.hasClassLiterals()); - code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type)); + code.emitLdc(makeRef(tree.pos(), tree.selected.type)); result = items.makeStackItem(pt); return; } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/jvm/Items.java --- a/src/share/classes/com/sun/tools/javac/jvm/Items.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Items.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -571,10 +571,8 @@ int idx = pool.put(value); if (typecode == LONGcode || typecode == DOUBLEcode) { code.emitop2(ldc2w, idx); - } else if (idx <= 255) { - code.emitop1(ldc1, idx); } else { - code.emitop2(ldc2, idx); + code.emitLdc(idx); } } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/main/Main.java --- a/src/share/classes/com/sun/tools/javac/main/Main.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -497,6 +497,8 @@ if (!(doclintOpts.size() == 1 && doclintOpts.iterator().next().equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) { JavacTask t = BasicJavacTask.instance(context); + // standard doclet normally generates H1, H2 + doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); new DocLint().init(t, doclintOpts.toArray(new String[doclintOpts.size()])); comp.keepComments = true; } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java --- a/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -770,7 +770,7 @@ * (which is treated as the beginning of the first line). * Stops positioned at the closing '/'. */ - protected class BasicComment implements Comment { + protected static class BasicComment implements Comment { CommentStyle cs; U comment_reader; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Apr 16 08:16:07 2013 -0700 @@ -171,8 +171,8 @@ protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { return keepEndPositions - ? new SimpleEndPosTable() - : new EmptyEndPosTable(); + ? new SimpleEndPosTable(this) + : new EmptyEndPosTable(this); } protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) { @@ -3088,6 +3088,7 @@ toplevel.docComments = docComments; if (keepLineMap) toplevel.lineMap = S.getLineMap(); + this.endPosTable.setParser(null); // remove reference to parser toplevel.endPositions = this.endPosTable; return toplevel; } @@ -4003,11 +4004,12 @@ /* * a functional source tree and end position mappings */ - protected class SimpleEndPosTable extends AbstractEndPosTable { + protected static class SimpleEndPosTable extends AbstractEndPosTable { private final Map endPosMap; - SimpleEndPosTable() { + SimpleEndPosTable(JavacParser parser) { + super(parser); endPosMap = new HashMap(); } @@ -4016,12 +4018,12 @@ } protected T to(T t) { - storeEnd(t, token.endPos); + storeEnd(t, parser.token.endPos); return t; } protected T toP(T t) { - storeEnd(t, S.prevToken().endPos); + storeEnd(t, parser.S.prevToken().endPos); return t; } @@ -4043,7 +4045,11 @@ /* * a default skeletal implementation without any mapping overhead. */ - protected class EmptyEndPosTable extends AbstractEndPosTable { + protected static class EmptyEndPosTable extends AbstractEndPosTable { + + EmptyEndPosTable(JavacParser parser) { + super(parser); + } protected void storeEnd(JCTree tree, int endpos) { /* empty */ } @@ -4065,13 +4071,21 @@ } - protected abstract class AbstractEndPosTable implements EndPosTable { + protected static abstract class AbstractEndPosTable implements EndPosTable { + /** + * The current parser. + */ + protected JavacParser parser; /** * Store the last error position. */ protected int errorEndPos; + public AbstractEndPosTable(JavacParser parser) { + this.parser = parser; + } + /** * Store ending position for a tree, the value of which is the greater * of last error position and the given ending position. @@ -4106,5 +4120,9 @@ errorEndPos = errPos; } } + + protected void setParser(JavacParser parser) { + this.parser = parser; + } } } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java --- a/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java Tue Apr 16 08:16:07 2013 -0700 @@ -206,7 +206,7 @@ } } - protected class JavadocComment extends JavaTokenizer.BasicComment { + protected static class JavadocComment extends JavaTokenizer.BasicComment { /** * Translated and stripped contents of doc comment diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Apr 16 08:16:07 2013 -0700 @@ -216,9 +216,14 @@ compiler.misc.no.suitable.functional.intf.inst=\ cannot infer functional interface descriptor for {0} +# 0: message segment +compiler.misc.bad.intersection.target.for.functional.expr=\ + bad intersection type target for lambda or method reference\n\ + {0} + # 0: type -compiler.misc.secondary.bound.must.be.marker.intf=\ - secondary bound {0} must be a marker interface +compiler.misc.not.an.intf.component=\ + component type {0} is not an interface # 0: symbol kind, 1: message segment compiler.err.invalid.mref=\ @@ -731,6 +736,11 @@ compiler.misc.incompatible.arg.types.in.mref=\ incompatible parameter types in method reference +# 0: list of type +compiler.misc.bad.arg.types.in.lambda=\ + cannot type-check lambda expression with inferred parameter types\n\ + inferred types: {0} + compiler.err.new.not.allowed.in.annotation=\ ''new'' not allowed in an annotation diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/util/BaseFileManager.java --- a/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -112,9 +112,8 @@ protected ClassLoader getClassLoader(URL[] urls) { ClassLoader thisClassLoader = getClass().getClassLoader(); - // Bug: 6558476 - // Ideally, ClassLoader should be Closeable, but before JDK7 it is not. - // On older versions, try the following, to get a closeable classloader. + // Allow the following to specify a closeable classloader + // other than URLClassLoader. // 1: Allow client to specify the class to use via hidden option if (classLoaderClass != null) { @@ -128,19 +127,6 @@ // ignore errors loading user-provided class loader, fall through } } - - // 2: If URLClassLoader implements Closeable, use that. - if (Closeable.class.isAssignableFrom(URLClassLoader.class)) - return new URLClassLoader(urls, thisClassLoader); - - // 3: Try using private reflection-based CloseableURLClassLoader - try { - return new CloseableURLClassLoader(urls, thisClassLoader); - } catch (Throwable t) { - // ignore errors loading workaround class loader, fall through - } - - // 4: If all else fails, use plain old standard URLClassLoader return new URLClassLoader(urls, thisClassLoader); } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java --- a/src/share/classes/com/sun/tools/javac/util/CloseableURLClassLoader.java Thu Apr 11 09:40:22 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.tools.javac.util; - -import java.io.Closeable; -import java.io.IOException; -import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.jar.JarFile; - -/** - * A URLClassLoader that also implements Closeable. - * Reflection is used to access internal data structures in the URLClassLoader, - * since no public API exists for this purpose. Therefore this code is somewhat - * fragile. Caveat emptor. - * @throws Error if the internal data structures are not as expected. - * - *

This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. - */ -public class CloseableURLClassLoader - extends URLClassLoader implements Closeable { - public CloseableURLClassLoader(URL[] urls, ClassLoader parent) throws Error { - super(urls, parent); - try { - getLoaders(); //proactive check that URLClassLoader is as expected - } catch (Throwable t) { - throw new Error("cannot create CloseableURLClassLoader", t); - } - } - - /** - * Close any jar files that may have been opened by the class loader. - * Reflection is used to access the jar files in the URLClassLoader's - * internal data structures. - * @throws java.io.IOException if the jar files cannot be found for any - * reson, or if closing the jar file itself causes an IOException. - */ - @Override - public void close() throws IOException { - try { - for (Object l: getLoaders()) { - if (l.getClass().getName().equals("sun.misc.URLClassPath$JarLoader")) { - Field jarField = l.getClass().getDeclaredField("jar"); - JarFile jar = (JarFile) getField(l, jarField); - if (jar != null) { - //System.err.println("CloseableURLClassLoader: closing " + jar); - jar.close(); - } - } - } - } catch (Throwable t) { - IOException e = new IOException("cannot close class loader"); - e.initCause(t); - throw e; - } - } - - private ArrayList getLoaders() - throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException - { - Field ucpField = URLClassLoader.class.getDeclaredField("ucp"); - Object urlClassPath = getField(this, ucpField); - if (urlClassPath == null) - throw new AssertionError("urlClassPath not set in URLClassLoader"); - Field loadersField = urlClassPath.getClass().getDeclaredField("loaders"); - return (ArrayList) getField(urlClassPath, loadersField); - } - - private Object getField(Object o, Field f) - throws IllegalArgumentException, IllegalAccessException { - boolean prev = f.isAccessible(); - try { - f.setAccessible(true); - return f.get(o); - } finally { - f.setAccessible(prev); - } - } - -} diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/util/Pair.java --- a/src/share/classes/com/sun/tools/javac/util/Pair.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/Pair.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package com.sun.tools.javac.util; +import java.util.Objects; + /** A generic class for pairs. * *

This is NOT part of any supported API. @@ -46,15 +48,11 @@ return "Pair[" + fst + "," + snd + "]"; } - private static boolean equals(Object x, Object y) { - return (x == null && y == null) || (x != null && x.equals(y)); - } - public boolean equals(Object other) { return other instanceof Pair && - equals(fst, ((Pair)other).fst) && - equals(snd, ((Pair)other).snd); + Objects.equals(fst, ((Pair)other).fst) && + Objects.equals(snd, ((Pair)other).snd); } public int hashCode() { diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java --- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Tue Apr 16 08:16:07 2013 -0700 @@ -395,6 +395,9 @@ @Override public String visitClassSymbol(ClassSymbol s, Locale locale) { + if (s.type.isCompound()) { + return visit(s.type, locale); + } String name = nameSimplifier.simplify(s); if (name.length() == 0 || !getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) { @@ -583,7 +586,11 @@ @Override public Void visitClassSymbol(ClassSymbol s, Void ignored) { - nameSimplifier.addUsage(s); + if (s.type.isCompound()) { + typePreprocessor.visit(s.type); + } else { + nameSimplifier.addUsage(s); + } return null; } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/com/sun/tools/javadoc/DocEnv.java --- a/src/share/classes/com/sun/tools/javadoc/DocEnv.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Apr 16 08:16:07 2013 -0700 @@ -810,6 +810,8 @@ JavacTask t = BasicJavacTask.instance(context); doclint = new DocLint(); + // standard doclet normally generates H1, H2 + doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); } diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/javax/annotation/processing/AbstractProcessor.java --- a/src/share/classes/javax/annotation/processing/AbstractProcessor.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/javax/annotation/processing/AbstractProcessor.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -28,6 +28,7 @@ import java.util.Set; import java.util.HashSet; import java.util.Collections; +import java.util.Objects; import javax.lang.model.element.*; import javax.lang.model.SourceVersion; import javax.tools.Diagnostic; @@ -146,8 +147,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { if (initialized) throw new IllegalStateException("Cannot call init more than once."); - if (processingEnv == null) - throw new NullPointerException("Tool provided null ProcessingEnvironment"); + Objects.requireNonNull(processingEnv, "Tool provided null ProcessingEnvironment"); this.processingEnv = processingEnv; initialized = true; diff -r 2c9acb17f41a -r 1f19b84efa6d src/share/classes/javax/lang/model/element/Modifier.java --- a/src/share/classes/javax/lang/model/element/Modifier.java Thu Apr 11 09:40:22 2013 -0700 +++ b/src/share/classes/javax/lang/model/element/Modifier.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -53,6 +53,11 @@ /** The modifier {@code protected} */ PROTECTED, /** The modifier {@code private} */ PRIVATE, /** The modifier {@code abstract} */ ABSTRACT, + /** + * The modifier {@code default} + * @since 1.8 + */ + DEFAULT, /** The modifier {@code static} */ STATIC, /** The modifier {@code final} */ FINAL, /** The modifier {@code transient} */ TRANSIENT, diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/T4965689/ClassLiteralWastesByteTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T4965689/ClassLiteralWastesByteTest.java Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4965689 + * @summary class literal code wastes a byte + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Paths; + +public class ClassLiteralWastesByteTest { + + private static final String assertionErrorMsg = + "Instead of ldc_w, ldc instruction should have been generated"; + + public static void main(String[] args) { + new ClassLiteralWastesByteTest().run(); + } + + void run() { + check("-c", Paths.get(System.getProperty("test.classes"), + "test.class").toString()); + } + + void check(String... params) { + StringWriter s; + String out; + try (PrintWriter pw = new PrintWriter(s = new StringWriter())) { + com.sun.tools.javap.Main.run(params, pw); + out = s.toString(); + } + if (out.contains("ldc_w")) { + throw new AssertionError(assertionErrorMsg); + } + } + +} + +class test { + void m() { + Class aClass = test.class; + } +} diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/T6558476.java --- a/test/tools/javac/T6558476.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/T6558476.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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,6 +23,8 @@ /* * @test + * @bug 6558476 + * @summary com/sun/tools/javac/Main.compile don't release file handles on return * @run main/othervm -Xmx512m -Xms512m T6558476 */ @@ -70,8 +72,7 @@ public static void main(String[] args) throws IOException { File javaHomeDir = new File(System.getProperty("java.home")); - File tmpDir = new File(System.getProperty("java.io.tmpdir")); - File outputDir = new File(tmpDir, "outputDir" + new Random().nextInt(65536)); + File outputDir = new File("outputDir" + new Random().nextInt(65536)); outputDir.mkdir(); outputDir.deleteOnExit(); diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/T6900149.java --- a/test/tools/javac/T6900149.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/T6900149.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -39,7 +39,7 @@ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); - File emptyFile = File.createTempFile("Empty", ".java"); + File emptyFile = createTempFile("Empty.java"); File[] files = new File[] { emptyFile, emptyFile }; CompilationTask task = compiler.getTask(null, fm, diag, null, null, fm.getJavaFileObjects(files)); @@ -47,4 +47,10 @@ throw new AssertionError("compilation failed"); } } + + private static File createTempFile(String path) throws IOException { + File f = new File(path); + try (FileWriter out = new FileWriter(f)) { } + return f; + } } diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/diags/CheckExamples.java --- a/test/tools/javac/diags/CheckExamples.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/diags/CheckExamples.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -34,6 +34,8 @@ */ import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; /** @@ -53,7 +55,27 @@ * Standard entry point. */ public static void main(String... args) throws Exception { - new CheckExamples().run(); + boolean jtreg = (System.getProperty("test.src") != null); + Path tmpDir; + boolean deleteOnExit; + if (jtreg) { + // use standard jtreg scratch directory: the current directory + tmpDir = Paths.get(System.getProperty("user.dir")); + deleteOnExit = false; + } else { + tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), + CheckExamples.class.getName()); + deleteOnExit = true; + } + Example.setTempDir(tmpDir.toFile()); + + try { + new CheckExamples().run(); + } finally { + if (deleteOnExit) { + clean(tmpDir); + } + } } /** @@ -190,6 +212,25 @@ int errors; + /** + * Clean the contents of a directory. + */ + static void clean(Path dir) throws IOException { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return super.visitFile(file, attrs); + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (exc == null) Files.delete(dir); + return super.postVisitDirectory(dir, exc); + } + }); + } + static class Counts { static String[] prefixes = { "compiler.err.", diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/diags/RunExamples.java --- a/test/tools/javac/diags/RunExamples.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/diags/RunExamples.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -33,7 +33,8 @@ */ import java.io.*; -import java.text.SimpleDateFormat; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -56,16 +57,18 @@ public class RunExamples { public static void main(String... args) throws Exception { jtreg = (System.getProperty("test.src") != null); - File tmpDir; + Path tmpDir; + boolean deleteOnExit; if (jtreg) { // use standard jtreg scratch directory: the current directory - tmpDir = new File(System.getProperty("user.dir")); + tmpDir = Paths.get(System.getProperty("user.dir")); + deleteOnExit = false; } else { - tmpDir = new File(System.getProperty("java.io.tmpdir"), - RunExamples.class.getName() - + (new SimpleDateFormat("yyMMddHHmmss")).format(new Date())); + tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), + RunExamples.class.getName()); + deleteOnExit = true; } - Example.setTempDir(tmpDir); + Example.setTempDir(tmpDir.toFile()); RunExamples r = new RunExamples(); @@ -73,15 +76,8 @@ if (r.run(args)) return; } finally { - /* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the - * jtreg scratch directory, which is the current directory. - * In case someone is faking jtreg mode, make sure to only - * clean tmpDir when it is reasonable to do so. - */ - if (tmpDir.isDirectory() && - tmpDir.getName().startsWith(RunExamples.class.getName())) { - if (clean(tmpDir)) - tmpDir.delete(); + if (deleteOnExit) { + clean(tmpDir); } } @@ -203,14 +199,20 @@ /** * Clean the contents of a directory. */ - static boolean clean(File dir) { - boolean ok = true; - for (File f: dir.listFiles()) { - if (f.isDirectory()) - ok &= clean(f); - ok &= f.delete(); - } - return ok; + static void clean(Path dir) throws IOException { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return super.visitFile(file, attrs); + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + if (exc == null) Files.delete(dir); + return super.postVisitDirectory(dir, exc); + } + }); } static abstract class Runner { diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/diags/examples/BadArgTypesInLambda.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/diags/examples/BadArgTypesInLambda.java Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,38 @@ +/* + * 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.cant.apply.symbol +// key: compiler.misc.no.conforming.assignment.exists +// key: compiler.misc.bad.arg.types.in.lambda + +class BadArgTypesInLambda { + interface SAM { + void m(Integer i); + } + + void g(SAM s) { } + + void test() { + g(x->{ String s = x; }); + } +} diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/diags/examples/NotAnInterfaceComponent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/diags/examples/NotAnInterfaceComponent.java Tue Apr 16 08:16:07 2013 -0700 @@ -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. + */ + +// key: compiler.err.prob.found.req +// key: compiler.misc.bad.intersection.target.for.functional.expr +// key: compiler.misc.not.an.intf.component + +class NotAnInterfaceComponent { + Object o = (Object & Runnable) ()-> { }; +} diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java --- a/test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java Thu Apr 11 09:40:22 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// key: compiler.err.prob.found.req -// key: compiler.misc.secondary.bound.must.be.marker.intf - -class SecondaryBoundMustBeMarkerInterface { - Runnable r = (Runnable & Comparable)()->{}; -} diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/doclint/ImplicitHeadersTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/doclint/ImplicitHeadersTest.java Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,35 @@ +/* + * 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 8006346 + * @summary doclint should make allowance for headers generated by standard doclet + * @compile -Xdoclint:all/public ImplicitHeadersTest.java + */ + +/** + *

Header

+ */ +public class ImplicitHeadersTest { } + diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/BadRecovery.out --- a/test/tools/javac/lambda/BadRecovery.out Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/BadRecovery.out Tue Apr 16 08:16:07 2013 -0700 @@ -1,3 +1,2 @@ -BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda)) BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null) -2 errors +1 error diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/Intersection01.java --- a/test/tools/javac/lambda/Intersection01.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/Intersection01.java Tue Apr 16 08:16:07 2013 -0700 @@ -25,7 +25,7 @@ * @test * @bug 8002099 * @summary Add support for intersection types in cast expression - * @compile/fail/ref=Intersection01.out -XDrawDiagnostics Intersection01.java + * @compile Intersection01.java */ class Intersection01 { diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/Intersection01.out --- a/test/tools/javac/lambda/Intersection01.out Thu Apr 11 09:40:22 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) -Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: java.io.Serializable, (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable)) -2 errors diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TargetType01.java --- a/test/tools/javac/lambda/TargetType01.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/TargetType01.java Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,11 +23,10 @@ /* * @test - * @bug 8003280 + * @bug 8003280 8009131 * @summary Add lambda tests * check nested case of overload resolution and lambda parameter inference - * @author Maurizio Cimadamore - * @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java + * @compile TargetType01.java */ class TargetType01 { diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TargetType01.out --- a/test/tools/javac/lambda/TargetType01.out Thu Apr 11 09:40:22 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -TargetType01.java:46:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 -TargetType01.java:46:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 -2 errors diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TargetType43.out --- a/test/tools/javac/lambda/TargetType43.out Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/TargetType43.out Tue Apr 16 08:16:07 2013 -0700 @@ -1,5 +1,4 @@ TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) -TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object)) TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null) -4 errors +3 errors diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TargetType66.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType66.java Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,26 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8009131 + * @summary Overload: javac should discard methods that lead to errors in lambdas with implicit parameter types + * @compile/fail/ref=TargetType66.out -XDrawDiagnostics TargetType66.java + */ +class TargetType66 { + interface SAM1 { + void m(String s); + } + + interface SAM2 { + void m(Integer s); + } + + void g(SAM1 s1) { } + void g(SAM2 s2) { } + + void test() { + g(x->{ String s = x; }); //g(SAM1) + g(x->{ Integer i = x; }); //g(SAM2) + g(x->{ Object o = x; }); //ambiguous + g(x->{ Character c = x; }); //error: inapplicable methods + g(x->{ Character c = ""; }); //error: incompatible types + } +} diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TargetType66.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/TargetType66.out Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,4 @@ +TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66 +TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer)))} +TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character) +3 errors diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/TestInvokeDynamic.java --- a/test/tools/javac/lambda/TestInvokeDynamic.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/TestInvokeDynamic.java Tue Apr 16 08:16:07 2013 -0700 @@ -24,7 +24,7 @@ /* * @test * @bug 7194586 - * @bug 8003280 8006694 + * @bug 8003280 8006694 8010404 * @summary Add lambda tests * Add back-end support for invokedynamic * temporarily workaround combo tests are causing time out in several platforms @@ -48,6 +48,7 @@ import com.sun.tools.classfile.Code_attribute; import com.sun.tools.classfile.ConstantPool.*; import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.LineNumberTable_attribute; import com.sun.tools.classfile.Method; import com.sun.tools.javac.api.JavacTaskImpl; @@ -239,7 +240,7 @@ int id = checkCount.incrementAndGet(); JavaSource source = new JavaSource(id); JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc, - null, null, Arrays.asList(source)); + Arrays.asList("-g"), null, Arrays.asList(source)); Context context = ct.getContext(); Symtab syms = Symtab.instance(context); Names names = Names.instance(context); @@ -349,6 +350,16 @@ bsm_ref.getNameAndTypeInfo().getType() + " " + asBSMSignatureString()); } + + LineNumberTable_attribute lnt = + (LineNumberTable_attribute)ea.attributes.get(Attribute.LineNumberTable); + + if (lnt == null) { + throw new Error("No LineNumberTable attribute"); + } + if (lnt.line_number_table_length != 2) { + throw new Error("Wrong number of entries in LineNumberTable"); + } } catch (Exception e) { e.printStackTrace(); throw new Error("error reading " + compiledTest +": " + e); @@ -376,7 +387,10 @@ "}\n" + "class Test#ID {\n" + " void m() { }\n" + - " void test() { m(); }\n" + + " void test() {\n" + + " Object o = this; // marker statement \n" + + " m();\n" + + " }\n" + "}"; String source; diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java --- a/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Tue Apr 16 08:16:07 2013 -0700 @@ -28,10 +28,11 @@ */ import com.sun.source.util.JavacTask; -import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.tools.Diagnostic; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; @@ -45,37 +46,45 @@ enum BoundKind { INTF, - CLASS, - SAM, - ZAM; + CLASS; } enum MethodKind { - NONE, - ABSTRACT, - DEFAULT; + NONE(false), + ABSTRACT_M(true), + DEFAULT_M(false), + ABSTRACT_G(true), + DEFAULT_G(false); + + boolean isAbstract; + + MethodKind(boolean isAbstract) { + this.isAbstract = isAbstract; + } } enum TypeKind { - A("interface A { }\n", "A", BoundKind.ZAM), - B("interface B { default void m() { } }\n", "B", BoundKind.ZAM), - C("interface C { void m(); }\n", "C", BoundKind.SAM), - D("interface D extends B { }\n", "D", BoundKind.ZAM), - E("interface E extends C { }\n", "E", BoundKind.SAM), - F("interface F extends C { void g(); }\n", "F", BoundKind.INTF), - G("interface G extends B { void g(); }\n", "G", BoundKind.SAM), - H("interface H extends A { void g(); }\n", "H", BoundKind.SAM), + A("interface A { }\n", "A", BoundKind.INTF, MethodKind.NONE), + B("interface B { default void m() { } }\n", "B", BoundKind.INTF, MethodKind.DEFAULT_M), + C("interface C { void m(); }\n", "C", BoundKind.INTF, MethodKind.ABSTRACT_M), + D("interface D extends B { }\n", "D", BoundKind.INTF, MethodKind.DEFAULT_M), + E("interface E extends C { }\n", "E", BoundKind.INTF, MethodKind.ABSTRACT_M), + F("interface F extends C { void g(); }\n", "F", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.ABSTRACT_M), + G("interface G extends B { void g(); }\n", "G", BoundKind.INTF, MethodKind.ABSTRACT_G, MethodKind.DEFAULT_M), + H("interface H extends A { void g(); }\n", "H", BoundKind.INTF, MethodKind.ABSTRACT_G), OBJECT("", "Object", BoundKind.CLASS), STRING("", "String", BoundKind.CLASS); String declStr; String typeStr; BoundKind boundKind; + MethodKind[] methodKinds; - private TypeKind(String declStr, String typeStr, BoundKind boundKind) { + private TypeKind(String declStr, String typeStr, BoundKind boundKind, MethodKind... methodKinds) { this.declStr = declStr; this.typeStr = typeStr; this.boundKind = boundKind; + this.methodKinds = methodKinds; } boolean compatibleSupertype(TypeKind tk) { @@ -263,14 +272,22 @@ boolean errorExpected = !cInfo.wellFormed(); if (ek.isFunctional) { - //first bound must be a SAM - errorExpected |= cInfo.types[0].boundKind != BoundKind.SAM; - if (cInfo.types.length > 1) { - //additional bounds must be ZAMs - for (int i = 1; i < cInfo.types.length; i++) { - errorExpected |= cInfo.types[i].boundKind != BoundKind.ZAM; + List mks = new ArrayList<>(); + for (TypeKind tk : cInfo.types) { + if (tk.boundKind == BoundKind.CLASS) { + errorExpected = true; + break; + } else { + mks = mergeMethods(mks, Arrays.asList(tk.methodKinds)); } } + int abstractCount = 0; + for (MethodKind mk : mks) { + if (mk.isAbstract) { + abstractCount++; + } + } + errorExpected |= abstractCount != 1; } if (errorExpected != diagChecker.errorFound) { @@ -281,6 +298,32 @@ } } + List mergeMethods(List l1, List l2) { + List mergedMethods = new ArrayList<>(l1); + for (MethodKind mk2 : l2) { + boolean add = !mergedMethods.contains(mk2); + switch (mk2) { + case ABSTRACT_G: + add = add && !mergedMethods.contains(MethodKind.DEFAULT_G); + break; + case ABSTRACT_M: + add = add && !mergedMethods.contains(MethodKind.DEFAULT_M); + break; + case DEFAULT_G: + mergedMethods.remove(MethodKind.ABSTRACT_G); + case DEFAULT_M: + mergedMethods.remove(MethodKind.ABSTRACT_M); + case NONE: + add = false; + break; + } + if (add) { + mergedMethods.add(mk2); + } + } + return mergedMethods; + } + static class DiagnosticChecker implements javax.tools.DiagnosticListener { boolean errorFound; diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java --- a/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Tue Apr 16 08:16:07 2013 -0700 @@ -427,6 +427,8 @@ */ public void testReflectCall() { Interface I = new Interface("I", DefaultMethod.std("99")); + //workaround accessibility issue when loading C with DirectedClassLoader + I.addAccessFlag(AccessFlag.PUBLIC); Class C = new Class("C", I); Compiler.Flags[] flags = this.verbose ? diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javac/processing/model/element/TestExecutableElement.java --- a/test/tools/javac/processing/model/element/TestExecutableElement.java Thu Apr 11 09:40:22 2013 -0700 +++ b/test/tools/javac/processing/model/element/TestExecutableElement.java Tue Apr 16 08:16:07 2013 -0700 @@ -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,7 +23,7 @@ /* * @test - * @bug 8005046 + * @bug 8005046 8011052 * @summary Test basic properties of javax.lang.element.Element * @author Joseph D. Darcy * @library /tools/javac/lib @@ -35,6 +35,7 @@ import java.util.Formatter; import java.util.Set; import java.util.Objects; +import java.util.regex.*; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import static javax.lang.model.SourceVersion.*; @@ -79,9 +80,39 @@ boolean methodIsDefault = method.isDefault(); + if (expectedDefault) { + if (!method.getModifiers().contains(Modifier.DEFAULT)) { + messager.printMessage(ERROR, + "Modifier \"default\" not present as expected.", + method); + } + + // Check printing output + java.io.Writer stringWriter = new java.io.StringWriter(); + eltUtils.printElements(stringWriter, method); + Pattern p = Pattern.compile(expectedIsDefault.expectedTextRegex(), Pattern.DOTALL); + + if (! p.matcher(stringWriter.toString()).matches()) { + messager.printMessage(ERROR, + new Formatter().format("Unexpected printing ouptput:%n\tgot %s,%n\texpected pattern %s.", + stringWriter.toString(), + expectedIsDefault.expectedTextRegex()).toString(), + method); + } + + System.out.println("\t" + stringWriter.toString()); + + } else { + if (method.getModifiers().contains(Modifier.DEFAULT)) { + messager.printMessage(ERROR, + "Modifier \"default\" present when not expected.", + method); + } + } + if (methodIsDefault != expectedDefault) { messager.printMessage(ERROR, - new Formatter().format("Unexpected Executable.isDefault result: got %s, expected %s", + new Formatter().format("Unexpected Executable.isDefault result: got ``%s'', expected ``%s''.", expectedDefault, methodIsDefault).toString(), method); @@ -98,6 +129,7 @@ @Target(ElementType.METHOD) @interface IsDefault { boolean value(); + String expectedTextRegex() default ""; } /** @@ -108,6 +140,6 @@ boolean process(Set annotations, RoundEnvironment roundEnv); - @IsDefault(true) - default void quux() {}; + @IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$") + default strictfp void quux() {}; } diff -r 2c9acb17f41a -r 1f19b84efa6d test/tools/javadoc/doclint/ImplicitHeadersTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javadoc/doclint/ImplicitHeadersTest.java Tue Apr 16 08:16:07 2013 -0700 @@ -0,0 +1,45 @@ +/* + * 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 8006346 + * @summary doclint should make allowance for headers generated by standard doclet + */ + +import java.io.File; + +/** + *

Header

+ */ +public class ImplicitHeadersTest { + public static void main(String... args) { + File testSrc = new File(System.getProperty("test.src")); + File testFile = new File(testSrc, ImplicitHeadersTest.class.getSimpleName() + ".java"); + String[] javadocArgs = { "-d", "out", testFile.getPath() }; + int rc = com.sun.tools.javadoc.Main.execute(javadocArgs); + if (rc != 0) + throw new Error("unexpected exit: rc=" + rc); + } +} +