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;
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 @@ public abstract class Symbol implements Element {
private static final long serialVersionUID = 0;
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 CompletionFailure(Symbol sym, String errmsg) {
@ -1282,8 +1284,26 @@ public abstract class Symbol implements Element {
// 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

View File

@ -173,7 +173,7 @@ public class Check {
* @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;
}

View File

@ -131,6 +131,10 @@ public class ClassReader extends ClassFile implements Completer {
*/
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 @@ public class ClassReader extends ClassFile implements Completer {
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 @@ public class ClassReader extends ClassFile implements Completer {
* 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 @@ public class ClassReader extends ClassFile implements Completer {
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 @@ public class ClassReader extends ClassFile implements Completer {
* 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]);
}

View File

@ -198,6 +198,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
*/
public Log log;
/** Factory for creating diagnostic objects
*/
JCDiagnostic.Factory diagFactory;
/** The tree factory module.
*/
protected TreeMaker make;
@ -304,6 +308,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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;
}

View File

@ -734,7 +734,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} 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);

View File

@ -827,6 +827,10 @@ compiler.misc.bad.class.file.header=\
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.

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