changeset 11:7366066839bb

6668794: javac puts localized text in raw diagnostics 6668796: bad diagnostic "bad class file" given for source files Summary: Replace internal use of localized text with JCDiagnostic fragments; fix diagnostic for bad source file Reviewed-by: mcimadamore
author jjg
date Wed, 12 Mar 2008 13:06:00 -0700
parents b66d15dfd001
children 6beca695cfae
files src/share/classes/com/sun/tools/javac/code/Symbol.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/main/JavaCompiler.java src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/6668794/badClass/A.java test/tools/javac/6668794/badClass/B.java test/tools/javac/6668794/badClass/Test.java test/tools/javac/6668794/badSource/Test.java test/tools/javac/6668794/badSource/Test.out test/tools/javac/6668794/badSource/p/A.java
diffstat 12 files changed, 232 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Mar 12 13:06:00 2008 -0700
@@ -25,13 +25,9 @@
 
 package com.sun.tools.javac.code;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import javax.lang.model.element.*;
-import javax.lang.model.type.ReferenceType;
-import javax.lang.model.type.TypeMirror;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.util.*;
@@ -1272,8 +1268,14 @@
         private static final long serialVersionUID = 0;
         public Symbol sym;
 
+        /** A diagnostic object describing the failure
+         */
+        public JCDiagnostic diag;
+
         /** A localized string describing the failure.
+         * @deprecated Use {@code getDetail()} or {@code getMessage()}
          */
+        @Deprecated
         public String errmsg;
 
         public CompletionFailure(Symbol sym, String errmsg) {
@@ -1282,8 +1284,26 @@
 //          this.printStackTrace();//DEBUG
         }
 
+        public CompletionFailure(Symbol sym, JCDiagnostic diag) {
+            this.sym = sym;
+            this.diag = diag;
+//          this.printStackTrace();//DEBUG
+        }
+
+        public JCDiagnostic getDiagnostic() {
+            return diag;
+        }
+
+        @Override
         public String getMessage() {
-            return errmsg;
+            if (diag != null)
+                return diag.getMessage(null);
+            else
+                return errmsg;
+        }
+
+        public Object getDetailValue() {
+            return (diag != null ? diag : errmsg);
         }
 
         @Override
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Mar 12 13:06:00 2008 -0700
@@ -173,7 +173,7 @@
      *  @param ex         The failure to report.
      */
     public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
-        log.error(pos, "cant.access", ex.sym, ex.errmsg);
+        log.error(pos, "cant.access", ex.sym, ex.getDetailValue());
         if (ex instanceof ClassReader.BadClassFile) throw new Abort();
         else return syms.errType;
     }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Mar 12 13:06:00 2008 -0700
@@ -131,6 +131,10 @@
      */
     private final JavaFileManager fileManager;
 
+    /** Factory for diagnostics
+     */
+    JCDiagnostic.Factory diagFactory;
+
     /** Can be reassigned from outside:
      *  the completer to be used for ".java" files. If this remains unassigned
      *  ".java" files will not be loaded.
@@ -221,6 +225,7 @@
         fileManager = context.get(JavaFileManager.class);
         if (fileManager == null)
             throw new AssertionError("FileManager initialization error");
+        diagFactory = JCDiagnostic.Factory.instance(context);
 
         init(syms, definitive);
         log = Log.instance(context);
@@ -256,23 +261,26 @@
  * Error Diagnoses
  ***********************************************************************/
 
