Thu, 07 Jan 2016 08:45:19 +0000
8145466: javac: No line numbers in compilation error
Summary: Compiler should not use the syntax tree from enclosing contexts in diagnostics even when the enclosing contexts are consulted for method lookup.
Reviewed-by: mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Mon Jan 04 12:08:55 2016 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Jan 07 08:45:19 2016 +0000 1.3 @@ -25,6 +25,7 @@ 1.4 1.5 package com.sun.tools.javac.comp; 1.6 1.7 +import com.sun.tools.javac.tree.JCTree; 1.8 import com.sun.tools.javac.util.*; 1.9 import com.sun.tools.javac.code.*; 1.10 1.11 @@ -80,6 +81,13 @@ 1.12 */ 1.13 Type defaultSuperCallSite = null; 1.14 1.15 + /** Tree that when non null, is to be preferentially used in diagnostics. 1.16 + * Usually Env<AttrContext>.tree is the tree to be referred to in messages, 1.17 + * but this may not be true during the window a method is looked up in enclosing 1.18 + * contexts (JDK-8145466) 1.19 + */ 1.20 + JCTree preferredTreeForDiagnostics; 1.21 + 1.22 /** Duplicate this context, replacing scope field and copying all others. 1.23 */ 1.24 AttrContext dup(Scope scope) { 1.25 @@ -94,6 +102,7 @@ 1.26 info.returnResult = returnResult; 1.27 info.defaultSuperCallSite = defaultSuperCallSite; 1.28 info.isSerializable = isSerializable; 1.29 + info.preferredTreeForDiagnostics = preferredTreeForDiagnostics; 1.30 return info; 1.31 } 1.32
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Jan 04 12:08:55 2016 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jan 07 08:45:19 2016 +0000 2.3 @@ -717,7 +717,8 @@ 2.4 Warner warn) { 2.5 //should we expand formals? 2.6 boolean useVarargs = deferredAttrContext.phase.isVarargsRequired(); 2.7 - List<JCExpression> trees = TreeInfo.args(env.tree); 2.8 + JCTree callTree = treeForDiagnostics(env); 2.9 + List<JCExpression> trees = TreeInfo.args(callTree); 2.10 2.11 //inference context used during this method check 2.12 InferenceContext inferenceContext = deferredAttrContext.inferenceContext; 2.13 @@ -726,7 +727,7 @@ 2.14 2.15 if (varargsFormal == null && 2.16 argtypes.size() != formals.size()) { 2.17 - reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 2.18 + reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 2.19 } 2.20 2.21 while (argtypes.nonEmpty() && formals.head != varargsFormal) { 2.22 @@ -738,7 +739,7 @@ 2.23 } 2.24 2.25 if (formals.head != varargsFormal) { 2.26 - reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 2.27 + reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args 2.28 } 2.29 2.30 if (useVarargs) { 2.31 @@ -754,6 +755,11 @@ 2.32 } 2.33 } 2.34 2.35 + // where 2.36 + private JCTree treeForDiagnostics(Env<AttrContext> env) { 2.37 + return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree; 2.38 + } 2.39 + 2.40 /** 2.41 * Does the actual argument conforms to the corresponding formal? 2.42 */ 2.43 @@ -1828,17 +1834,23 @@ 2.44 boolean staticOnly = false; 2.45 while (env1.outer != null) { 2.46 if (isStatic(env1)) staticOnly = true; 2.47 - sym = findMethod( 2.48 - env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 2.49 - allowBoxing, useVarargs, false); 2.50 - if (sym.exists()) { 2.51 - if (staticOnly && 2.52 - sym.kind == MTH && 2.53 - sym.owner.kind == TYP && 2.54 - (sym.flags() & STATIC) == 0) return new StaticError(sym); 2.55 - else return sym; 2.56 - } else if (sym.kind < bestSoFar.kind) { 2.57 - bestSoFar = sym; 2.58 + Assert.check(env1.info.preferredTreeForDiagnostics == null); 2.59 + env1.info.preferredTreeForDiagnostics = env.tree; 2.60 + try { 2.61 + sym = findMethod( 2.62 + env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 2.63 + allowBoxing, useVarargs, false); 2.64 + if (sym.exists()) { 2.65 + if (staticOnly && 2.66 + sym.kind == MTH && 2.67 + sym.owner.kind == TYP && 2.68 + (sym.flags() & STATIC) == 0) return new StaticError(sym); 2.69 + else return sym; 2.70 + } else if (sym.kind < bestSoFar.kind) { 2.71 + bestSoFar = sym; 2.72 + } 2.73 + } finally { 2.74 + env1.info.preferredTreeForDiagnostics = null; 2.75 } 2.76 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 2.77 env1 = env1.outer; 2.78 @@ -4214,7 +4226,11 @@ 2.79 DiagnosticPosition preferedPos, DiagnosticSource preferredSource, 2.80 DiagnosticType preferredKind, JCDiagnostic d) { 2.81 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[0]; 2.82 - return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(), 2.83 + DiagnosticPosition pos = d.getDiagnosticPosition(); 2.84 + if (pos == null) { 2.85 + pos = preferedPos; 2.86 + } 2.87 + return diags.create(preferredKind, preferredSource, pos, 2.88 "prob.found.req", cause); 2.89 } 2.90 });
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/diags/DiagnosticRewriterTest.java Thu Jan 07 08:45:19 2016 +0000 3.3 @@ -0,0 +1,18 @@ 3.4 +/* 3.5 + * @test /nodynamiccopyright/ 3.6 + * @bug 8145466 8146533 3.7 + * @summary javac: No line numbers in compilation error 3.8 + * @compile/fail/ref=DiagnosticRewriterTest.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest.java 3.9 + */ 3.10 + 3.11 +class DiagnosticRewriterTest { 3.12 + void test() { 3.13 + new Object() { 3.14 + void g() { 3.15 + m(2L); 3.16 + } 3.17 + }; 3.18 + } 3.19 + 3.20 + void m(int i) { } 3.21 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/diags/DiagnosticRewriterTest.out Thu Jan 07 08:45:19 2016 +0000 4.3 @@ -0,0 +1,3 @@ 4.4 +DiagnosticRewriterTest.java:12:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int) 4.5 +- compiler.note.compressed.diags 4.6 +1 error
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/diags/DiagnosticRewriterTest2.java Thu Jan 07 08:45:19 2016 +0000 5.3 @@ -0,0 +1,22 @@ 5.4 +/* 5.5 + * @test /nodynamiccopyright/ 5.6 + * @bug 8145466 8146533 5.7 + * @summary javac: No line numbers in compilation error 5.8 + * @compile/fail/ref=DiagnosticRewriterTest2.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest2.java 5.9 + */ 5.10 + 5.11 +class DiagnosticRewriterTest2 { 5.12 + class Bar { 5.13 + Bar(Object o) { } 5.14 + } 5.15 + void test() { 5.16 + new Bar(null) { 5.17 + void g() { 5.18 + m(2L); 5.19 + m(); 5.20 + } 5.21 + }; 5.22 + } 5.23 + 5.24 + void m(int i) { } 5.25 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/diags/DiagnosticRewriterTest2.out Thu Jan 07 08:45:19 2016 +0000 6.3 @@ -0,0 +1,4 @@ 6.4 +DiagnosticRewriterTest2.java:15:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int) 6.5 +DiagnosticRewriterTest2.java:16:13: compiler.err.cant.apply.symbol: kindname.method, m, int, compiler.misc.no.args, kindname.class, DiagnosticRewriterTest2, (compiler.misc.arg.length.mismatch) 6.6 +- compiler.note.compressed.diags 6.7 +2 errors