6668794: javac puts localized text in raw diagnostics

6668796: bad diagnostic "bad class file" given for source files

Replace internal use of localized text with JCDiagnostic fragments; fix diagnostic for bad source file

Reviewed-by: mcimadamore
This commit is contained in:
Jonathan Gibbons 2008-03-12 13:06:00 -07:00
parent 4cd40a47ff
commit 7dbe0828de
12 changed files with 233 additions and 33 deletions

View File

@ -25,13 +25,9 @@
package com.sun.tools.javac.code; package com.sun.tools.javac.code;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.type.ReferenceType;
import javax.lang.model.type.TypeMirror;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
@ -1272,8 +1268,14 @@ public abstract class Symbol implements Element {
private static final long serialVersionUID = 0; private static final long serialVersionUID = 0;
public Symbol sym; public Symbol sym;
/** A localized string describing the failure. /** 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 String errmsg;
public CompletionFailure(Symbol sym, String errmsg) { public CompletionFailure(Symbol sym, String errmsg) {
@ -1282,10 +1284,28 @@ public abstract class Symbol implements Element {
// this.printStackTrace();//DEBUG // 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() { public String getMessage() {
if (diag != null)
return diag.getMessage(null);
else
return errmsg; return errmsg;
} }
public Object getDetailValue() {
return (diag != null ? diag : errmsg);
}
@Override @Override
public CompletionFailure initCause(Throwable cause) { public CompletionFailure initCause(Throwable cause) {
super.initCause(cause); super.initCause(cause);

View File

@ -173,7 +173,7 @@ public class Check {
* @param ex The failure to report. * @param ex The failure to report.
*/ */
public Type completionError(DiagnosticPosition pos, CompletionFailure ex) { 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(); if (ex instanceof ClassReader.BadClassFile) throw new Abort();
else return syms.errType; else return syms.errType;
} }

View File

@ -131,6 +131,10 @@ public class ClassReader extends ClassFile implements Completer {
*/ */
private final JavaFileManager fileManager; private final JavaFileManager fileManager;
/** Factory for diagnostics
*/
JCDiagnostic.Factory diagFactory;
/** Can be reassigned from outside: /** Can be reassigned from outside:
* the completer to be used for ".java" files. If this remains unassigned * the completer to be used for ".java" files. If this remains unassigned
* ".java" files will not be loaded. * ".java" files will not be loaded.
@ -221,6 +225,7 @@ public class ClassReader extends ClassFile implements Completer {
fileManager = context.get(JavaFileManager.class); fileManager = context.get(JavaFileManager.class);
if (fileManager == null) if (fileManager == null)
throw new AssertionError("FileManager initialization error"); throw new AssertionError("FileManager initialization error");
diagFactory = JCDiagnostic.Factory.instance(context);
init(syms, definitive); init(syms, definitive);
log = Log.instance(context); log = Log.instance(context);
@ -256,23 +261,26 @@ public class ClassReader extends ClassFile implements Completer {
* Error Diagnoses * Error Diagnoses
***********************************************************************/ ***********************************************************************/
public static class BadClassFile extends CompletionFailure {
public class BadClassFile extends CompletionFailure {
private static final long serialVersionUID = 0; private static final long serialVersionUID = 0;
/** public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag) {
* @param msg A localized message. super(sym, createBadClassFileDiagnostic(file, diag));
*/
public BadClassFile(ClassSymbol c, Object cname, Object msg) {
super(c, Log.getLocalizedString("bad.class.file.header",
cname, msg));
} }
} }
// 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) { public BadClassFile badClassFile(String key, Object... args) {
return new BadClassFile ( return new BadClassFile (
currentOwner.enclClass(), currentOwner.enclClass(),
currentClassFile, currentClassFile,
Log.getLocalizedString(key, args)); diagFactory.fragment(key, args));
} }
/************************************************************************ /************************************************************************
@ -1893,10 +1901,10 @@ public class ClassReader extends ClassFile implements Completer {
currentClassFile = previousClassFile; currentClassFile = previousClassFile;
} }
} else { } else {
JCDiagnostic diag =
diagFactory.fragment("class.file.not.found", c.flatname);
throw throw
newCompletionFailure(c, newCompletionFailure(c, diag);
Log.getLocalizedString("class.file.not.found",
c.flatname));
} }
} }
// where // where
@ -1934,22 +1942,22 @@ public class ClassReader extends ClassFile implements Completer {
* In practice, only one can be used at a time, so we share one * In practice, only one can be used at a time, so we share one
* to reduce the expense of allocating new exception objects. * to reduce the expense of allocating new exception objects.
*/ */
private CompletionFailure newCompletionFailure(ClassSymbol c, private CompletionFailure newCompletionFailure(TypeSymbol c,
String localized) { JCDiagnostic diag) {
if (!cacheCompletionFailure) { if (!cacheCompletionFailure) {
// log.warning("proc.messager", // log.warning("proc.messager",
// Log.getLocalizedString("class.file.not.found", c.flatname)); // Log.getLocalizedString("class.file.not.found", c.flatname));
// c.debug.printStackTrace(); // c.debug.printStackTrace();
return new CompletionFailure(c, localized); return new CompletionFailure(c, diag);
} else { } else {
CompletionFailure result = cachedCompletionFailure; CompletionFailure result = cachedCompletionFailure;
result.sym = c; result.sym = c;
result.errmsg = localized; result.diag = diag;
return result; return result;
} }
} }
private CompletionFailure cachedCompletionFailure = private CompletionFailure cachedCompletionFailure =
new CompletionFailure(null, null); new CompletionFailure(null, (JCDiagnostic) null);
{ {
cachedCompletionFailure.setStackTrace(new StackTraceElement[0]); cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
} }

