changeset 3182:bdbad16dd9ac

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
author sadayapalam
date Tue, 22 Dec 2015 16:37:52 +0530
parents cb73b474703e
children 5d73162435ba
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/diags/DiagnosticRewriterTest.java test/tools/javac/diags/DiagnosticRewriterTest.out test/tools/javac/diags/DiagnosticRewriterTest2.java test/tools/javac/diags/DiagnosticRewriterTest2.out
diffstat 6 files changed, 87 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Mon Dec 21 17:47:21 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java	Tue Dec 22 16:37:52 2015 +0530
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.comp;
 
+import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.WriteableScope;
@@ -95,6 +96,13 @@
      */
     Type defaultSuperCallSite = null;
 
+    /** Tree that when non null, is to be preferentially used in diagnostics.
+     *  Usually Env<AttrContext>.tree is the tree to be referred to in messages,
+     *  but this may not be true during the window a method is looked up in enclosing
+     *  contexts (JDK-8145466)
+     */
+    JCTree preferredTreeForDiagnostics;
+
     /** Duplicate this context, replacing scope field and copying all others.
      */
     AttrContext dup(WriteableScope scope) {
@@ -112,6 +120,7 @@
         info.isSpeculative = isSpeculative;
         info.isAnonymousDiamond = isAnonymousDiamond;
         info.isNewClass = isNewClass;
+        info.preferredTreeForDiagnostics = preferredTreeForDiagnostics;
         return info;
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 21 17:47:21 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Dec 22 16:37:52 2015 +0530
@@ -722,7 +722,8 @@
                                     Warner warn) {
             //should we expand formals?
             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
-            List<JCExpression> trees = TreeInfo.args(env.tree);
+            JCTree callTree = treeForDiagnostics(env);
+            List<JCExpression> trees = TreeInfo.args(callTree);
 
             //inference context used during this method check
             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
@@ -731,7 +732,7 @@
 
             if (varargsFormal == null &&
                     argtypes.size() != formals.size()) {
-                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
             }
 
             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
@@ -743,7 +744,7 @@
             }
 
             if (formals.head != varargsFormal) {
-                reportMC(env.tree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+                reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
             }
 
             if (useVarargs) {
@@ -759,6 +760,11 @@
             }
         }
 
+            // where
+            private JCTree treeForDiagnostics(Env<AttrContext> env) {
+                return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
+            }
+
         /**
          * Does the actual argument conforms to the corresponding formal?
          */
@@ -1847,17 +1853,23 @@
         boolean staticOnly = false;
         while (env1.outer != null) {
             if (isStatic(env1)) staticOnly = true;
-            Symbol sym = findMethod(
-                env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
-                allowBoxing, useVarargs);
-            if (sym.exists()) {
-                if (staticOnly &&
-                    sym.kind == MTH &&
-                    sym.owner.kind == TYP &&
-                    (sym.flags() & STATIC) == 0) return new StaticError(sym);
-                else return sym;
-            } else {
-                bestSoFar = bestOf(bestSoFar, sym);
+            Assert.check(env1.info.preferredTreeForDiagnostics == null);
+            env1.info.preferredTreeForDiagnostics = env.tree;
+            try {
+                Symbol sym = findMethod(
+                    env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
+                    allowBoxing, useVarargs);
+                if (sym.exists()) {
+                    if (staticOnly &&
+                        sym.kind == MTH &&
+                        sym.owner.kind == TYP &&
+                        (sym.flags() & STATIC) == 0) return new StaticError(sym);
+                    else return sym;
+                } else {
+                    bestSoFar = bestOf(bestSoFar, sym);
+                }
+            } finally {
+                env1.info.preferredTreeForDiagnostics = null;
             }
             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
             env1 = env1.outer;
@@ -4184,7 +4196,11 @@
                     DiagnosticPosition preferedPos, DiagnosticSource preferredSource,
                     DiagnosticType preferredKind, JCDiagnostic d) {
                 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
-                return diags.create(preferredKind, preferredSource, d.getDiagnosticPosition(),
+                DiagnosticPosition pos = d.getDiagnosticPosition();
+                if (pos == null) {
+                    pos = preferedPos;
+                }
+                return diags.create(preferredKind, preferredSource, pos,
                         "prob.found.req", cause);
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/DiagnosticRewriterTest.java	Tue Dec 22 16:37:52 2015 +0530
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8145466
+ * @summary javac: No line numbers in compilation error
+ * @compile/fail/ref=DiagnosticRewriterTest.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest.java
+ */
+
+class DiagnosticRewriterTest {
+   void test() {
+      new Object() {
+         void g() {
+            m(2L);
+         }
+      };
+   }
+
+   void m(int i) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/DiagnosticRewriterTest.out	Tue Dec 22 16:37:52 2015 +0530
@@ -0,0 +1,3 @@
+DiagnosticRewriterTest.java:12:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int)
+- compiler.note.compressed.diags
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/DiagnosticRewriterTest2.java	Tue Dec 22 16:37:52 2015 +0530
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8145466
+ * @summary javac: No line numbers in compilation error
+ * @compile/fail/ref=DiagnosticRewriterTest2.out -Xdiags:compact -XDrawDiagnostics DiagnosticRewriterTest2.java
+ */
+
+class DiagnosticRewriterTest2 {
+   class Bar {
+       Bar(Object o) { }
+   }
+   void test() {
+      new Bar(null) {
+         void g() {
+            m(2L);
+            m();
+         }
+      };
+   }
+
+   void m(int i) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/DiagnosticRewriterTest2.out	Tue Dec 22 16:37:52 2015 +0530
@@ -0,0 +1,4 @@
+DiagnosticRewriterTest2.java:15:15: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int)
+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)
+- compiler.note.compressed.diags
+2 errors