diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java index d49624f6843e0f311bde6a149ec0e4e8a6974b4e..6678d48c062a8731842d8bcaf401978ac93bc1ff 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2391,7 +2391,8 @@ public class Attr extends JCTree.Visitor { 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))); + .report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params), + deferredDiag)); //hidden diag parameter //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 diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 03ae28854c2826b0bcc2ffe392f6d7314b3e4ac3..de949a7a243a4902bc67c853d1b5fb1a7097339d 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -37,7 +37,10 @@ import com.sun.tools.javac.comp.DeferredAttr.DeferredType; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Infer.FreeTypeListener; import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; +import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.DiagnosticRewriter; +import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template; import com.sun.tools.javac.jvm.*; +import com.sun.tools.javac.main.Option; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind; @@ -94,6 +97,7 @@ public class Resolve { public final boolean allowDefaultMethods; public final boolean allowStructuralMostSpecific; private final boolean debugResolve; + private final boolean compactMethodDiags; final EnumSet verboseResolutionMode; Scope polymorphicSignatureScope; @@ -124,6 +128,8 @@ public class Resolve { varargsEnabled = source.allowVarargs(); Options options = Options.instance(context); debugResolve = options.isSet("debugresolve"); + compactMethodDiags = options.isSet(Option.XDIAGS, "compact") || + options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics"); verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); Target target = Target.instance(context); allowMethodHandles = target.hasMethodHandles(); @@ -661,6 +667,10 @@ public class Resolve { this.basicKey = basicKey; this.inferKey = inferKey; } + + String regex() { + return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey); + } } /** @@ -691,6 +701,7 @@ public class Resolve { Warner warn) { //should we expand formals? boolean useVarargs = deferredAttrContext.phase.isVarargsRequired(); + List trees = TreeInfo.args(env.tree); //inference context used during this method check InferenceContext inferenceContext = deferredAttrContext.inferenceContext; @@ -699,17 +710,19 @@ public class Resolve { if (varargsFormal == null && argtypes.size() != formals.size()) { - reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } while (argtypes.nonEmpty() && formals.head != varargsFormal) { - checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn); + DiagnosticPosition pos = trees != null ? trees.head : null; + checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn); argtypes = argtypes.tail; formals = formals.tail; + trees = trees != null ? trees.tail : trees; } if (formals.head != varargsFormal) { - reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args + reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args } if (useVarargs) { @@ -717,8 +730,10 @@ public class Resolve { //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5) final Type elt = types.elemtype(varargsFormal); while (argtypes.nonEmpty()) { - checkArg(true, argtypes.head, elt, deferredAttrContext, warn); + DiagnosticPosition pos = trees != null ? trees.head : null; + checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn); argtypes = argtypes.tail; + trees = trees != null ? trees.tail : trees; } } } @@ -726,9 +741,9 @@ public class Resolve { /** * Does the actual argument conforms to the corresponding formal? */ - abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); + abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn); - protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { + protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) { boolean inferDiag = inferenceContext != infer.emptyContext; InapplicableMethodException ex = inferDiag ? infer.inferenceException : inapplicableMethodException; @@ -738,7 +753,8 @@ public class Resolve { args2[0] = inferenceContext.inferenceVars(); args = args2; } - throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args); + String key = inferDiag ? diag.inferKey : diag.basicKey; + throw ex.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)); } public MethodCheck mostSpecificCheck(List actuals, boolean strict) { @@ -752,7 +768,7 @@ public class Resolve { */ MethodCheck arityMethodCheck = new AbstractMethodCheck() { @Override - void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { + void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { //do nothing - actual always compatible to formals } }; @@ -778,9 +794,9 @@ public class Resolve { MethodCheck resolveMethodCheck = new AbstractMethodCheck() { @Override - void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { + void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) { ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn); - mresult.check(null, actual); + mresult.check(pos, actual); } @Override @@ -809,7 +825,7 @@ public class Resolve { } else { if (!isAccessible(env, t)) { Symbol location = env.enclClass.sym; - reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); + reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location); } } } @@ -822,7 +838,7 @@ public class Resolve { @Override public void report(DiagnosticPosition pos, JCDiagnostic details) { - reportMC(methodDiag, deferredAttrContext.inferenceContext, details); + reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details); } }; return new MethodResultInfo(to, checkContext); @@ -3327,6 +3343,18 @@ public class Resolve { } else { Candidate c = errCandidate(); + if (compactMethodDiags) { + for (Map.Entry _entry : + MethodResolutionDiagHelper.rewriters.entrySet()) { + if (_entry.getKey().matches(c.details)) { + JCDiagnostic simpleDiag = + _entry.getValue().rewriteDiagnostic(diags, pos, + log.currentSource(), dkind, c.details); + simpleDiag.setFlag(DiagnosticFlag.COMPRESSED); + return simpleDiag; + } + } + } Symbol ws = c.sym.asMemberOf(site, types); return diags.create(dkind, log.currentSource(), pos, "cant.apply.symbol", @@ -3375,35 +3403,75 @@ public class Resolve { Name name, List argtypes, List typeargtypes) { - if (!resolveContext.candidates.isEmpty()) { + Map candidatesMap = mapCandidates(); + Map filteredCandidates = filterCandidates(candidatesMap); + if (filteredCandidates.isEmpty()) { + filteredCandidates = candidatesMap; + } + boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size(); + if (filteredCandidates.size() > 1) { JCDiagnostic err = diags.create(dkind, + null, + truncatedDiag ? + EnumSet.of(DiagnosticFlag.COMPRESSED) : + EnumSet.noneOf(DiagnosticFlag.class), log.currentSource(), pos, "cant.apply.symbols", name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), name == names.init ? site.tsym.name : name, methodArguments(argtypes)); - return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); + return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site)); + } else if (filteredCandidates.size() == 1) { + JCDiagnostic d = new InapplicableSymbolError(resolveContext).getDiagnostic(dkind, pos, + location, site, name, argtypes, typeargtypes); + if (truncatedDiag) { + d.setFlag(DiagnosticFlag.COMPRESSED); + } + return d; } else { return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes); } } - //where - List candidateDetails(Type site) { - Map details = new LinkedHashMap(); - for (Candidate c : resolveContext.candidates) { - if (c.isApplicable()) continue; - JCDiagnostic detailDiag = diags.fragment("inapplicable.method", - Kinds.kindName(c.sym), - c.sym.location(site, types), - c.sym.asMemberOf(site, types), - c.details); - details.put(c.sym, detailDiag); + private Map mapCandidates() { + Map candidates = new LinkedHashMap(); + for (Candidate c : resolveContext.candidates) { + if (c.isApplicable()) continue; + candidates.put(c.sym, c.details); + } + return candidates; + } + + Map filterCandidates(Map candidatesMap) { + Map candidates = new LinkedHashMap(); + for (Map.Entry _entry : candidatesMap.entrySet()) { + JCDiagnostic d = _entry.getValue(); + if (!compactMethodDiags || + !new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) { + candidates.put(_entry.getKey(), d); + } + } + return candidates; + } + + private List candidateDetails(Map candidatesMap, Type site) { + List details = List.nil(); + for (Map.Entry _entry : candidatesMap.entrySet()) { + Symbol sym = _entry.getKey(); + JCDiagnostic detailDiag = diags.fragment("inapplicable.method", + Kinds.kindName(sym), + sym.location(site, types), + sym.asMemberOf(site, types), + _entry.getValue()); + details = details.prepend(detailDiag); + } + //typically members are visited in reverse order (see Scope) + //so we need to reverse the candidate list so that candidates + //conform to source order + return details; } - return List.from(details.values()); - } } /** @@ -3624,6 +3692,105 @@ public class Resolve { } } + /** + * Helper class for method resolution diagnostic simplification. + * Certain resolution diagnostic are rewritten as simpler diagnostic + * where the enclosing resolution diagnostic (i.e. 'inapplicable method') + * is stripped away, as it doesn't carry additional info. The logic + * for matching a given diagnostic is given in terms of a template + * hierarchy: a diagnostic template can be specified programmatically, + * so that only certain diagnostics are matched. Each templete is then + * associated with a rewriter object that carries out the task of rewtiting + * the diagnostic to a simpler one. + */ + static class MethodResolutionDiagHelper { + + /** + * A diagnostic rewriter transforms a method resolution diagnostic + * into a simpler one + */ + interface DiagnosticRewriter { + JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, + DiagnosticPosition preferedPos, DiagnosticSource preferredSource, + DiagnosticType preferredKind, JCDiagnostic d); + } + + /** + * A diagnostic template is made up of two ingredients: (i) a regular + * expression for matching a diagnostic key and (ii) a list of sub-templates + * for matching diagnostic arguments. + */ + static class Template { + + /** regex used to match diag key */ + String regex; + + /** templates used to match diagnostic args */ + Template[] subTemplates; + + Template(String key, Template... subTemplates) { + this.regex = key; + this.subTemplates = subTemplates; + } + + /** + * Returns true if the regex matches the diagnostic key and if + * all diagnostic arguments are matches by corresponding sub-templates. + */ + boolean matches(Object o) { + JCDiagnostic d = (JCDiagnostic)o; + Object[] args = d.getArgs(); + if (!d.getCode().matches(regex) || + subTemplates.length != d.getArgs().length) { + return false; + } + for (int i = 0; i < args.length ; i++) { + if (!subTemplates[i].matches(args[i])) { + return false; + } + } + return true; + } + } + + /** a dummy template that match any diagnostic argument */ + static final Template skip = new Template("") { + @Override + boolean matches(Object d) { + return true; + } + }; + + /** rewriter map used for method resolution simplification */ + static final Map rewriters = + new LinkedHashMap(); + + static { + String argMismatchRegex = MethodCheckDiag.ARG_MISMATCH.regex(); + rewriters.put(new Template(argMismatchRegex, new Template("(.*)(bad.arg.types.in.lambda)", skip, skip)), + new DiagnosticRewriter() { + @Override + public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, + DiagnosticPosition preferedPos, DiagnosticSource preferredSource, + DiagnosticType preferredKind, JCDiagnostic d) { + return (JCDiagnostic)((JCDiagnostic)d.getArgs()[0]).getArgs()[1]; + } + }); + + rewriters.put(new Template(argMismatchRegex, skip), + new DiagnosticRewriter() { + @Override + public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags, + DiagnosticPosition preferedPos, DiagnosticSource preferredSource, + DiagnosticType preferredKind, JCDiagnostic d) { + JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0]; + return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(), + "prob.found.req", cause); + } + }); + } + } + enum MethodResolutionPhase { BASIC(false, false), BOX(true, false), diff --git a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 9463d10c99785a9281b8fc161dfbf555d2f01653..291a34142053f3df12f3a244b0e583c3f0c037ec 100644 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -1614,6 +1614,9 @@ public class JavaCompiler implements ClassReader.SourceCompleter { log.warning("proc.use.proc.or.implicit"); } chk.reportDeferredDiagnostics(); + if (log.compressedOutput) { + log.mandatoryNote(null, "compressed.diags"); + } } /** Close the compiler, flushing the logs diff --git a/src/share/classes/com/sun/tools/javac/main/Option.java b/src/share/classes/com/sun/tools/javac/main/Option.java index b6bfa33ae0829f05e3fd1e39d292e57ece5e07ca..dd3bbe80c6b4eaaba1381aa9bc70c787e54296a3 100644 --- a/src/share/classes/com/sun/tools/javac/main/Option.java +++ b/src/share/classes/com/sun/tools/javac/main/Option.java @@ -407,6 +407,8 @@ public enum Option { } }, + XDIAGS("-Xdiags:", "opt.diags", EXTENDED, BASIC, ONEOF, "compact", "verbose"), + /* This is a back door to the compiler's option table. * -XDx=y sets the option x to the value y. * -XDx sets the option x to the value x. diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 8df3a0a4b58e42d967ac3108f219802037bf5559..192780ab95620b339685bfc17c164be9f6368876 100644 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -227,11 +227,13 @@ compiler.misc.not.an.intf.component=\ # 0: symbol kind, 1: message segment compiler.err.invalid.mref=\ - invalid {0} reference; {1} + invalid {0} reference\n\ + {1} # 0: symbol kind, 1: message segment compiler.misc.invalid.mref=\ - invalid {0} reference; {1} + invalid {0} reference\n\ + {1} compiler.misc.static.mref.with.targs=\ parameterized qualifier on static method reference @@ -714,7 +716,8 @@ compiler.err.neither.conditional.subtype=\ # 0: message segment compiler.misc.incompatible.type.in.conditional=\ - bad type in conditional expression; {0} + bad type in conditional expression\n\ + {0} compiler.misc.conditional.target.cant.be.void=\ target-type for conditional expression cannot be void @@ -743,7 +746,7 @@ compiler.misc.incompatible.arg.types.in.lambda=\ compiler.misc.incompatible.arg.types.in.mref=\ incompatible parameter types in method reference -# 0: list of type +# 0: list of type, 1: message segment compiler.misc.bad.arg.types.in.lambda=\ cannot type-check lambda expression with inferred parameter types\n\ inferred types: {0} @@ -1154,6 +1157,9 @@ compiler.misc.x.print.rounds=\ ## The following string will appear before all messages keyed as: ## "compiler.note". +compiler.note.compressed.diags=\ + Some messages have been simplified; recompile with -Xdiags:verbose to get full output + compiler.note.potential.lambda.found=\ This anonymous inner class creation can be turned into a lambda expression. @@ -1742,6 +1748,10 @@ compiler.err.not.within.bounds=\ compiler.err.prob.found.req=\ incompatible types: {0} +# 0: message segment +compiler.misc.prob.found.req=\ + incompatible types: {0} + # 0: message segment, 1: type, 2: type compiler.warn.prob.found.req=\ {0}\n\ diff --git a/src/share/classes/com/sun/tools/javac/resources/javac.properties b/src/share/classes/com/sun/tools/javac/resources/javac.properties index 490a9276cee56d21569efc7491bcea0652359682..caf67462a8245068173d471b61704cd89b535e66 100644 --- a/src/share/classes/com/sun/tools/javac/resources/javac.properties +++ b/src/share/classes/com/sun/tools/javac/resources/javac.properties @@ -168,6 +168,8 @@ javac.opt.prefer=\ Specify which file to read when both a source file and class file are found for an implicitly compiled class javac.opt.AT=\ Read options and filenames from file +javac.opt.diags=\ + Select a diagnostic mode ## errors diff --git a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java index b1e7700e83cadbb8dd0b38e7365357d3e54bd53e..f49331795fd67f138cc9f8ceb91dca4f70287410 100644 --- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java +++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java @@ -349,6 +349,7 @@ public class JCDiagnostic implements Diagnostic { SYNTAX, RECOVERABLE, NON_DEFERRABLE, + COMPRESSED } private final DiagnosticType type; diff --git a/src/share/classes/com/sun/tools/javac/util/List.java b/src/share/classes/com/sun/tools/javac/util/List.java index 93e2c3a3ec670eb1bfa35ceb8a71a8d3fab13d6d..611798d9caaf6d40ca7e5c79a053927873063bb4 100644 --- a/src/share/classes/com/sun/tools/javac/util/List.java +++ b/src/share/classes/com/sun/tools/javac/util/List.java @@ -154,11 +154,11 @@ public class List extends AbstractCollection implements java.util.List } public static List from(Iterable coll) { - List xs = nil(); + ListBuffer xs = ListBuffer.lb(); for (A a : coll) { - xs = new List(a, xs); + xs.append(a); } - return xs; + return xs.toList(); } /** Construct a list consisting of a given number of identical elements. diff --git a/src/share/classes/com/sun/tools/javac/util/Log.java b/src/share/classes/com/sun/tools/javac/util/Log.java index c2f42fe5a2867ecc87db3aa9e5bd3867088b9a6e..5ed6d7841039f5af5abbcfa21e7cf6d5475bcedb 100644 --- a/src/share/classes/com/sun/tools/javac/util/Log.java +++ b/src/share/classes/com/sun/tools/javac/util/Log.java @@ -213,6 +213,11 @@ public class Log extends AbstractLog { */ public Set expectDiagKeys; + /** + * Set to true if a compressed diagnostic is reported + */ + public boolean compressedOutput; + /** * JavacMessages object used for localization. */ @@ -597,6 +602,9 @@ public class Log extends AbstractLog { } break; } + if (diagnostic.isFlagSet(JCDiagnostic.DiagnosticFlag.COMPRESSED)) { + compressedOutput = true; + } } } diff --git a/test/tools/javac/Diagnostics/compressed/T8012003a.java b/test/tools/javac/Diagnostics/compressed/T8012003a.java new file mode 100644 index 0000000000000000000000000000000000000000..97729648cdc5fa2c8e154ab83c40148f2bf972b0 --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003a.java @@ -0,0 +1,24 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8012003 + * @summary Method diagnostics resolution need to be simplified in some cases + * test general overload resolution simplifications + * @compile/fail/ref=T8012003a.out -XDrawDiagnostics -Xdiags:compact T8012003a.java + */ + +class T8012003a { + void m1(Integer i) { } + + void m2(Integer i) { } + void m2(Integer i, Object o) { } + + void m3(Integer i) { } + void m3(String s) { } + + void test() { + m1(""); + m1(false ? "" : ""); + m2(""); + m3('x'); + } +} diff --git a/test/tools/javac/Diagnostics/compressed/T8012003a.out b/test/tools/javac/Diagnostics/compressed/T8012003a.out new file mode 100644 index 0000000000000000000000000000000000000000..b12871661d8922e6f251498fe79b286aad67836a --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003a.out @@ -0,0 +1,6 @@ +T8012003a.java:19:12: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer) +T8012003a.java:20:20: compiler.err.prob.found.req: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)) +T8012003a.java:21:12: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer) +T8012003a.java:22:9: compiler.err.cant.apply.symbols: kindname.method, m3, char,{(compiler.misc.inapplicable.method: kindname.method, T8012003a, m3(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: char, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, T8012003a, m3(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: char, java.lang.String)))} +- compiler.note.compressed.diags +4 errors diff --git a/test/tools/javac/Diagnostics/compressed/T8012003b.java b/test/tools/javac/Diagnostics/compressed/T8012003b.java new file mode 100644 index 0000000000000000000000000000000000000000..f5fbeb0dd223f5ffd20c3be29c42c9ac49a7978e --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003b.java @@ -0,0 +1,37 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8012003 + * @summary Method diagnostics resolution need to be simplified in some cases + * test lambda-related overload resolution simplifications + * @compile/fail/ref=T8012003b.out -XDrawDiagnostics -Xdiags:compact T8012003b.java + */ + +class T8012003b { + + interface Consumer_V { + void m(X x); + } + + interface Consumer_NV { + Integer m(X x); + } + + void m1(Runnable r) { } + void m1(Runnable r, String s) { } + + void m2(Consumer_V ci) { } + + void m3(Consumer_NV ci) { } + + void g(String arg) { } + String g2(String arg) { return arg; } + + void test() { + m1(this::g); + m1(()->1); + m1(()->false ? "" : ""); + m2(this::g); + m3(this::g2); + m3(this::k); + } +} diff --git a/test/tools/javac/Diagnostics/compressed/T8012003b.out b/test/tools/javac/Diagnostics/compressed/T8012003b.out new file mode 100644 index 0000000000000000000000000000000000000000..246900b8f49e4ab21adfb37cb4ec527d92265fcf --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003b.out @@ -0,0 +1,8 @@ +T8012003b.java:30:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, java.lang.String, compiler.misc.no.args, kindname.class, T8012003b, (compiler.misc.arg.length.mismatch))) +T8012003b.java:31:16: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void)) +T8012003b.java:32:22: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.conditional.target.cant.be.void)) +T8012003b.java:33:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.String))) +T8012003b.java:34:12: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)) +T8012003b.java:35:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, k, , , (compiler.misc.location: kindname.class, T8012003b, null)) +- compiler.note.compressed.diags +6 errors diff --git a/test/tools/javac/Diagnostics/compressed/T8012003c.java b/test/tools/javac/Diagnostics/compressed/T8012003c.java new file mode 100644 index 0000000000000000000000000000000000000000..a64f977d043696c518b6c048fcec0929530bed52 --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003c.java @@ -0,0 +1,24 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8012003 + * @summary Method diagnostics resolution need to be simplified in some cases + * test simplification of lambda type-checking error leading to resolution failure + * @compile/fail/ref=T8012003c.out -XDrawDiagnostics -Xdiags:compact T8012003c.java + */ + +class T8012003c { + + interface I { + void m(P p); + } + + void m(I i) { } + + void test() { + m(p->p.m()); + } +} + +class P { + private void m() { } +} diff --git a/test/tools/javac/Diagnostics/compressed/T8012003c.out b/test/tools/javac/Diagnostics/compressed/T8012003c.out new file mode 100644 index 0000000000000000000000000000000000000000..7af49cc18e56c33fa010320b0931f69be235f70b --- /dev/null +++ b/test/tools/javac/Diagnostics/compressed/T8012003c.out @@ -0,0 +1,3 @@ +T8012003c.java:18:15: compiler.err.report.access: m(), private, P +- compiler.note.compressed.diags +1 error diff --git a/test/tools/javac/diags/examples/BadArgTypesInLambda.java b/test/tools/javac/diags/examples/BadArgTypesInLambda.java index 1062a6396066480ddfc44ec14b41c4f1a79801df..493c4c31efc4cb1d3ea3d6d65fe46715cbc3516f 100644 --- a/test/tools/javac/diags/examples/BadArgTypesInLambda.java +++ b/test/tools/javac/diags/examples/BadArgTypesInLambda.java @@ -24,6 +24,9 @@ // key: compiler.err.cant.apply.symbol // key: compiler.misc.no.conforming.assignment.exists // key: compiler.misc.bad.arg.types.in.lambda +// key: compiler.err.prob.found.req +// key: compiler.misc.inconvertible.types +// options: -Xdiags:verbose class BadArgTypesInLambda { interface SAM { diff --git a/test/tools/javac/diags/examples/CompressedDiags.java b/test/tools/javac/diags/examples/CompressedDiags.java new file mode 100644 index 0000000000000000000000000000000000000000..a71f7355e50f1883c43ddef32fa8ea5c941fd160 --- /dev/null +++ b/test/tools/javac/diags/examples/CompressedDiags.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.prob.found.req +// key: compiler.misc.inconvertible.types +// key: compiler.note.compressed.diags +// key: compiler.note.note +// key: compiler.misc.count.error +// key: compiler.err.error +// run: backdoor + +class CompressedDiags { + + void m(String s) { } + + void test() { + m(1); + } +} diff --git a/test/tools/javac/diags/examples/KindnameConstructor.java b/test/tools/javac/diags/examples/KindnameConstructor.java index db7d39bfce3afa22b80facdc2bd14dea62856586..4b0f739c8e4b4532f5a2fbb419295e3a44b1a842 100644 --- a/test/tools/javac/diags/examples/KindnameConstructor.java +++ b/test/tools/javac/diags/examples/KindnameConstructor.java @@ -28,6 +28,7 @@ // key: compiler.misc.inconvertible.types // key: compiler.misc.count.error // key: compiler.err.error +// options: -Xdiags:verbose // run: backdoor class KindnameConstructor { diff --git a/test/tools/javac/diags/examples/ProbFoundReqFragment.java b/test/tools/javac/diags/examples/ProbFoundReqFragment.java new file mode 100644 index 0000000000000000000000000000000000000000..4eaa88ca08a43143e066ab90ba1f6c2c3ec4ea58 --- /dev/null +++ b/test/tools/javac/diags/examples/ProbFoundReqFragment.java @@ -0,0 +1,44 @@ +/* + * 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.prob.found.req +// key: compiler.misc.inconvertible.types +// key: compiler.misc.invalid.mref +// key: compiler.misc.kindname.method +// key: compiler.misc.count.error +// key: compiler.err.error +// run: backdoor + +class ProbFoundReqFragment { + + interface I { + void g(int i); + } + + void m(String s) { } + + void test() { + I i = this::m; + } +} diff --git a/test/tools/javac/lambda/TargetType66.out b/test/tools/javac/lambda/TargetType66.out index b4f311f6377e0a12cb0578007adf4964f3f37420..b5c828df27bf5c3cd29650b8801d4011ae427008 100644 --- a/test/tools/javac/lambda/TargetType66.out +++ b/test/tools/javac/lambda/TargetType66.out @@ -1,4 +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: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.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character))))),(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, (compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Character)))))} TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character) 3 errors