-    public static class BadClassFile extends CompletionFailure {
+
+    public class BadClassFile extends CompletionFailure {
         private static final long serialVersionUID = 0;
 
-        /**
-         * @param msg A localized message.
-         */
-        public BadClassFile(ClassSymbol c, Object cname, Object msg) {
-            super(c, Log.getLocalizedString("bad.class.file.header",
-                                            cname, msg));
+        public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) {
+            super(sym, createBadClassFileDiagnostic(file, diag));
         }
     }
+    // where
+    private JCDiagnostic createBadClassFileDiagnostic(JavaFileObject file, JCDiagnostic diag) {
+        String key = (file.getKind() == JavaFileObject.Kind.SOURCE
+                    ? "bad.source.file.header" : "bad.class.file.header");
+        return diagFactory.fragment(key, file, diag);
+    }
 
     public BadClassFile badClassFile(String key, Object... args) {
         return new BadClassFile (
             currentOwner.enclClass(),
             currentClassFile,
-            Log.getLocalizedString(key, args));
+            diagFactory.fragment(key, args));
     }
 
 /************************************************************************
@@ -1893,10 +1901,10 @@
                 currentClassFile = previousClassFile;
             }
         } else {
+            JCDiagnostic diag =
+                diagFactory.fragment("class.file.not.found", c.flatname);
             throw
-                newCompletionFailure(c,
-                                     Log.getLocalizedString("class.file.not.found",
-                                                            c.flatname));
+                newCompletionFailure(c, diag);
         }
     }
     // where
@@ -1934,22 +1942,22 @@
          *  In practice, only one can be used at a time, so we share one
          *  to reduce the expense of allocating new exception objects.
          */
-        private CompletionFailure newCompletionFailure(ClassSymbol c,
-                                                       String localized) {
+        private CompletionFailure newCompletionFailure(TypeSymbol c,
+                                                       JCDiagnostic diag) {
             if (!cacheCompletionFailure) {
                 // log.warning("proc.messager",
                 //             Log.getLocalizedString("class.file.not.found", c.flatname));
                 // c.debug.printStackTrace();
-                return new CompletionFailure(c, localized);
+                return new CompletionFailure(c, diag);
             } else {
                 CompletionFailure result = cachedCompletionFailure;
                 result.sym = c;
-                result.errmsg = localized;
+                result.diag = diag;
                 return result;
             }
         }
         private CompletionFailure cachedCompletionFailure =
-            new CompletionFailure(null, null);
+            new CompletionFailure(null, (JCDiagnostic) null);
         {
             cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
         }
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Wed Mar 12 13:06:00 2008 -0700
@@ -198,6 +198,10 @@
      */
     public Log log;
 
+    /** Factory for creating diagnostic objects
+     */
+    JCDiagnostic.Factory diagFactory;
+
     /** The tree factory module.
      */
     protected TreeMaker make;
@@ -304,6 +308,7 @@
 
         names = Name.Table.instance(context);
         log = Log.instance(context);
+        diagFactory = JCDiagnostic.Factory.instance(context);
         reader = ClassReader.instance(context);
         make = TreeMaker.instance(context);
         writer = ClassWriter.instance(context);
@@ -318,7 +323,7 @@
             syms = Symtab.instance(context);
         } catch (CompletionFailure ex) {
             // inlined Check.completionError as it is not initialized yet
-            log.error("cant.access", ex.sym, ex.errmsg);
+            log.error("cant.access", ex.sym, ex.getDetailValue());
             if (ex instanceof ClassReader.BadClassFile)
                 throw new Abort();
         }
@@ -683,16 +688,16 @@
                                                  JavaFileObject.Kind.SOURCE);
             if (isPkgInfo) {
                 if (enter.getEnv(tree.packge) == null) {
-                    String msg
-                        = log.getLocalizedString("file.does.not.contain.package",
+                    JCDiagnostic diag =
+                        diagFactory.fragment("file.does.not.contain.package",
                                                  c.location());
-                    throw new ClassReader.BadClassFile(c, filename, msg);
+                    throw reader.new BadClassFile(c, filename, diag);
                 }
             } else {
-                throw new
-                    ClassReader.BadClassFile(c, filename, log.
-                                             getLocalizedString("file.doesnt.contain.class",
-                                                                c.fullname));
+                JCDiagnostic diag =
+                        diagFactory.fragment("file.doesnt.contain.class",
+                                            c.getQualifiedName());
+                throw reader.new BadClassFile(c, filename, diag);
             }
         }
 
