# HG changeset patch # User lana # Date 1398927585 25200 # Node ID b5c2375893e2bca1883e5571bd911b6f0b533bf4 # Parent df290532391403e5cccd7f4966bc7385fdf32c54# Parent 12f99d1f23d97e10f76df03663d1ea561862d3a0 Merge diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -177,7 +177,7 @@ try { url = adjustEndFileSeparator(url); if (isUrl(pkglisturl)) { - readPackageListFromURL(url, toURL(pkglisturl)); + readPackageListFromURL(url, toURL(adjustEndFileSeparator(pkglisturl))); } else { readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl)); } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/code/Source.java --- a/src/share/classes/com/sun/tools/javac/code/Source.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Wed Apr 30 23:59:45 2014 -0700 @@ -191,6 +191,9 @@ public boolean allowObjectToPrimitiveCast() { return compareTo(JDK1_7) >= 0; } + public boolean enforceThisDotInit() { + return compareTo(JDK1_7) >= 0; + } public boolean allowPoly() { return compareTo(JDK1_8) >= 0; } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Apr 30 23:59:45 2014 -0700 @@ -249,7 +249,7 @@ if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { if (allowPoly && inferenceContext.free(found)) { if ((ownkind & ~resultInfo.pkind) == 0) { - owntype = resultInfo.check(tree, inferenceContext.asFree(owntype)); + owntype = resultInfo.check(tree, inferenceContext.asUndetVar(owntype)); } else { log.error(tree.pos(), "unexpected.type", kindNames(resultInfo.pkind), @@ -2402,7 +2402,7 @@ //add thrown types as bounds to the thrown types free variables if needed: if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) { List inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make); - List thrownTypes = resultInfo.checkContext.inferenceContext().asFree(lambdaType.getThrownTypes()); + List thrownTypes = resultInfo.checkContext.inferenceContext().asUndetVars(lambdaType.getThrownTypes()); chk.unhandled(inferredThrownTypes, thrownTypes); } @@ -2543,7 +2543,7 @@ @Override public boolean compatible(Type found, Type req, Warner warn) { //return type must be compatible in both current context and assignment context - return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn); + return chk.basicHandler.compatible(found, inferenceContext().asUndetVar(req), warn); } @Override @@ -2576,7 +2576,7 @@ * types must be compatible with the return type of the expected descriptor. */ private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext) { - Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); + Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType()); //return values have already been checked - but if lambda has no return //values, we must ensure that void/value compatibility is correct; @@ -2588,7 +2588,7 @@ diags.fragment("missing.ret.val", returnType))); } - List argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes()); + List argTypes = checkContext.inferenceContext().asUndetVars(descriptor.getParameterTypes()); if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) { checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); } @@ -2618,7 +2618,7 @@ * - an instance field, we use the first constructor. * - a static field, we create a fake clinit method. */ - private Env lambdaEnv(JCLambda that, Env env) { + public Env lambdaEnv(JCLambda that, Env env) { Env lambdaEnv; Symbol owner = env.info.scope.owner; if (owner.kind == VAR && owner.owner.kind == TYP) { @@ -2832,7 +2832,7 @@ if (that.kind.isUnbound() && resultInfo.checkContext.inferenceContext().free(argtypes.head)) { //re-generate inference constraints for unbound receiver - if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asFree(argtypes.head), exprType)) { + if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) { //cannot happen as this has already been checked - we just need //to regenerate the inference constraints, as that has been lost //as a result of the call to inferenceContext.save() @@ -2870,7 +2870,7 @@ @SuppressWarnings("fallthrough") void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) { - Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType()); + Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType()); Type resType; switch (tree.getMode()) { @@ -2902,7 +2902,7 @@ } if (!speculativeAttr) { - List thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes()); + List thrownTypes = checkContext.inferenceContext().asUndetVars(descriptor.getThrownTypes()); if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) { log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes()); } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ package com.sun.tools.javac.comp; -import com.sun.source.tree.MemberReferenceTree; +import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -35,10 +35,8 @@ import com.sun.tools.javac.comp.Attr.ResultInfo; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; -import com.sun.tools.javac.comp.Resolve.ReferenceLookupHelper; import com.sun.tools.javac.tree.JCTree.*; - import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -48,6 +46,7 @@ import java.util.Set; import java.util.WeakHashMap; +import static com.sun.tools.javac.code.Kinds.VAL; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -76,6 +75,8 @@ final Symtab syms; final TreeMaker make; final Types types; + final Flow flow; + final Names names; public static DeferredAttr instance(Context context) { DeferredAttr instance = context.get(deferredAttrKey); @@ -96,7 +97,8 @@ syms = Symtab.instance(context); make = TreeMaker.instance(context); types = Types.instance(context); - Names names = Names.instance(context); + flow = Flow.instance(context); + names = Names.instance(context); stuckTree = make.Ident(names.empty).setType(Type.stuckType); emptyDeferredAttrContext = new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { @@ -139,6 +141,11 @@ return DEFERRED; } + @Override + public String toString() { + return "DeferredType"; + } + /** * A speculative cache is used to keep track of all overload resolution rounds * that triggered speculative attribution on a given deferred type. Each entry @@ -378,7 +385,9 @@ } } //where - protected TreeScanner unenterScanner = new TreeScanner() { + protected UnenterScanner unenterScanner = new UnenterScanner(); + + class UnenterScanner extends TreeScanner { @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol csym = tree.sym; @@ -391,7 +400,7 @@ syms.classes.remove(csym.flatname); super.visitClassDef(tree); } - }; + } /** * A deferred context is created on each method check. A deferred context is @@ -595,19 +604,111 @@ public void visitLambda(JCLambda tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { //must be a functional descriptor + Type descriptorType = null; try { - Type desc = types.findDescriptorType(pt); - if (desc.getParameterTypes().length() != tree.params.length()) { - checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda")); - } + descriptorType = types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { checkContext.report(null, ex.getDiagnostic()); } + + if (descriptorType.getParameterTypes().length() != tree.params.length()) { + checkContext.report(tree, + diags.fragment("incompatible.arg.types.in.lambda")); + } + + Type currentReturnType = descriptorType.getReturnType(); + boolean returnTypeIsVoid = currentReturnType.hasTag(VOID); + if (tree.getBodyKind() == BodyKind.EXPRESSION) { + boolean isExpressionCompatible = !returnTypeIsVoid || + TreeInfo.isExpressionStatement((JCExpression)tree.getBody()); + if (!isExpressionCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } else { + LambdaBodyStructChecker lambdaBodyChecker = + new LambdaBodyStructChecker(); + + tree.body.accept(lambdaBodyChecker); + boolean isVoidCompatible = lambdaBodyChecker.isVoidCompatible; + + if (returnTypeIsVoid) { + if (!isVoidCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("unexpected.ret.val")); + } + } else { + boolean isValueCompatible = lambdaBodyChecker.isPotentiallyValueCompatible + && !canLambdaBodyCompleteNormally(tree); + if (!isValueCompatible && !isVoidCompatible) { + log.error(tree.body.pos(), + "lambda.body.neither.value.nor.void.compatible"); + } + + if (!isValueCompatible) { + resultInfo.checkContext.report(tree.pos(), + diags.fragment("incompatible.ret.type.in.lambda", + diags.fragment("missing.ret.val", currentReturnType))); + } + } + } + } + } + + boolean canLambdaBodyCompleteNormally(JCLambda tree) { + JCLambda newTree = new TreeCopier<>(make).copy(tree); + /* attr.lambdaEnv will create a meaningful env for the + * lambda expression. This is specially useful when the + * lambda is used as the init of a field. But we need to + * remove any added symbol. + */ + Env localEnv = attr.lambdaEnv(newTree, env); + try { + List tmpParams = newTree.params; + while (tmpParams.nonEmpty()) { + tmpParams.head.vartype = make.at(tmpParams.head).Type(syms.errType); + tmpParams = tmpParams.tail; + } + + attr.attribStats(newTree.params, localEnv); + + /* set pt to Type.noType to avoid generating any bound + * which may happen if lambda's return type is an + * inference variable + */ + Attr.ResultInfo bodyResultInfo = attr.new ResultInfo(VAL, Type.noType); + localEnv.info.returnResult = bodyResultInfo; + + // discard any log output + Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); + try { + JCBlock body = (JCBlock)newTree.body; + /* we need to attribute the lambda body before + * doing the aliveness analysis. This is because + * constant folding occurs during attribution + * and the reachability of some statements depends + * on constant values, for example: + * + * while (true) {...} + */ + attr.attribStats(body.stats, localEnv); + + attr.preFlow(newTree); + /* make an aliveness / reachability analysis of the lambda + * to determine if it can complete normally + */ + flow.analyzeLambda(localEnv, newTree, make, true); + } finally { + log.popDiagnosticHandler(diagHandler); + } + return newTree.canCompleteNormally; + } finally { + JCBlock body = (JCBlock)newTree.body; + unenterScanner.scan(body.stats); + localEnv.info.scope.leave(); } } @@ -625,10 +726,7 @@ public void visitReference(JCMemberReference tree) { Check.CheckContext checkContext = resultInfo.checkContext; Type pt = resultInfo.pt; - if (inferenceContext.inferencevars.contains(pt)) { - //ok - return; - } else { + if (!inferenceContext.inferencevars.contains(pt)) { try { types.findDescriptorType(pt); } catch (Types.FunctionDescriptorLookupError ex) { @@ -658,6 +756,40 @@ } } } + + /* This visitor looks for return statements, its analysis will determine if + * a lambda body is void or value compatible. We must analyze return + * statements contained in the lambda body only, thus any return statement + * contained in an inner class or inner lambda body, should be ignored. + */ + class LambdaBodyStructChecker extends TreeScanner { + boolean isVoidCompatible = true; + boolean isPotentiallyValueCompatible = true; + + @Override + public void visitClassDef(JCClassDecl tree) { + // do nothing + } + + @Override + public void visitLambda(JCLambda tree) { + // do nothing + } + + @Override + public void visitNewClass(JCNewClass tree) { + // do nothing + } + + @Override + public void visitReturn(JCReturn tree) { + if (tree.expr != null) { + isVoidCompatible = false; + } else { + isPotentiallyValueCompatible = false; + } + } + } } /** an empty deferred attribution context - all methods throw exceptions */ @@ -769,7 +901,7 @@ /** * handler that is executed when a node has been discarded */ - abstract void skip(JCTree tree); + void skip(JCTree tree) {} } /** @@ -781,11 +913,6 @@ PolyScanner() { super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** @@ -798,11 +925,6 @@ super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP, FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP)); } - - @Override - void skip(JCTree tree) { - //do nothing - } } /** diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/Flow.java --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Apr 30 23:59:45 2014 -0700 @@ -45,7 +45,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*; /** This pass implements dataflow analysis for Java programs though - * different AST visitor steps. Liveness analysis (see AliveAlanyzer) checks that + * different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that * every statement is reachable. Exception analysis (see FlowAnalyzer) ensures that * every checked exception that is thrown is declared or caught. Definite assignment analysis * (see AssignAnalyzer) ensures that each variable is assigned when used. Definite @@ -197,6 +197,7 @@ private final boolean allowImprovedRethrowAnalysis; private final boolean allowImprovedCatchAnalysis; private final boolean allowEffectivelyFinalInInnerClasses; + private final boolean enforceThisDotInit; public static Flow instance(Context context) { Flow instance = context.get(flowKey); @@ -207,7 +208,7 @@ public void analyzeTree(Env env, TreeMaker make) { new AliveAnalyzer().analyzeTree(env, make); - new AssignAnalyzer(log, syms, lint, names).analyzeTree(env); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); new FlowAnalyzer().analyzeTree(env, make); new CaptureAnalyzer().analyzeTree(env, make); } @@ -239,7 +240,7 @@ //related errors, which will allow for more errors to be detected Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log); try { - new AssignAnalyzer(log, syms, lint, names).analyzeTree(env); + new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env); LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer(); flowAnalyzer.analyzeTree(env, that, make); return flowAnalyzer.inferredThrownTypes; @@ -289,6 +290,7 @@ allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis(); allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis(); allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses(); + enforceThisDotInit = source.enforceThisDotInit(); } /** @@ -1427,6 +1429,8 @@ protected Names names; + final boolean enforceThisDotInit; + public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit { final Bits inits; @@ -1449,7 +1453,7 @@ } } - public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names) { + public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) { this.inits = inits; uninits = new Bits(); uninitsTry = new Bits(); @@ -1459,6 +1463,7 @@ uninitsWhenFalse = new Bits(true); this.syms = syms; this.names = names; + this.enforceThisDotInit = enforceThisDotInit; } private boolean isInitialConstructor = false; @@ -2280,12 +2285,34 @@ public void visitAssign(JCAssign tree) { JCTree lhs = TreeInfo.skipParens(tree.lhs); - if (!(lhs instanceof JCIdent)) { + if (!isIdentOrThisDotIdent(lhs)) scanExpr(lhs); - } scanExpr(tree.rhs); letInit(lhs); } + private boolean isIdentOrThisDotIdent(JCTree lhs) { + if (lhs.hasTag(IDENT)) + return true; + if (!lhs.hasTag(SELECT)) + return false; + + JCFieldAccess fa = (JCFieldAccess)lhs; + return fa.selected.hasTag(IDENT) && + ((JCIdent)fa.selected).name == names._this; + } + + // check fields accessed through this. are definitely + // assigned before reading their value + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + if (enforceThisDotInit && + tree.selected.hasTag(IDENT) && + ((JCIdent)tree.selected).name == names._this && + tree.sym.kind == VAR) + { + checkInit(tree.pos(), (VarSymbol)tree.sym); + } + } public void visitAssignop(JCAssignOp tree) { scanExpr(tree.lhs); @@ -2419,8 +2446,8 @@ } } - public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names) { - super(new Bits(), syms, names); + public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) { + super(new Bits(), syms, names, enforceThisDotInit); this.log = log; this.lint = lint; } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Wed Apr 30 23:59:45 2014 -0700 @@ -220,9 +220,10 @@ */ Type generateReturnConstraints(Attr.ResultInfo resultInfo, MethodType mt, InferenceContext inferenceContext) { + InferenceContext rsInfoInfContext = resultInfo.checkContext.inferenceContext(); Type from = mt.getReturnType(); if (mt.getReturnType().containsAny(inferenceContext.inferencevars) && - resultInfo.checkContext.inferenceContext() != emptyContext) { + rsInfoInfContext != emptyContext) { from = types.capture(from); //add synthetic captured ivars for (Type t : from.getTypeArguments()) { @@ -231,13 +232,13 @@ } } } - Type qtype1 = inferenceContext.asFree(from); + Type qtype1 = inferenceContext.asUndetVar(from); Type to = returnConstraintTarget(qtype1, resultInfo.pt); - Assert.check(allowGraphInference || !resultInfo.checkContext.inferenceContext().free(to), + Assert.check(allowGraphInference || !rsInfoInfContext.free(to), "legacy inference engine cannot handle constraints on both sides of a subtyping assertion"); //we need to skip capture? Warner retWarn = new Warner(); - if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) || + if (!resultInfo.checkContext.compatible(qtype1, rsInfoInfContext.asUndetVar(to), retWarn) || //unchecked conversion is not allowed in source 7 mode (!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) { throw inferenceException @@ -280,7 +281,7 @@ ListBuffer todo = new ListBuffer<>(); //step 1 - create fresh tvars for (Type t : vars) { - UndetVar uv = (UndetVar)inferenceContext.asFree(t); + UndetVar uv = (UndetVar)inferenceContext.asUndetVar(t); List upperBounds = uv.getBounds(InferenceBound.UPPER); if (Type.containsAny(upperBounds, vars)) { TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner); @@ -399,7 +400,7 @@ return types.createErrorType(funcInterface); } for (Type p : descParameterTypes) { - if (!types.isSameType(funcInterfaceContext.asFree(p), paramTypes.head)) { + if (!types.isSameType(funcInterfaceContext.asUndetVar(p), paramTypes.head)) { checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface)); return types.createErrorType(funcInterface); } @@ -515,6 +516,32 @@ /** max number of incorporation rounds */ static final int MAX_INCORPORATION_STEPS = 100; + /* If for two types t and s there is a least upper bound that is a + * parameterized type G, then there exists a supertype of 't' of the form + * G and a supertype of 's' of the form G + * which will be returned by this method. If no such supertypes exists then + * null is returned. + * + * As an example for the following input: + * + * t = java.util.ArrayList + * s = java.util.List + * + * we get this ouput: + * + * Pair[java.util.List,java.util.List] + */ + private Pair getParameterizedSupers(Type t, Type s) { + Type lubResult = types.lub(t, s); + if (lubResult == syms.errType || lubResult == syms.botType || + !lubResult.isParameterized()) { + return null; + } + Type asSuperOfT = types.asSuper(t, lubResult.tsym); + Type asSuperOfS = types.asSuper(s, lubResult.tsym); + return new Pair<>(asSuperOfT, asSuperOfS); + } + /** * This enumeration defines an entry point for doing inference variable * bound incorporation - it can be used to inject custom incorporation @@ -533,22 +560,23 @@ if (uv.inst != null) { Type inst = uv.inst; for (Type u : uv.getBounds(InferenceBound.UPPER)) { - if (!isSubtype(inst, inferenceContext.asFree(u), warn, infer)) { + if (!isSubtype(inst, inferenceContext.asUndetVar(u), warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.UPPER); } } for (Type l : uv.getBounds(InferenceBound.LOWER)) { - if (!isSubtype(inferenceContext.asFree(l), inst, warn, infer)) { + if (!isSubtype(inferenceContext.asUndetVar(l), inst, warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.LOWER); } } for (Type e : uv.getBounds(InferenceBound.EQ)) { - if (!isSameType(inst, inferenceContext.asFree(e), infer)) { + if (!isSameType(inst, inferenceContext.asUndetVar(e), infer)) { infer.reportBoundError(uv, BoundErrorKind.EQ); } } } } + @Override boolean accepts(UndetVar uv, InferenceContext inferenceContext) { //applies to all undetvars @@ -594,12 +622,12 @@ for (Type e : uv.getBounds(InferenceBound.EQ)) { if (e.containsAny(inferenceContext.inferenceVars())) continue; for (Type u : uv.getBounds(InferenceBound.UPPER)) { - if (!isSubtype(e, inferenceContext.asFree(u), warn, infer)) { + if (!isSubtype(e, inferenceContext.asUndetVar(u), warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); } } for (Type l : uv.getBounds(InferenceBound.LOWER)) { - if (!isSubtype(inferenceContext.asFree(l), e, warn, infer)) { + if (!isSubtype(inferenceContext.asUndetVar(l), e, warn, infer)) { infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); } } @@ -615,7 +643,7 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { - isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn , infer); + isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn , infer); } } } @@ -629,7 +657,7 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { for (Type b2 : uv.getBounds(InferenceBound.EQ)) { - isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer); + isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer); } } } @@ -643,12 +671,59 @@ Infer infer = inferenceContext.infer(); for (Type b1 : uv.getBounds(InferenceBound.EQ)) { for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { - isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer); + isSubtype(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), warn, infer); } } } }, /** + * Given a bound set containing {@code alpha <: P} and + * {@code alpha <: P} where P is a parameterized type, + * perform {@code T = S} (which could lead to new bounds). + */ + CROSS_UPPER_UPPER() { + @Override + public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { + Infer infer = inferenceContext.infer(); + List boundList = uv.getBounds(InferenceBound.UPPER); + List boundListTail = boundList.tail; + while (boundList.nonEmpty()) { + List tmpTail = boundListTail; + while (tmpTail.nonEmpty()) { + Type b1 = boundList.head; + Type b2 = tmpTail.head; + if (b1 != b2) { + Pair commonSupers = infer.getParameterizedSupers(b1, b2); + if (commonSupers != null) { + List allParamsSuperBound1 = commonSupers.fst.allparams(); + List allParamsSuperBound2 = commonSupers.snd.allparams(); + while (allParamsSuperBound1.nonEmpty() && allParamsSuperBound2.nonEmpty()) { + //traverse the list of all params comparing them + if (!allParamsSuperBound1.head.hasTag(WILDCARD) && + !allParamsSuperBound2.head.hasTag(WILDCARD)) { + isSameType(inferenceContext.asUndetVar(allParamsSuperBound1.head), + inferenceContext.asUndetVar(allParamsSuperBound2.head), infer); + } + allParamsSuperBound1 = allParamsSuperBound1.tail; + allParamsSuperBound2 = allParamsSuperBound2.tail; + } + Assert.check(allParamsSuperBound1.isEmpty() && allParamsSuperBound2.isEmpty()); + } + } + tmpTail = tmpTail.tail; + } + boundList = boundList.tail; + boundListTail = boundList.tail; + } + } + + @Override + boolean accepts(UndetVar uv, InferenceContext inferenceContext) { + return !uv.isCaptured() && + uv.getBounds(InferenceBound.UPPER).nonEmpty(); + } + }, + /** * Given a bound set containing {@code alpha == S} and {@code alpha == T} * perform {@code S == T} (which could lead to new bounds). */ @@ -658,7 +733,7 @@ for (Type b1 : uv.getBounds(InferenceBound.EQ)) { for (Type b2 : uv.getBounds(InferenceBound.EQ)) { if (b1 != b2) { - isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1), infer); + isSameType(inferenceContext.asUndetVar(b2), inferenceContext.asUndetVar(b1), infer); } } } @@ -673,7 +748,7 @@ Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.UPPER)) { if (inferenceContext.inferenceVars().contains(b)) { - UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); + UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b); if (uv2.isCaptured()) continue; //alpha <: beta //0. set beta :> alpha @@ -699,7 +774,7 @@ Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.LOWER)) { if (inferenceContext.inferenceVars().contains(b)) { - UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); + UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b); if (uv2.isCaptured()) continue; //alpha :> beta //0. set beta <: alpha @@ -725,7 +800,7 @@ Infer infer = inferenceContext.infer(); for (Type b : uv.getBounds(InferenceBound.EQ)) { if (inferenceContext.inferenceVars().contains(b)) { - UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); + UndetVar uv2 = (UndetVar)inferenceContext.asUndetVar(b); if (uv2.isCaptured()) continue; //alpha == beta //0. set beta == alpha @@ -1475,7 +1550,7 @@ StringBuilder buf = new StringBuilder(); String sep = ""; for (Type from : data) { - UndetVar uv = (UndetVar)inferenceContext.asFree(from); + UndetVar uv = (UndetVar)inferenceContext.asUndetVar(from); for (Type bound : uv.getBounds(InferenceBound.values())) { if (bound.containsAny(List.from(to.data))) { buf.append(sep); @@ -1684,7 +1759,7 @@ Set optDepsByNode = stuckDeps.get(i); for (Node n_j : nodes) { Type j = n_j.data.first(); - UndetVar uv_i = (UndetVar)inferenceContext.asFree(i); + UndetVar uv_i = (UndetVar)inferenceContext.asUndetVar(i); if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) { //update i's bound dependencies n_i.addDependency(DependencyKind.BOUND, n_j); @@ -1833,6 +1908,8 @@ }); } + /* Returns the corresponding inference variables. + */ private List filterVars(Filter fu) { ListBuffer res = new ListBuffer<>(); for (Type t : undetvars) { @@ -1890,14 +1967,14 @@ * undet vars (used ahead of subtyping/compatibility checks to allow propagation * of inference constraints). */ - final Type asFree(Type t) { + final Type asUndetVar(Type t) { return types.subst(t, inferencevars, undetvars); } - final List asFree(List ts) { + final List asUndetVars(List ts) { ListBuffer buf = new ListBuffer<>(); for (Type t : ts) { - buf.append(asFree(t)); + buf.append(asUndetVar(t)); } return buf.toList(); } @@ -2073,7 +2150,7 @@ private boolean solveBasic(List varsToSolve, EnumSet steps) { boolean changed = false; for (Type t : varsToSolve.intersect(restvars())) { - UndetVar uv = (UndetVar)asFree(t); + UndetVar uv = (UndetVar)asUndetVar(t); for (InferenceStep step : steps) { if (step.accepts(uv, this)) { uv.inst = step.solve(uv, this); diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2360,6 +2360,7 @@ /** Visitor method: Translate a single node. * Attach the source position from the old tree to its replacement tree. */ + @Override public T translate(T tree) { if (tree == null) { return null; diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Apr 30 23:59:45 2014 -0700 @@ -899,7 +899,7 @@ @Override public boolean compatible(Type found, Type req, Warner warn) { - found = pendingInferenceContext.asFree(found); + found = pendingInferenceContext.asUndetVar(found); req = infer.returnConstraintTarget(found, req); return super.compatible(found, req, warn); } @@ -936,8 +936,8 @@ public boolean compatible(Type found, Type req, Warner warn) { return strict ? - types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) : - types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn); + types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn) : + types.isConvertible(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn); } public void report(DiagnosticPosition pos, JCDiagnostic details) { @@ -1142,7 +1142,7 @@ Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); if (types.isSameTypes(desc_t.getParameterTypes(), - inferenceContext().asFree(desc_s.getParameterTypes()))) { + inferenceContext().asUndetVars(desc_s.getParameterTypes()))) { if (types.asSuper(t, s.tsym) != null || types.asSuper(s, t.tsym) != null) { result &= MostSpecificCheckContext.super.compatible(t, s, warn); @@ -1169,7 +1169,7 @@ Type desc_t = types.findDescriptorType(t); Type desc_s = types.findDescriptorType(s); if (types.isSameTypes(desc_t.getParameterTypes(), - inferenceContext().asFree(desc_s.getParameterTypes()))) { + inferenceContext().asUndetVars(desc_s.getParameterTypes()))) { if (types.asSuper(t, s.tsym) != null || types.asSuper(s, t.tsym) != null) { result &= MostSpecificCheckContext.super.compatible(t, s, warn); @@ -3152,7 +3152,7 @@ if (TreeInfo.isStaticSelector(referenceTree.expr, names) && argtypes.nonEmpty() && (argtypes.head.hasTag(NONE) || - types.isSubtypeUnchecked(inferenceContext.asFree(argtypes.head), site))) { + types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) { return new UnboundMethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); } else { @@ -4265,7 +4265,11 @@ } DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) { - return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn); + DeferredAttrContext parent = (pendingResult == null) + ? deferredAttr.emptyDeferredAttrContext + : pendingResult.checkContext.deferredAttrContext(); + return deferredAttr.new DeferredAttrContext(attrMode, sym, step, + inferenceContext, parent, warn); } /** diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Apr 30 23:59:45 2014 -0700 @@ -512,14 +512,14 @@ break; case CONSTANT_Fieldref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner); break; } case CONSTANT_Methodref: case CONSTANT_InterfaceMethodref: { ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = (NameAndType)readPool(getChar(index + 3)); + NameAndType nt = readNameAndType(getChar(index + 3)); poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner); break; } @@ -588,13 +588,34 @@ /** Read class entry. */ ClassSymbol readClassSymbol(int i) { - return (ClassSymbol) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof ClassSymbol)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Class_info", i); + return (ClassSymbol)obj; } /** Read name. */ Name readName(int i) { - return (Name) (readPool(i)); + Object obj = readPool(i); + if (obj != null && !(obj instanceof Name)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_Utf8_info or CONSTANT_String_info", i); + return (Name)obj; + } + + /** Read name and type. + */ + NameAndType readNameAndType(int i) { + Object obj = readPool(i); + if (obj != null && !(obj instanceof NameAndType)) + throw badClassFile("bad.const.pool.entry", + currentClassFile.toString(), + "CONSTANT_NameAndType_info", i); + return (NameAndType)obj; } /************************************************************************ @@ -1245,7 +1266,7 @@ sym.owner.members().remove(sym); ClassSymbol self = (ClassSymbol)sym; ClassSymbol c = readClassSymbol(nextChar()); - NameAndType nt = (NameAndType)readPool(nextChar()); + NameAndType nt = readNameAndType(nextChar()); if (c.members_field == null) throw badClassFile("bad.enclosing.class", self, c); diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2818,7 +2818,7 @@ } private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) { - super(new LVTBits(), syms, names); + super(new LVTBits(), syms, names, false); lvtInits = (LVTBits)inits; this.lvtRanges = lvtRanges; } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Apr 30 23:59:45 2014 -0700 @@ -3406,16 +3406,28 @@ * | ModifiersOpt * ( Type Ident * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) - * | VOID Ident MethodDeclaratorRest - * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) * | Ident ConstructorDeclaratorRest * | TypeParameters Ident ConstructorDeclaratorRest * | ClassOrInterfaceOrEnumDeclaration * ) * InterfaceBodyDeclaration = * ";" - * | ModifiersOpt Type Ident - * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) + * | ModifiersOpt + * ( Type Ident + * ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest ) + * | VOID Ident MethodDeclaratorRest + * | TypeParameters [Annotations] + * ( Type Ident MethodDeclaratorRest + * | VOID Ident VoidMethodDeclaratorRest + * ) + * | ClassOrInterfaceOrEnumDeclaration + * ) + * */ protected List classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { if (token.kind == SEMI) { @@ -3444,28 +3456,29 @@ } List annosAfterParams = annotationsOpt(Tag.ANNOTATION); + if (annosAfterParams.nonEmpty()) { + checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); + mods.annotations = mods.annotations.appendList(annosAfterParams); + if (mods.pos == Position.NOPOS) + mods.pos = mods.annotations.head.pos; + } + Token tk = token; pos = token.pos; JCExpression type; boolean isVoid = token.kind == VOID; if (isVoid) { - if (annosAfterParams.nonEmpty()) - illegal(annosAfterParams.head.pos); type = to(F.at(pos).TypeIdent(TypeTag.VOID)); nextToken(); } else { - if (annosAfterParams.nonEmpty()) { - checkAnnotationsAfterTypeParams(annosAfterParams.head.pos); - mods.annotations = mods.annotations.appendList(annosAfterParams); - if (mods.pos == Position.NOPOS) - mods.pos = mods.annotations.head.pos; - } // method returns types are un-annotated types type = unannotatedType(); } if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) error(pos, "invalid.meth.decl.ret.type.req"); + else if (annosAfterParams.nonEmpty()) + illegal(annosAfterParams.head.pos); return List.of(methodDeclaratorRest( pos, mods, null, names.init, typarams, isInterface, true, dc)); @@ -3497,13 +3510,9 @@ } /** MethodDeclaratorRest = - * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") + * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") * VoidMethodDeclaratorRest = - * FormalParameters [Throws TypeList] ( MethodBody | ";") - * InterfaceMethodDeclaratorRest = - * FormalParameters BracketsOpt [THROWS TypeList] ";" - * VoidInterfaceMethodDeclaratorRest = - * FormalParameters [THROWS TypeList] ";" + * FormalParameters [THROWS TypeList] ( MethodBody | ";") * ConstructorDeclaratorRest = * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody */ diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -735,6 +735,9 @@ bad return type in method reference\n\ {0} +compiler.err.lambda.body.neither.value.nor.void.compatible=\ + lambda body is neither value nor void compatible + # 0: list of type compiler.err.incompatible.thrown.types.in.mref=\ incompatible thrown types {0} in method reference @@ -1702,6 +1705,11 @@ cannot access {0}\n\ {1} +# 0: file name, 1: expected CP entry type, 2: constant pool index +compiler.misc.bad.const.pool.entry=\ + bad constant pool entry in {0}\n\ + expected {1} at index {2} + # 0: file name, 1: message segment compiler.misc.bad.class.file.header=\ bad class file: {0}\n\ diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java --- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,9 +56,9 @@ return null; } else { tree.accept(this); - JCTree result = this.result; + JCTree tmpResult = this.result; this.result = null; - return (T)result; // XXX cast + return (T)tmpResult; // XXX cast } } diff -r df2905323914 -r b5c2375893e2 src/share/classes/com/sun/tools/javadoc/JavadocTool.java --- a/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Wed Apr 30 11:17:22 2014 -0700 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Wed Apr 30 23:59:45 2014 -0700 @@ -68,6 +68,7 @@ final Messager messager; final JavadocClassReader javadocReader; final JavadocEnter javadocEnter; + final Set uniquefiles; /** * Construct a new JavaCompiler processor, using appropriately @@ -78,6 +79,7 @@ messager = Messager.instance0(context); javadocReader = JavadocClassReader.instance0(context); javadocEnter = JavadocEnter.instance0(context); + uniquefiles = new HashSet<>(); } /** @@ -148,9 +150,7 @@ String name = it.head; if (!docClasses && fm != null && name.endsWith(".java") && new File(name).exists()) { JavaFileObject fo = fm.getJavaFileObjects(name).iterator().next(); - docenv.notice("main.Loading_source_file", name); - JCCompilationUnit tree = parse(fo); - classTrees.append(tree); + parse(fo, classTrees, true); } else if (isValidPackageName(name)) { names = names.append(name); } else if (name.endsWith(".java")) { @@ -163,9 +163,7 @@ } } for (JavaFileObject fo: fileObjects) { - docenv.notice("main.Loading_source_file", fo.getName()); - JCCompilationUnit tree = parse(fo); - classTrees.append(tree); + parse(fo, classTrees, true); } if (!docClasses) { @@ -213,7 +211,7 @@ * .java files found in such a directory to args. */ private void parsePackageClasses(String name, - Iterable files, + List files, ListBuffer trees, List excludedPackages) throws IOException { @@ -221,7 +219,6 @@ return; } - boolean hasFiles = false; docenv.notice("main.Loading_source_files_for_package", name); if (files == null) { @@ -238,19 +235,22 @@ } files = lb.toList(); } + if (files.nonEmpty()) { + for (JavaFileObject fo : files) { + parse(fo, trees, false); + } + } else { + messager.warning(Messager.NOPOS, "main.no_source_files_for_package", + name.replace(File.separatorChar, '.')); + } + } - Set ufiles = new HashSet<>(); - for (JavaFileObject fo : files) { - if (ufiles.add(fo)) { // ignore duplicates - // messager.notice("main.Loading_source_file", fn); - trees.append(parse(fo)); - hasFiles = true; - } - } - - if (!hasFiles) { - messager.warning(Messager.NOPOS, "main.no_source_files_for_package", - name.replace(File.separatorChar, '.')); + private void parse(JavaFileObject fo, ListBuffer trees, + boolean trace) { + if (uniquefiles.add(fo)) { // ignore duplicates + if (trace) + docenv.notice("main.Loading_source_file", fo.getName()); + trees.append(parse(fo)); } } diff -r df2905323914 -r b5c2375893e2 test/com/sun/javadoc/testLinkOption/TestLinkOption.java --- a/test/com/sun/javadoc/testLinkOption/TestLinkOption.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/com/sun/javadoc/testLinkOption/TestLinkOption.java Wed Apr 30 23:59:45 2014 -0700 @@ -23,18 +23,20 @@ /* * @test - * @bug 4720957 5020118 8026567 + * @bug 4720957 5020118 8026567 8038976 * @summary Test to make sure that -link and -linkoffline link to - * right files. + * right files, and URLs with and without trailing slash are accepted. * @author jamieh * @library ../lib/ * @build JavadocTester TestLinkOption * @run main TestLinkOption */ +import java.io.File; + public class TestLinkOption extends JavadocTester { - private static final String BUG_ID = "4720957-5020118"; + private static final String BUG_ID = "4720957-5020118-8038976"; //Generate the documentation using -linkoffline and a URL as the first parameter. private static final String[] ARGS1 = new String[] { @@ -83,7 +85,34 @@ } }; private static final String[][] NEGATED_TEST2 = NO_TEST; - + /* + * Create the documentation using the -link option, vary the behavior with + * both trailing and no trailing slash. We are only interested in ensuring + * that the command executes with no errors or related warnings. + */ + static String[] createArguments(boolean withTrailingSlash) { + String packagePath = new File(BUG_ID + "-1").getAbsolutePath(); + String outputDirName = BUG_ID; + if (withTrailingSlash) { + // add the trailing slash, if it is not present! + if (!packagePath.endsWith(FS)) { + packagePath = packagePath + FS; + } + outputDirName = outputDirName + "-3"; + } else { + // remove the trailing slash, if it is present! + if (packagePath.endsWith(FS)) { + packagePath = packagePath.substring(0, packagePath.length() - 1); + } + outputDirName = outputDirName + "-4"; + } + String args[] = { + "-d", outputDirName, "-sourcepath", SRC_DIR, + "-link", "file:///" + packagePath, "-package", "pkg2" + }; + System.out.println("packagePath: " + packagePath); + return args; + } /** * The entry point of the test. * @param args the array of command line arguments. @@ -92,6 +121,12 @@ TestLinkOption tester = new TestLinkOption(); run(tester, ARGS1, TEST1, NEGATED_TEST1); run(tester, ARGS2, TEST2, NEGATED_TEST2); + tester.runJavadoc(createArguments(true)); // with trailing slash + tester.runJavadoc(createArguments(false)); // without trailing slash + tester.printSummary(); + if (tester.getWarningOutput().contains("warning - Error fetching URL")) { + throw new Error("URL rejected ?"); + } tester.printSummary(); } diff -r df2905323914 -r b5c2375893e2 test/tools/javac/DefiniteAssignment/T8039026.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/DefiniteAssignment/T8039026.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8039026 + * @summary Definitely unassigned field can be accessed + * @compile/fail/ref=T8039026.out -XDrawDiagnostics T8039026.java + */ + +public class T8039026 { + final int x,y,z; + final int a = this.y; // <- error + { + int b = true ? this.x : 0; // <- error + System.out.println(this.x); // <- error + this.y = 1; + } + T8039026() { + this.x = 1; // <- no error! + this.y = 1; // <- error + this.z = this.x; // <- no error + } +} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/DefiniteAssignment/T8039026.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/DefiniteAssignment/T8039026.out Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,4 @@ +T8039026.java:10:23: compiler.err.var.might.not.have.been.initialized: y +T8039026.java:12:28: compiler.err.var.might.not.have.been.initialized: x +T8039026.java:18:13: compiler.err.var.might.already.be.assigned: y +3 errors diff -r df2905323914 -r b5c2375893e2 test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/T8029002/MultipleUpperBoundsIncorporationTest.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8029002 + * @summary javac should take multiple upper bounds into account in incorporation + * @compile MultipleUpperBoundsIncorporationTest.java + */ + +import java.util.ArrayList; +import java.util.List; + +public class MultipleUpperBoundsIncorporationTest { + + static class TestCase1 { + interface Task {} + + class Comparator {} + + class CustomException extends Exception {} + + class TaskQueue> {} + + abstract class Test { + abstract > TaskQueue create(Comparator comparator); + + void f(Comparator> comp) { + TaskQueue> queue = create(comp); + queue.getClass(); + } + } + } + + static class TestCase2 { + public > E typedNull() { + return null; + } + + public void call() { + ArrayList list = typedNull(); + } + } + + static class TestCase3 { + interface I extends Iterable {} + + > Exp typedNull() { return null; } + I i = typedNull(); + } + +} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/typeAnnotations/newlocations/AfterMethodTypeParams.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8038788 + * @summary Verify proper handling of annotations after method's type parameters. + * @build AfterMethodTypeParams + * @run main AfterMethodTypeParams + */ + +import java.io.IOException; +import java.io.StringWriter; +import java.net.URI; +import java.util.*; + +import javax.lang.model.element.Name; +import javax.tools.*; + +import com.sun.source.tree.*; +import com.sun.source.util.*; + +public class AfterMethodTypeParams { + + public static void main(String... args) throws IOException { + new AfterMethodTypeParams().run(); + } + + void run() throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + + for (TestCase tc : testCases) { + String test = TEMPLATE.replace("CONTENT", tc.snippet); + List files = Arrays.asList(new MyFileObject(test)); + StringWriter out = new StringWriter(); + List options = Arrays.asList("-XDrawDiagnostics", "-XDshouldStopPolicy=FLOW"); + JavacTask task = (JavacTask) compiler.getTask(out, null, null, options, null, files); + + new TreePathScanner() { + boolean seenAnnotation; + @Override + public Void visitAnnotation(AnnotationTree node, Void p) { + Name name = ((IdentifierTree) node.getAnnotationType()).getName(); + seenAnnotation |= name.contentEquals("TA") || name.contentEquals("DA"); + return null; + } + @Override + public Void visitCompilationUnit(CompilationUnitTree node, Void p) { + super.visitCompilationUnit(node, p); + if (!seenAnnotation) + error(test, "Annotation was missing"); + return null; + } + }.scan(task.parse(), null); + + task.analyze(); + + if (!tc.error.equals(out.toString().trim())) { + error(test, "Incorrect errors: " + out.toString()); + } + } + + if (errors > 0) { + throw new IllegalStateException("Errors found"); + } + } + + int errors; + + void error(String code, String error) { + System.out.println("Error detected: " + error); + System.out.println("Code:"); + System.out.println(code); + errors++; + } + + static String TEMPLATE = + "import java.lang.annotation.*;\n" + + "public class Test {\n" + + " CONTENT\n" + + "}\n" + + "@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})\n" + + "@interface DA { }\n" + + "@Target(ElementType.TYPE_USE)\n" + + "@interface TA { }\n"; + + static class MyFileObject extends SimpleJavaFileObject { + final String text; + public MyFileObject(String text) { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + this.text = text; + } + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return text; + } + } + + static TestCase[] testCases = new TestCase[] { + new TestCase(" @DA int foo1() { return 0;}", ""), + new TestCase(" @DA void foo2() { }", ""), + new TestCase(" @TA int foo3() { return 0;}", ""), + new TestCase(" @TA void foo4() { }", + "Test.java:3:9: compiler.err.annotation.type.not.applicable"), + new TestCase(" @DA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"), + new TestCase(" @TA Test() { }", "Test.java:3:9: compiler.err.illegal.start.of.type"), + }; + + static class TestCase { + final String snippet; + final String error; + public TestCase(String snippet, String error) { + this.snippet = snippet; + this.error = error; + } + } +} + diff -r df2905323914 -r b5c2375893e2 test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java --- a/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java Wed Apr 30 23:59:45 2014 -0700 @@ -41,7 +41,7 @@ private void run() throws IOException, ConstantPoolException { File testClasses = new File(System.getProperty("test.classes")); - for (File classFile : testClasses.listFiles()) { + for (File classFile : testClasses.listFiles(f -> f.getName().endsWith(".class"))) { ClassFile cf = ClassFile.read(classFile); if (cf.getName().matches(".*\\$[0-9]+")) { EnclosingMethod_attribute encl = diff -r df2905323914 -r b5c2375893e2 test/tools/javac/diags/examples.not-yet.txt --- a/test/tools/javac/diags/examples.not-yet.txt Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/diags/examples.not-yet.txt Wed Apr 30 23:59:45 2014 -0700 @@ -111,3 +111,4 @@ compiler.warn.unknown.enum.constant.reason # in bad class file compiler.warn.override.equals.but.not.hashcode # when a class overrides equals but not hashCode method from Object compiler.err.cant.inherit.from.anon # error for subclass of anonymous class +compiler.misc.bad.const.pool.entry # constant pool entry has wrong type diff -r df2905323914 -r b5c2375893e2 test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/diags/examples/LambdaBodyNeitherValueNorVoidCompatible.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.lambda.body.neither.value.nor.void.compatible +// key: compiler.err.cant.apply.symbol +// key: compiler.misc.incompatible.ret.type.in.lambda +// key: compiler.misc.missing.ret.val +// key: compiler.misc.no.conforming.assignment.exists + +class LambdaBodyNeitherValueNorVoidCompatible { + interface I { + String f(String x); + } + + static void foo(I i) {} + + void m() { + foo((x) -> { + if (x == null) { + return; + } else { + return x; + } + }); + } +} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/ErroneousLambdaExpr.java --- a/test/tools/javac/lambda/ErroneousLambdaExpr.java Wed Apr 30 11:17:22 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * 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 - * 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 8003280 - * @summary Add lambda tests - * stale state after speculative attribution round leads to missing classfiles - * @compile/fail/ref=ErroneousLambdaExpr.out -XDrawDiagnostics ErroneousLambdaExpr.java - */ -public class ErroneousLambdaExpr { - - static int assertionCount = 0; - - static void assertTrue(boolean cond) { - assertionCount++; - if (!cond) - throw new AssertionError(); - } - - interface SAM1 { - X m(X t, String s); - } - - interface SAM2 { - void m(String s, int i); - } - - interface SAM3 { - X m(X t, String s, int i); - } - - void call(SAM1 s1) { assertTrue(true); } - - void call(SAM2 s2) { assertTrue(false); } - - void call(SAM3 s3) { assertTrue(false); } - - public static void main(String[] args) { - ErroneousLambdaExpr test = - new ErroneousLambdaExpr<>(); - - test.call((builder, string) -> { builder.append(string); return builder; }); - assertTrue(assertionCount == 1); - } -} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/ErroneousLambdaExpr.out --- a/test/tools/javac/lambda/ErroneousLambdaExpr.out Wed Apr 30 11:17:22 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -ErroneousLambdaExpr.java:63:13: compiler.err.ref.ambiguous: call, kindname.method, call(ErroneousLambdaExpr.SAM1), ErroneousLambdaExpr, kindname.method, call(ErroneousLambdaExpr.SAM2), ErroneousLambdaExpr -1 error diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/LambdaExprLeadsToMissingClassFilesTest.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8003280 + * @summary Add lambda tests + * stale state after speculative attribution round leads to missing classfiles + */ +public class LambdaExprLeadsToMissingClassFilesTest { + + static int assertionCount = 0; + + static void assertTrue(boolean cond) { + assertionCount++; + if (!cond) { + throw new AssertionError(); + } + } + + interface SAM1 { + X m(X t, String s); + } + + interface SAM2 { + void m(String s, int i); + } + + interface SAM3 { + X m(X t, String s, int i); + } + + void call(SAM1 s1) { assertTrue(true); } + + void call(SAM2 s2) { assertTrue(false); } + + void call(SAM3 s3) { assertTrue(false); } + + public static void main(String[] args) { + LambdaExprLeadsToMissingClassFilesTest test = + new LambdaExprLeadsToMissingClassFilesTest<>(); + + test.call((builder, string) -> { builder.append(string); return builder; }); + assertTrue(assertionCount == 1); + } +} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/MostSpecific09.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MostSpecific09.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,81 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8029718 + * @summary Should always use lambda body structure to disambiguate overload resolution + * @compile/fail/ref=MostSpecific09.out -XDrawDiagnostics -XDshouldStopPolicy=ATTR -XDverboseResolution=applicable,success MostSpecific09.java + */ + +class MostSpecific09 { + + interface I { + String xoo(String x); + } + + interface J { + void xoo(int x); + } + + static void foo(I i) {} + static void foo(J j) {} + + static void moo(I i) {} + static void moo(J j) {} + + void m() { + foo((x) -> { return x += 1; }); + foo((x) -> { return ""; }); + foo((x) -> { System.out.println(""); }); + foo((x) -> { return ""; System.out.println(""); }); + foo((x) -> { throw new RuntimeException(); }); + foo((x) -> { while (true); }); + + foo((x) -> x += 1); + foo((x) -> ""); + } + + /* any return statement that is not in the body of the lambda but in an + * inner class or another lambda should be ignored for value void compatibility + * determination. + */ + void m1() { + boolean cond = true; + foo((x) -> { + if (cond) { + return ""; + } + System.out.println(""); + }); + + foo((x)->{ + class Bar { + String m() { + return "from Bar.m()"; + } + } + class Boo { + Bar b = new Bar (){ + String m() { + return "from Bar$1.m()"; + } + }; + } + moo((y) -> { return ""; }); + return; + }); + + foo((x)->{ + class Bar { + void m() {} + } + class Boo { + Bar b = new Bar (){ + void m() { + return; + } + }; + } + moo((y) -> { System.out.println(""); }); + return ""; + }); + } +} diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/MostSpecific09.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/MostSpecific09.out Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,27 @@ +MostSpecific09.java:25:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:26:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:27:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)} +MostSpecific09.java:27:32: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:28:13: compiler.err.lambda.body.neither.value.nor.void.compatible +MostSpecific09.java:28:9: compiler.err.cant.apply.symbols: kindname.method, foo, @680,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))} +MostSpecific09.java:28:43: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:29:28: compiler.note.verbose.resolve.multi: , java.lang.RuntimeException, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, java.lang.RuntimeException(), null)} +MostSpecific09.java:30:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:32:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09 +MostSpecific09.java:33:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:42:13: compiler.err.lambda.body.neither.value.nor.void.compatible +MostSpecific09.java:42:9: compiler.err.cant.apply.symbols: kindname.method, foo, @1129,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))} +MostSpecific09.java:46:23: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +MostSpecific09.java:49:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)} +MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:56:35: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:56:25: compiler.note.verbose.resolve.multi: , compiler.misc.anonymous.class: MostSpecific09$1Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$1Boo$1(), null)} +MostSpecific09.java:62:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.I), null)} +MostSpecific09.java:66:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)} +MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:71:35: compiler.note.verbose.resolve.multi: , Bar, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, Bar(), null)} +MostSpecific09.java:71:25: compiler.note.verbose.resolve.multi: , compiler.misc.anonymous.class: MostSpecific09$2Boo$1, 0, BASIC, compiler.misc.no.args, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, compiler.misc.anonymous.class: MostSpecific09$2Boo$1(), null)} +MostSpecific09.java:77:13: compiler.note.verbose.resolve.multi: moo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, moo(MostSpecific09.J), null)} +MostSpecific09.java:77:36: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)} +7 errors diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType01.java --- a/test/tools/javac/lambda/TargetType01.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType01.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,10 @@ static String M(F_S_S f){ return null; } static { - M(x1 -> { return M( x2 -> { return x1 + x2; });}); //ambiguous + M(x1 -> { + return M( x2 -> { + return x1 + x2; + }); + }); //ambiguous } } diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType01.out --- a/test/tools/javac/lambda/TargetType01.out Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType01.out Wed Apr 30 23:59:45 2014 -0700 @@ -1,3 +1,3 @@ TargetType01.java:45:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 -TargetType01.java:45:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01 +TargetType01.java:46:20: 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 df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType02.java --- a/test/tools/javac/lambda/TargetType02.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType02.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,31 +1,9 @@ /* - * 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 - * 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 8003280 + * @test /nodynamiccopyright/ + * @bug 8003280 8029718 * @summary Add lambda tests * check overload resolution and target type inference w.r.t. generic methods + * Should always use lambda body structure to disambiguate overload resolution * @author Maurizio Cimadamore * @compile/fail/ref=TargetType02.out -XDrawDiagnostics TargetType02.java */ @@ -47,9 +25,18 @@ static void call3(S1 s) { } static void call3(S2 s) { } + static Z call4(S1 s) { return null; } + static Z call4(S2 s) { return null; } + void test() { call1(i -> { toString(); return i; }); call2(i -> { toString(); return i; }); call3(i -> { toString(); return i; }); + call3(i -> { + toString(); + return call4(j -> { + return j; + }); + }); } } diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType02.out --- a/test/tools/javac/lambda/TargetType02.out Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType02.out Wed Apr 30 23:59:45 2014 -0700 @@ -1,3 +1,5 @@ -TargetType02.java:52:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String) -TargetType02.java:53:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 -2 errors +TargetType02.java:33:14: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, java.lang.String) +TargetType02.java:34:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 +TargetType02.java:35:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(TargetType02.S1), TargetType02, kindname.method, call3(TargetType02.S2), TargetType02 +TargetType02.java:37:20: compiler.err.ref.ambiguous: call4, kindname.method, call4(TargetType02.S1), TargetType02, kindname.method, call4(TargetType02.S2), TargetType02 +4 errors diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType21.out --- a/test/tools/javac/lambda/TargetType21.out Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType21.out Wed Apr 30 23:59:45 2014 -0700 @@ -1,7 +1,5 @@ TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:31:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))) -TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM2), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 -TargetType21.java:33:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM2, @946, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))) -6 errors +TargetType21.java:32:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +TargetType21.java:32:13: compiler.err.cant.apply.symbol: kindname.method, call, TargetType21.SAM1, @888, kindname.class, TargetType21, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String))) +TargetType21.java:33:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM3), TargetType21 +4 errors diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/TargetType42.java --- a/test/tools/javac/lambda/TargetType42.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/TargetType42.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,18 @@ class TargetType42 { interface SAM { - Y f(X x); + Y f(X x); } void m(SAM> s, Z z) { } void test(Object obj) { - m((x)->{ class Foo { }; return (x2)-> { new Foo(); return null; }; }, obj); + m((x)->{ + class Foo { } + return (x2)-> { + new Foo(); + return null; + }; + }, obj); } } diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/lambdaExpression/LambdaTest1.java --- a/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.List; import java.util.ArrayList; -import java.util.Date; public class LambdaTest1 { diff -r df2905323914 -r b5c2375893e2 test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java --- a/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Wed Apr 30 23:59:45 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -209,7 +209,11 @@ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); DiagnosticChecker dc = new DiagnosticChecker(); JavacTask ct = (JavacTask)tool.getTask(null, null, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile)); - ct.analyze(); + try { + ct.analyze(); + } catch (Exception e) { + throw new AssertionError("failing SAM source file \n" + samSourceFile + "\n\n" + "failing client source file \n"+ clientSourceFile); + } if (dc.errorFound == checkSamConversion()) { throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile); } diff -r df2905323914 -r b5c2375893e2 test/tools/javac/processing/environment/round/ErroneousAnnotations.out --- a/test/tools/javac/processing/environment/round/ErroneousAnnotations.out Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/processing/environment/round/ErroneousAnnotations.out Wed Apr 30 23:59:45 2014 -0700 @@ -1,4 +1,3 @@ ErroneousAnnotations.java:8:2: compiler.err.cant.resolve: kindname.class, Undefined, , ErroneousAnnotations.java:10:6: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, ErroneousAnnotations, null) 2 errors -Results: [] diff -r df2905323914 -r b5c2375893e2 test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java --- a/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java Wed Apr 30 23:59:45 2014 -0700 @@ -93,7 +93,8 @@ roundEnvironment. getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); - System.err.println("Results: " + resultsMeta); + if (!resultsMeta.isEmpty()) + System.err.println("Results: " + resultsMeta); if (resultsMeta.size() != annotatedElementInfo.expectedSize()) { failed = true; diff -r df2905323914 -r b5c2375893e2 test/tools/javadoc/parser/7091528/T7091528.java --- a/test/tools/javadoc/parser/7091528/T7091528.java Wed Apr 30 11:17:22 2014 -0700 +++ b/test/tools/javadoc/parser/7091528/T7091528.java Wed Apr 30 23:59:45 2014 -0700 @@ -23,7 +23,7 @@ /** * @test - * @bug 7091528 8029145 + * @bug 7091528 8029145 8037484 * @summary ensures javadoc parses unique source files and ignores all class files * @compile p/C1.java p/q/C2.java * @run main T7091528 @@ -50,6 +50,16 @@ "-sourcepath", testSrc.getAbsolutePath(), "-subpackages", "p:p.q"); + File testPkgDir = new File(testSrc, "p"); + File testFile = new File(testPkgDir, "C3.java"); + runTest("-d", ".", + "-sourcepath", testSrc.getAbsolutePath(), + testFile.getAbsolutePath(), + "p"); + runTest("-d", ".", + "-classpath", testSrc.getAbsolutePath(), + testFile.getAbsolutePath(), + "p"); } void runTest(String... args) { @@ -65,7 +75,7 @@ } if (rc != 0) - System.err.println("javadoc failed: exit code = " + rc); + throw new Error("javadoc failed: exit code = " + rc); if (out.matches("(?s).*p/[^ ]+\\.class.*")) throw new Error("reading .class files"); diff -r df2905323914 -r b5c2375893e2 test/tools/javadoc/parser/7091528/p/C3.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javadoc/parser/7091528/p/C3.java Wed Apr 30 23:59:45 2014 -0700 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** This is class C3, and no package for me please */ +public class C3 {} +