View File

@ -198,6 +198,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
*/ */
public Log log; public Log log;
/** Factory for creating diagnostic objects
*/
JCDiagnostic.Factory diagFactory;
/** The tree factory module. /** The tree factory module.
*/ */
protected TreeMaker make; protected TreeMaker make;
@ -304,6 +308,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
names = Name.Table.instance(context); names = Name.Table.instance(context);
log = Log.instance(context); log = Log.instance(context);
diagFactory = JCDiagnostic.Factory.instance(context);
reader = ClassReader.instance(context); reader = ClassReader.instance(context);
make = TreeMaker.instance(context); make = TreeMaker.instance(context);
writer = ClassWriter.instance(context); writer = ClassWriter.instance(context);
@ -318,7 +323,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
syms = Symtab.instance(context); syms = Symtab.instance(context);
} catch (CompletionFailure ex) { } catch (CompletionFailure ex) {
// inlined Check.completionError as it is not initialized yet // 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) if (ex instanceof ClassReader.BadClassFile)
throw new Abort(); throw new Abort();
} }
@ -683,16 +688,16 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
JavaFileObject.Kind.SOURCE); JavaFileObject.Kind.SOURCE);
if (isPkgInfo) { if (isPkgInfo) {
if (enter.getEnv(tree.packge) == null) { if (enter.getEnv(tree.packge) == null) {
String msg JCDiagnostic diag =
= log.getLocalizedString("file.does.not.contain.package", diagFactory.fragment("file.does.not.contain.package",
c.location()); c.location());
throw new ClassReader.BadClassFile(c, filename, msg); throw reader.new BadClassFile(c, filename, diag);
} }
} else { } else {
throw new JCDiagnostic diag =
ClassReader.BadClassFile(c, filename, log. diagFactory.fragment("file.doesnt.contain.class",
getLocalizedString("file.doesnt.contain.class", c.getQualifiedName());
c.fullname)); throw reader.new BadClassFile(c, filename, diag);
} }
} }
@ -997,7 +1002,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
annotationProcessingOccurred = c.annotationProcessingOccurred = true; annotationProcessingOccurred = c.annotationProcessingOccurred = true;
return c; return c;
} catch (CompletionFailure ex) { } catch (CompletionFailure ex) {
log.error("cant.access", ex.sym, ex.errmsg); log.error("cant.access", ex.sym, ex.getDetailValue());
return this; return this;
} }

View File

@ -734,7 +734,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} catch (CompletionFailure ex) { } catch (CompletionFailure ex) {
StringWriter out = new StringWriter(); StringWriter out = new StringWriter();
ex.printStackTrace(new PrintWriter(out)); 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; return false;
} catch (Throwable t) { } catch (Throwable t) {
throw new AnnotationProcessingError(t); throw new AnnotationProcessingError(t);

View File

@ -827,6 +827,10 @@ compiler.misc.bad.class.file.header=\
bad class file: {0}\n\ bad class file: {0}\n\
{1}\n\ {1}\n\
Please remove or make sure it appears in the correct subdirectory of the classpath. 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 ## The following are all possible strings for the second argument ({1}) of the
## above strings. ## above strings.

View File

@ -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 { }

View File

@ -0,0 +1,7 @@
/*
* /nodynamiccopyright/
*/
class B {
p.A a;
}

View File

@ -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", "."));
}

View File

@ -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;
}

View File

@ -0,0 +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))

View File

@ -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 { }