@@ -997,7 +1002,7 @@
                 annotationProcessingOccurred = c.annotationProcessingOccurred = true;
             return c;
         } catch (CompletionFailure ex) {
-            log.error("cant.access", ex.sym, ex.errmsg);
+            log.error("cant.access", ex.sym, ex.getDetailValue());
             return this;
 
         }
--- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Wed Mar 12 13:06:00 2008 -0700
@@ -734,7 +734,7 @@
         } catch (CompletionFailure ex) {
             StringWriter out = new StringWriter();
             ex.printStackTrace(new PrintWriter(out));
-            log.error("proc.cant.access", ex.sym, ex.errmsg, out.toString());
+            log.error("proc.cant.access", ex.sym, ex.getDetailValue(), out.toString());
             return false;
         } catch (Throwable t) {
             throw new AnnotationProcessingError(t);
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Mar 11 13:14:55 2008 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Mar 12 13:06:00 2008 -0700
@@ -827,6 +827,10 @@
 bad class file: {0}\n\
 {1}\n\
 Please remove or make sure it appears in the correct subdirectory of the classpath.
+compiler.misc.bad.source.file.header=\
+bad source file: {0}\n\
+{1}\n\
+Please remove or make sure it appears in the correct subdirectory of the sourcepath.
 
 ## The following are all possible strings for the second argument ({1}) of the
 ## above strings.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badClass/A.java	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package q;
+
+class A { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badClass/B.java	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,7 @@
+/*
+ * /nodynamiccopyright/
+ */
+
+class B {
+    p.A a;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badClass/Test.java	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6668794 6668796
+ * @summary javac puts localized text in raw diagnostics
+ *      bad diagnostic "bad class file" given for source files
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+
+public class Test {
+    public static void main(String[] args) throws Exception {
+        new Test().run();
+    }
+
+    void run() throws Exception {
+
+        // compile q.A then move it to p.A
+        compile("A.java");
+
+        File p = new File("p");
+        p.mkdirs();
+        new File("q/A.class").renameTo(new File("p/A.class"));
+
+        // compile B against p.A
+        String[] out = compile("B.java");
+        if (out.length == 0)
+            throw new Error("no diagnostics generated");
+
+        String expected = "B.java:6:6: compiler.err.cant.access: p.A, " +
+            "(- compiler.misc.bad.class.file.header: A.class, " +
+            "(- compiler.misc.class.file.wrong.class: q.A))";
+
+        if (!out[0].equals(expected)) {
+            System.err.println("expected: " + expected);
+            System.err.println("   found: " + out[0]);
+            throw new Error("test failed");
+        }
+    }
+
+    String[] compile(String file) {
+        String[] options = {
+            "-XDrawDiagnostics",
+            "-d", ".",
+            "-classpath", ".",
+            new File(testSrc, file).getPath()
+        };
+
+        System.err.println("compile: " + Arrays.asList(options));
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(options, out);
+        out.close();
+
+        String outText = sw.toString();
+        System.err.println(outText);
+
+        return sw.toString().split("[\\r\\n]+");
+    }
+
+    File testSrc = new File(System.getProperty("test.src", "."));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badSource/Test.java	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyight/
+ * @bug 6668794 6668796
+ * @summary javac puts localized text in raw diagnostics
+ *      bad diagnostic "bad class file" given for source files
+ * @compile/fail/ref=Test.out -XDrawDiagnostics Test.java
+ */
+
+class Test {
+    p.A a;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badSource/Test.out	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,1 @@
+Test.java:10:6: compiler.err.cant.access: p.A, (- compiler.misc.bad.source.file.header: A.java, (- compiler.misc.file.doesnt.contain.class: p.A))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6668794/badSource/p/A.java	Wed Mar 12 13:06:00 2008 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package q;
+
+class A { }