mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-11-27 06:10:37 +00:00
7013272: Automatically generate info about how compiler resource keys are used
Reviewed-by: mcimadamore
This commit is contained in:
parent
a184b53cec
commit
de3bde6688
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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
|
||||
@ -331,7 +331,7 @@
|
||||
executable="${dist.bin.dir}/javac"
|
||||
srcdir="test/tools/javac/diags"
|
||||
destdir="${build.dir}/diag-examples/classes"
|
||||
includes="Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
|
||||
includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
|
||||
sourcepath=""
|
||||
classpath="${dist.lib.dir}/javac.jar"
|
||||
includeAntRuntime="no"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. 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
|
||||
@ -106,7 +106,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
}
|
||||
|
||||
/**
|
||||
* * Get a localized string represenation for all the symbols in the input list.
|
||||
* * Get a localized string representation for all the symbols in the input list.
|
||||
*
|
||||
* @param ts symbols to be displayed
|
||||
* @param locale the locale in which the string is to be rendered
|
||||
|
File diff suppressed because it is too large
Load Diff
346
langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java
Normal file
346
langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java
Normal file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import javax.tools.*;
|
||||
|
||||
import com.sun.tools.javac.api.*;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.Formattable.LocalizedString;
|
||||
import com.sun.tools.javac.code.Flags.Flag;
|
||||
import com.sun.tools.javac.code.Kinds.KindName;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.file.*;
|
||||
import com.sun.tools.javac.main.Main;
|
||||
import com.sun.tools.javac.parser.Token;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
|
||||
import javax.lang.model.SourceVersion;
|
||||
|
||||
/**
|
||||
* Compiler factory for instances of Example.Compiler that use custom
|
||||
* DiagnosticFormatter and Messages objects to track the types of args
|
||||
* when when localizing diagnostics.
|
||||
* The compiler objects only support "output" mode, not "check" mode.
|
||||
*/
|
||||
class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
// Same code as Example.Compiler.DefaultFactory, but the names resolve differently
|
||||
public Example.Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
String first;
|
||||
String[] rest;
|
||||
if (opts == null || opts.isEmpty()) {
|
||||
first = null;
|
||||
rest = new String[0];
|
||||
} else {
|
||||
first = opts.get(0);
|
||||
rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
|
||||
}
|
||||
if (first == null || first.equals("jsr199"))
|
||||
return new Jsr199Compiler(verbose, rest);
|
||||
else if (first.equals("simple"))
|
||||
return new SimpleCompiler(verbose);
|
||||
else if (first.equals("backdoor"))
|
||||
return new BackdoorCompiler(verbose);
|
||||
else
|
||||
throw new IllegalArgumentException(first);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile using the JSR 199 API. The diagnostics generated are
|
||||
* scanned for resource keys. Not all diagnostic keys are generated
|
||||
* via the JSR 199 API -- for example, rich diagnostics are not directly
|
||||
* accessible, and some diagnostics generated by the file manager may
|
||||
* not be generated (for example, the JSR 199 file manager does not see
|
||||
* -Xlint:path).
|
||||
*/
|
||||
static class Jsr199Compiler extends Example.Compiler {
|
||||
List<String> fmOpts;
|
||||
|
||||
Jsr199Compiler(boolean verbose, String... args) {
|
||||
super(verbose);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("-filemanager") && (i + 1 < args.length)) {
|
||||
fmOpts = Arrays.asList(args[++i].split(","));
|
||||
} else
|
||||
throw new IllegalArgumentException(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_jsr199: " + opts + " " + files);
|
||||
|
||||
JavacTool tool = JavacTool.create();
|
||||
|
||||
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
|
||||
if (fmOpts != null)
|
||||
fm = new FileManager(fm, fmOpts);
|
||||
|
||||
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
|
||||
|
||||
JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos);
|
||||
Context c = t.getContext();
|
||||
ArgTypeMessages.preRegister(c);
|
||||
Options options = Options.instance(c);
|
||||
Log.instance(c).setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
Boolean ok = t.call();
|
||||
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the test using the standard simple entry point.
|
||||
*/
|
||||
static class SimpleCompiler extends Example.Compiler {
|
||||
SimpleCompiler(boolean verbose) {
|
||||
super(verbose);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_simple: " + opts + " " + files);
|
||||
|
||||
List<String> args = new ArrayList<String>();
|
||||
|
||||
args.addAll(opts);
|
||||
for (File f: files)
|
||||
args.add(f.getPath());
|
||||
|
||||
Main main = new Main("javac", out);
|
||||
Context c = new Context() {
|
||||
@Override public void clear() {
|
||||
((JavacFileManager) get(JavaFileManager.class)).close();
|
||||
super.clear();
|
||||
}
|
||||
};
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeDiagnosticFormatter.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
int result = main.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return (result == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static class BackdoorCompiler extends Example.Compiler {
|
||||
BackdoorCompiler(boolean verbose) {
|
||||
super(verbose);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
|
||||
assert out != null && keys == null;
|
||||
|
||||
if (verbose)
|
||||
System.err.println("run_simple: " + opts + " " + files);
|
||||
|
||||
List<String> args = new ArrayList<String>(opts);
|
||||
for (File f: files)
|
||||
args.add(f.getPath());
|
||||
|
||||
Context c = new Context();
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeDiagnosticFormatter.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
com.sun.tools.javac.main.Main m = new com.sun.tools.javac.main.Main("javac", out);
|
||||
int rc = m.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Custom Javac components">
|
||||
|
||||
/**
|
||||
* Diagnostic formatter which reports formats a diag as a series of lines
|
||||
* containing a key, and a possibly empty set of descriptive strings for the
|
||||
* arg types.
|
||||
*/
|
||||
static class ArgTypeDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
static void preRegister(final Context context) {
|
||||
context.put(Log.logKey, new Context.Factory<Log>() {
|
||||
public Log make() {
|
||||
Log log = new Log(context) { };
|
||||
Options options = Options.instance(context);
|
||||
log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
return log;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
ArgTypeDiagnosticFormatter(Options options) {
|
||||
super(null, new SimpleConfiguration(options,
|
||||
EnumSet.of(DiagnosticPart.SUMMARY,
|
||||
DiagnosticPart.DETAILS,
|
||||
DiagnosticPart.SUBDIAGNOSTICS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatDiagnostic(JCDiagnostic d, Locale locale) {
|
||||
return formatMessage(d, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatMessage(JCDiagnostic d, Locale l) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
formatMessage(d, buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private void formatMessage(JCDiagnostic d, StringBuilder buf) {
|
||||
String key = d.getCode();
|
||||
Object[] args = d.getArgs();
|
||||
// report the primary arg types, without recursing into diag fragments
|
||||
buf.append(getKeyArgsString(key, args));
|
||||
// report details for any diagnostic fragments
|
||||
for (Object arg: args) {
|
||||
if (arg instanceof JCDiagnostic) {
|
||||
buf.append("\n");
|
||||
formatMessage((JCDiagnostic) arg, buf);
|
||||
}
|
||||
}
|
||||
// report details for any subdiagnostics
|
||||
for (String s: formatSubdiagnostics(d, null)) {
|
||||
buf.append("\n");
|
||||
buf.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRaw() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostic formatter which "localizes" a message as a line
|
||||
* containing a key, and a possibly empty set of descriptive strings for the
|
||||
* arg types.
|
||||
*/
|
||||
static class ArgTypeMessages extends JavacMessages {
|
||||
static void preRegister(final Context c) {
|
||||
c.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
|
||||
public JavacMessages make() {
|
||||
return new ArgTypeMessages(c) {
|
||||
@Override
|
||||
public String getLocalizedString(Locale l, String key, Object... args) {
|
||||
return getKeyArgsString(key, args);
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ArgTypeMessages(Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to generate a string for key and args
|
||||
*/
|
||||
static String getKeyArgsString(String key, Object... args) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(key);
|
||||
String sep = ": ";
|
||||
for (Object o : args) {
|
||||
buf.append(sep);
|
||||
buf.append(getArgTypeOrStringValue(o));
|
||||
sep = ", ";
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static boolean showStringValues = false;
|
||||
|
||||
static String getArgTypeOrStringValue(Object o) {
|
||||
if (showStringValues && o instanceof String)
|
||||
return "\"" + o + "\"";
|
||||
return getArgType(o);
|
||||
}
|
||||
|
||||
static String getArgType(Object o) {
|
||||
if (o == null)
|
||||
return "null";
|
||||
if (o instanceof Name)
|
||||
return "name";
|
||||
if (o instanceof Boolean)
|
||||
return "boolean";
|
||||
if (o instanceof Integer)
|
||||
return "number";
|
||||
if (o instanceof String)
|
||||
return "string";
|
||||
if (o instanceof Flag)
|
||||
return "modifier";
|
||||
if (o instanceof KindName)
|
||||
return "symbol kind";
|
||||
if (o instanceof Token)
|
||||
return "token";
|
||||
if (o instanceof Symbol)
|
||||
return "symbol";
|
||||
if (o instanceof Type)
|
||||
return "type";
|
||||
if (o instanceof List) {
|
||||
List<?> l = (List<?>) o;
|
||||
if (l.isEmpty())
|
||||
return "list";
|
||||
else
|
||||
return "list of " + getArgType(l.get(0));
|
||||
}
|
||||
if (o instanceof ListBuffer)
|
||||
return getArgType(((ListBuffer) o).toList());
|
||||
if (o instanceof Set) {
|
||||
Set<?> s = (Set<?>) o;
|
||||
if (s.isEmpty())
|
||||
return "set";
|
||||
else
|
||||
return "set of " + getArgType(s.iterator().next());
|
||||
}
|
||||
if (o instanceof SourceVersion)
|
||||
return "source version";
|
||||
if (o instanceof FileObject || o instanceof File)
|
||||
return "file name";
|
||||
if (o instanceof JCDiagnostic)
|
||||
return "message segment";
|
||||
if (o instanceof LocalizedString)
|
||||
return "message segment"; // only instance is "no arguments"
|
||||
String s = o.getClass().getSimpleName();
|
||||
return (s.isEmpty() ? o.getClass().getName() : s);
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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
|
||||
@ -168,7 +168,7 @@ class Example implements Comparable<Example> {
|
||||
try {
|
||||
run(null, keys, true, verbose);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
@ -293,10 +293,15 @@ class Example implements Comparable<Example> {
|
||||
}
|
||||
|
||||
abstract static class Compiler {
|
||||
static Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
interface Factory {
|
||||
Compiler getCompiler(List<String> opts, boolean verbose);
|
||||
}
|
||||
|
||||
static class DefaultFactory implements Factory {
|
||||
public Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
String first;
|
||||
String[] rest;
|
||||
if (opts == null || opts.size() == 0) {
|
||||
if (opts == null || opts.isEmpty()) {
|
||||
first = null;
|
||||
rest = new String[0];
|
||||
} else {
|
||||
@ -311,6 +316,16 @@ class Example implements Comparable<Example> {
|
||||
return new BackdoorCompiler(verbose);
|
||||
else
|
||||
throw new IllegalArgumentException(first);
|
||||
}
|
||||
}
|
||||
|
||||
static Factory factory;
|
||||
|
||||
static Compiler getCompiler(List<String> opts, boolean verbose) {
|
||||
if (factory == null)
|
||||
factory = new DefaultFactory();
|
||||
|
||||
return factory.getCompiler(opts, verbose);
|
||||
}
|
||||
|
||||
protected Compiler(boolean verbose) {
|
||||
|
463
langtools/test/tools/javac/diags/MessageFile.java
Normal file
463
langtools/test/tools/javac/diags/MessageFile.java
Normal file
@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Class to facilitate manipulating compiler.properties.
|
||||
*/
|
||||
class MessageFile {
|
||||
static final Pattern emptyOrCommentPattern = Pattern.compile("( *#.*)?");
|
||||
static final Pattern infoPattern = Pattern.compile("# ([0-9]+: [-A-Za-z ]+, )*[0-9]+: [-A-Za-z ]+");
|
||||
|
||||
/**
|
||||
* A line of text within the message file.
|
||||
* The lines form a doubly linked list for simple navigation.
|
||||
*/
|
||||
class Line {
|
||||
String text;
|
||||
Line prev;
|
||||
Line next;
|
||||
|
||||
Line(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
boolean isEmptyOrComment() {
|
||||
return emptyOrCommentPattern.matcher(text).matches();
|
||||
}
|
||||
|
||||
boolean isInfo() {
|
||||
return infoPattern.matcher(text).matches();
|
||||
}
|
||||
|
||||
boolean hasContinuation() {
|
||||
return (next != null) && text.endsWith("\\");
|
||||
}
|
||||
|
||||
Line insertAfter(String text) {
|
||||
Line l = new Line(text);
|
||||
insertAfter(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
void insertAfter(Line l) {
|
||||
assert prev == null && next == null;
|
||||
l.prev = this;
|
||||
l.next = next;
|
||||
if (next == null)
|
||||
lastLine = l;
|
||||
else
|
||||
next.prev = l;
|
||||
next = l;
|
||||
}
|
||||
|
||||
Line insertBefore(String text) {
|
||||
Line l = new Line(text);
|
||||
insertBefore(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
void insertBefore(Line l) {
|
||||
assert prev == null && next == null;
|
||||
l.prev = prev;
|
||||
l.next = this;
|
||||
if (prev == null)
|
||||
firstLine = l;
|
||||
else
|
||||
prev.next = l;
|
||||
prev = l;
|
||||
}
|
||||
|
||||
void remove() {
|
||||
if (prev == null)
|
||||
firstLine = next;
|
||||
else
|
||||
prev.next = next;
|
||||
if (next == null)
|
||||
lastLine = prev;
|
||||
else
|
||||
next.prev = prev;
|
||||
prev = null;
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A message within the message file.
|
||||
* A message is a series of lines containing a "name=value" property,
|
||||
* optionally preceded by a comment describing the use of placeholders
|
||||
* such as {0}, {1}, etc within the property value.
|
||||
*/
|
||||
static final class Message {
|
||||
final Line firstLine;
|
||||
private Info info;
|
||||
|
||||
Message(Line l) {
|
||||
firstLine = l;
|
||||
}
|
||||
|
||||
boolean needInfo() {
|
||||
Line l = firstLine;
|
||||
while (true) {
|
||||
if (l.text.matches(".*\\{[0-9]+\\}.*"))
|
||||
return true;
|
||||
if (!l.hasContinuation())
|
||||
return false;
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> getPlaceholders() {
|
||||
Pattern p = Pattern.compile("\\{([0-9]+)\\}");
|
||||
Set<Integer> results = new TreeSet<Integer>();
|
||||
Line l = firstLine;
|
||||
while (true) {
|
||||
Matcher m = p.matcher(l.text);
|
||||
while (m.find())
|
||||
results.add(Integer.parseInt(m.group(1)));
|
||||
if (!l.hasContinuation())
|
||||
return results;
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Info object for this message. It may be empty if there
|
||||
* if no comment preceding the property specification.
|
||||
*/
|
||||
Info getInfo() {
|
||||
if (info == null) {
|
||||
Line l = firstLine.prev;
|
||||
if (l != null && l.isInfo())
|
||||
info = new Info(l.text);
|
||||
else
|
||||
info = new Info();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Info for this message.
|
||||
* If there was an info comment preceding the property specification,
|
||||
* it will be updated; otherwise, one will be inserted.
|
||||
*/
|
||||
void setInfo(Info info) {
|
||||
this.info = info;
|
||||
Line l = firstLine.prev;
|
||||
if (l != null && l.isInfo())
|
||||
l.text = info.toComment();
|
||||
else
|
||||
firstLine.insertBefore(info.toComment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the lines pertaining to this message.
|
||||
*/
|
||||
List<Line> getLines(boolean includeAllPrecedingComments) {
|
||||
List<Line> lines = new ArrayList<Line>();
|
||||
Line l = firstLine;
|
||||
if (includeAllPrecedingComments) {
|
||||
// scan back to find end of prev message
|
||||
while (l.prev != null && l.prev.isEmptyOrComment())
|
||||
l = l.prev;
|
||||
// skip leading blank lines
|
||||
while (l.text.isEmpty())
|
||||
l = l.next;
|
||||
} else {
|
||||
if (l.prev != null && l.prev.isInfo())
|
||||
l = l.prev;
|
||||
}
|
||||
|
||||
// include any preceding lines
|
||||
for ( ; l != firstLine; l = l.next)
|
||||
lines.add(l);
|
||||
|
||||
// include message lines
|
||||
for (l = firstLine; l != null && l.hasContinuation(); l = l.next)
|
||||
lines.add(l);
|
||||
lines.add(l);
|
||||
|
||||
// include trailing blank line if present
|
||||
l = l.next;
|
||||
if (l != null && l.text.isEmpty())
|
||||
lines.add(l);
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object to represent the comment that may precede the property
|
||||
* specification in a Message.
|
||||
* The comment is modelled as a list of fields, where the fields correspond
|
||||
* to the placeholder values (e.g. {0}, {1}, etc) within the message value.
|
||||
*/
|
||||
static final class Info {
|
||||
/**
|
||||
* An ordered set of descriptions for a placeholder value in a
|
||||
* message.
|
||||
*/
|
||||
static class Field {
|
||||
boolean unused;
|
||||
Set<String> values;
|
||||
boolean listOfAny = false;
|
||||
boolean setOfAny = false;
|
||||
Field(String s) {
|
||||
s = s.substring(s.indexOf(": ") + 2);
|
||||
values = new LinkedHashSet<String>(Arrays.asList(s.split(" or ")));
|
||||
for (String v: values) {
|
||||
if (v.startsWith("list of"))
|
||||
listOfAny = true;
|
||||
if (v.startsWith("set of"))
|
||||
setOfAny = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this field logically contains all the values of
|
||||
* another field.
|
||||
*/
|
||||
boolean contains(Field other) {
|
||||
if (unused != other.unused)
|
||||
return false;
|
||||
|
||||
for (String v: other.values) {
|
||||
if (values.contains(v))
|
||||
continue;
|
||||
if (v.equals("null") || v.equals("string"))
|
||||
continue;
|
||||
if (v.equals("list") && listOfAny)
|
||||
continue;
|
||||
if (v.equals("set") && setOfAny)
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the values of another field into this field.
|
||||
*/
|
||||
void merge(Field other) {
|
||||
unused |= other.unused;
|
||||
values.addAll(other.values);
|
||||
|
||||
// cleanup unnecessary entries
|
||||
|
||||
if (values.contains("null") && values.size() > 1) {
|
||||
// "null" is superceded by anything else
|
||||
values.remove("null");
|
||||
}
|
||||
|
||||
if (values.contains("string") && values.size() > 1) {
|
||||
// "string" is superceded by anything else
|
||||
values.remove("string");
|
||||
}
|
||||
|
||||
if (values.contains("list")) {
|
||||
// list is superceded by "list of ..."
|
||||
for (String s: values) {
|
||||
if (s.startsWith("list of ")) {
|
||||
values.remove("list");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (values.contains("set")) {
|
||||
// set is superceded by "set of ..."
|
||||
for (String s: values) {
|
||||
if (s.startsWith("set of ")) {
|
||||
values.remove("set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (other.values.contains("unused")) {
|
||||
values.clear();
|
||||
values.add("unused");
|
||||
}
|
||||
}
|
||||
|
||||
void markUnused() {
|
||||
values = new LinkedHashSet<String>();
|
||||
values.add("unused");
|
||||
listOfAny = false;
|
||||
setOfAny = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return values.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/** The fields of the Info object. */
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
|
||||
Info() { }
|
||||
|
||||
Info(String text) throws IllegalArgumentException {
|
||||
if (!text.startsWith("# "))
|
||||
throw new IllegalArgumentException();
|
||||
String[] segs = text.substring(2).split(", ");
|
||||
fields = new ArrayList<Field>();
|
||||
for (String seg: segs) {
|
||||
fields.add(new Field(seg));
|
||||
}
|
||||
}
|
||||
|
||||
Info(Set<String> infos) throws IllegalArgumentException {
|
||||
for (String s: infos)
|
||||
merge(new Info(s));
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return fields.isEmpty();
|
||||
}
|
||||
|
||||
boolean contains(Info other) {
|
||||
if (other.isEmpty())
|
||||
return true;
|
||||
|
||||
if (fields.size() != other.fields.size())
|
||||
return false;
|
||||
|
||||
Iterator<Field> oIter = other.fields.iterator();
|
||||
for (Field values: fields) {
|
||||
if (!values.contains(oIter.next()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void merge(Info other) {
|
||||
if (fields.isEmpty()) {
|
||||
fields.addAll(other.fields);
|
||||
return;
|
||||
}
|
||||
|
||||
if (other.fields.size() != fields.size())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
Iterator<Field> oIter = other.fields.iterator();
|
||||
for (Field d: fields) {
|
||||
d.merge(oIter.next());
|
||||
}
|
||||
}
|
||||
|
||||
void markUnused(Set<Integer> used) {
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
if (!used.contains(i))
|
||||
fields.get(i).markUnused();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fields.toString();
|
||||
}
|
||||
|
||||
String toComment() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# ");
|
||||
String sep = "";
|
||||
int i = 0;
|
||||
for (Field f: fields) {
|
||||
sb.append(sep);
|
||||
sb.append(i++);
|
||||
sb.append(": ");
|
||||
sep = "";
|
||||
for (String s: f.values) {
|
||||
sb.append(sep);
|
||||
sb.append(s);
|
||||
sep = " or ";
|
||||
}
|
||||
sep = ", ";
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Line firstLine;
|
||||
Line lastLine;
|
||||
Map<String, Message> messages = new TreeMap<String, Message>();
|
||||
|
||||
MessageFile(File file) throws IOException {
|
||||
Reader in = new FileReader(file);
|
||||
try {
|
||||
read(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
MessageFile(Reader in) throws IOException {
|
||||
read(in);
|
||||
}
|
||||
|
||||
final void read(Reader in) throws IOException {
|
||||
BufferedReader br = (in instanceof BufferedReader)
|
||||
? (BufferedReader) in
|
||||
: new BufferedReader(in);
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
Line l;
|
||||
if (firstLine == null)
|
||||
l = firstLine = lastLine = new Line(line);
|
||||
else
|
||||
l = lastLine.insertAfter(line);
|
||||
if (line.startsWith("compiler.")) {
|
||||
int eq = line.indexOf("=");
|
||||
if (eq > 0)
|
||||
messages.put(line.substring(0, eq), new Message(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write(File file) throws IOException {
|
||||
Writer out = new FileWriter(file);
|
||||
try {
|
||||
write(out);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
void write(Writer out) throws IOException {
|
||||
BufferedWriter bw = (out instanceof BufferedWriter)
|
||||
? (BufferedWriter) out
|
||||
: new BufferedWriter(out);
|
||||
for (Line l = firstLine; l != null; l = l.next) {
|
||||
bw.write(l.text);
|
||||
bw.write("\n"); // always use Unix line endings
|
||||
}
|
||||
bw.flush();
|
||||
}
|
||||
}
|
406
langtools/test/tools/javac/diags/MessageInfo.java
Normal file
406
langtools/test/tools/javac/diags/MessageInfo.java
Normal file
@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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.
|
||||
*
|
||||
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 7013272
|
||||
* @summary Automatically generate info about how compiler resource keys are used
|
||||
* @build Example ArgTypeCompilerFactory MessageFile MessageInfo
|
||||
* @run main MessageInfo
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility to manipulate compiler.properties, and suggest info comments based
|
||||
* on information derived from running examples.
|
||||
*
|
||||
* Options:
|
||||
* -examples dir location of examples directory
|
||||
* -o file output file
|
||||
* -check just check message file
|
||||
* -ensureNewlines ensure newline after each entry
|
||||
* -fixIndent fix indentation of continuation lines
|
||||
* -sort sort messages
|
||||
* -verbose verbose output
|
||||
* -replace replace comments instead of merging comments
|
||||
* file javac compiler.properties file
|
||||
*
|
||||
*/
|
||||
public class MessageInfo {
|
||||
public static void main(String... args) throws Exception {
|
||||
jtreg = (System.getProperty("test.src") != null);
|
||||
File tmpDir;
|
||||
if (jtreg) {
|
||||
// use standard jtreg scratch directory: the current directory
|
||||
tmpDir = new File(System.getProperty("user.dir"));
|
||||
} else {
|
||||
tmpDir = new File(System.getProperty("java.io.tmpdir"),
|
||||
MessageInfo.class.getName()
|
||||
+ (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
|
||||
}
|
||||
Example.setTempDir(tmpDir);
|
||||
Example.Compiler.factory = new ArgTypeCompilerFactory();
|
||||
|
||||
MessageInfo mi = new MessageInfo();
|
||||
|
||||
try {
|
||||
if (mi.run(args))
|
||||
return;
|
||||
} finally {
|
||||
/* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
|
||||
* jtreg scratch directory, which is the current directory.
|
||||
* In case someone is faking jtreg mode, make sure to only
|
||||
* clean tmpDir when it is reasonable to do so.
|
||||
*/
|
||||
if (tmpDir.isDirectory() &&
|
||||
tmpDir.getName().startsWith(MessageInfo.class.getName())) {
|
||||
if (clean(tmpDir))
|
||||
tmpDir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (jtreg)
|
||||
throw new Exception(mi.errors + " errors occurred");
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
void usage() {
|
||||
System.out.println("Usage:");
|
||||
System.out.println(" java MessageInfo [options] [file]");
|
||||
System.out.println("where options include");
|
||||
System.out.println(" -examples dir location of examples directory");
|
||||
System.out.println(" -o file output file");
|
||||
System.out.println(" -check just check message file");
|
||||
System.out.println(" -ensureNewlines ensure newline after each entry");
|
||||
System.out.println(" -fixIndent fix indentation of continuation lines");
|
||||
System.out.println(" -sort sort messages");
|
||||
System.out.println(" -verbose verbose output");
|
||||
System.out.println(" -replace replace comments instead of merging comments");
|
||||
System.out.println(" file javac compiler.properties file");
|
||||
}
|
||||
|
||||
boolean run(String... args) {
|
||||
File testSrc = new File(System.getProperty("test.src", "."));
|
||||
File examplesDir = new File(testSrc, "examples");
|
||||
File notYetFile = null;
|
||||
File msgFile = null;
|
||||
File outFile = null;
|
||||
boolean verbose = false;
|
||||
boolean ensureNewlines = false;
|
||||
boolean fixIndent = false;
|
||||
boolean sort = false;
|
||||
boolean replace = false;
|
||||
boolean check = jtreg; // default true in jtreg mode
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("-examples") && (i + 1) < args.length)
|
||||
examplesDir = new File(args[++i]);
|
||||
else if(arg.equals("-notyet") && (i + 1) < args.length)
|
||||
notYetFile = new File(args[++i]);
|
||||
else if (arg.equals("-ensureNewlines"))
|
||||
ensureNewlines = true;
|
||||
else if (arg.equals("-fixIndent"))
|
||||
fixIndent = true;
|
||||
else if (arg.equals("-sort"))
|
||||
sort = true;
|
||||
else if (arg.equals("-verbose"))
|
||||
verbose = true;
|
||||
else if (arg.equals("-replace"))
|
||||
replace = true;
|
||||
else if (arg.equals("-check"))
|
||||
check = true;
|
||||
else if (arg.equals("-o") && (i + 1) < args.length)
|
||||
outFile = new File(args[++i]);
|
||||
else if (arg.startsWith("-")) {
|
||||
error("unknown option: " + arg);
|
||||
return false;
|
||||
} else if (i == args.length - 1) {
|
||||
msgFile = new File(arg);
|
||||
} else {
|
||||
error("unknown arg: " + arg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check && outFile == null) {
|
||||
usage();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ensureNewlines || fixIndent || sort) && outFile == null) {
|
||||
error("must set output file for these options");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (notYetFile == null) {
|
||||
notYetFile = new File(examplesDir.getParentFile(), "examples.not-yet.txt");
|
||||
}
|
||||
|
||||
if (msgFile == null) {
|
||||
for (File d = testSrc; d != null; d = d.getParentFile()) {
|
||||
if (new File(d, "TEST.ROOT").exists()) {
|
||||
d = d.getParentFile();
|
||||
File f = new File(d, "src/share/classes/com/sun/tools/javac/resources/compiler.properties");
|
||||
if (f.exists()) {
|
||||
msgFile = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (msgFile == null) {
|
||||
error("no message file available");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MessageFile mf;
|
||||
try {
|
||||
mf = new MessageFile(msgFile);
|
||||
} catch (IOException e) {
|
||||
error("problem reading message file: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, Set<String>> msgInfo = runExamples(examplesDir, verbose);
|
||||
|
||||
if (ensureNewlines)
|
||||
ensureNewlines(mf);
|
||||
|
||||
if (fixIndent)
|
||||
fixIndent(mf);
|
||||
|
||||
if (sort)
|
||||
sort(mf, true);
|
||||
|
||||
for (Map.Entry<String, Set<String>> e: msgInfo.entrySet()) {
|
||||
String k = e.getKey();
|
||||
Set<String> suggestions = e.getValue();
|
||||
MessageFile.Message m = mf.messages.get(k);
|
||||
if (m == null) {
|
||||
error("Can't find message for " + k + " in message file");
|
||||
continue;
|
||||
}
|
||||
|
||||
MessageFile.Info info = m.getInfo();
|
||||
Set<Integer> placeholders = m.getPlaceholders();
|
||||
MessageFile.Info suggestedInfo = new MessageFile.Info(suggestions);
|
||||
suggestedInfo.markUnused(placeholders);
|
||||
|
||||
if (!info.isEmpty()) {
|
||||
if (info.contains(suggestedInfo))
|
||||
continue;
|
||||
if (!replace) {
|
||||
if (info.fields.size() != suggestedInfo.fields.size())
|
||||
error("Cannot merge info for " + k);
|
||||
else
|
||||
suggestedInfo.merge(info);
|
||||
}
|
||||
}
|
||||
|
||||
if (outFile == null) {
|
||||
System.err.println("suggest for " + k);
|
||||
System.err.println(suggestedInfo.toComment());
|
||||
} else
|
||||
m.setInfo(suggestedInfo);
|
||||
}
|
||||
|
||||
if (check)
|
||||
check(mf, notYetFile);
|
||||
|
||||
try {
|
||||
if (outFile != null)
|
||||
mf.write(outFile);
|
||||
} catch (IOException e) {
|
||||
error("problem writing file: " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return (errors == 0);
|
||||
}
|
||||
|
||||
void check(MessageFile mf, File notYetFile) {
|
||||
Set<String> notYetList = null;
|
||||
for (Map.Entry<String, MessageFile.Message> e: mf.messages.entrySet()) {
|
||||
String key = e.getKey();
|
||||
MessageFile.Message m = e.getValue();
|
||||
if (m.needInfo() && m.getInfo().isEmpty()) {
|
||||
if (notYetList == null)
|
||||
notYetList = getNotYetList(notYetFile);
|
||||
if (notYetList.contains(key))
|
||||
System.err.println("Warning: no info for " + key);
|
||||
else
|
||||
error("no info for " + key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ensureNewlines(MessageFile mf) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
MessageFile.Line l = m.firstLine;
|
||||
while (l.text.endsWith("\\"))
|
||||
l = l.next;
|
||||
if (l.next != null && !l.next.text.isEmpty())
|
||||
l.insertAfter("");
|
||||
}
|
||||
}
|
||||
|
||||
void fixIndent(MessageFile mf) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
MessageFile.Line l = m.firstLine;
|
||||
while (l.text.endsWith("\\") && l.next != null) {
|
||||
if (!l.next.text.matches("^ \\S.*"))
|
||||
l.next.text = " " + l.next.text.trim();
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sort(MessageFile mf, boolean includePrecedingNewlines) {
|
||||
for (MessageFile.Message m: mf.messages.values()) {
|
||||
for (MessageFile.Line l: m.getLines(includePrecedingNewlines)) {
|
||||
l.remove();
|
||||
mf.lastLine.insertAfter(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Set<String>> runExamples(File examplesDir, boolean verbose) {
|
||||
Map<String, Set<String>> map = new TreeMap<String, Set<String>>();
|
||||
for (Example e: getExamples(examplesDir)) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
e.run(pw, true, verbose);
|
||||
pw.close();
|
||||
String[] lines = sw.toString().split("\n");
|
||||
for (String line: lines) {
|
||||
if (!line.startsWith("compiler."))
|
||||
continue;
|
||||
int colon = line.indexOf(":");
|
||||
if (colon == -1)
|
||||
continue;
|
||||
String key = line.substring(0, colon);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("# ");
|
||||
int i = 0;
|
||||
String[] descs = line.substring(colon + 1).split(", *");
|
||||
for (String desc: descs) {
|
||||
if (i > 0) sb.append(", ");
|
||||
sb.append(i++);
|
||||
sb.append(": ");
|
||||
sb.append(desc.trim());
|
||||
}
|
||||
Set<String> set = map.get(key);
|
||||
if (set == null)
|
||||
map.put(key, set = new TreeSet<String>());
|
||||
set.add(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete set of examples to be checked.
|
||||
*/
|
||||
Set<Example> getExamples(File examplesDir) {
|
||||
Set<Example> results = new TreeSet<Example>();
|
||||
for (File f: examplesDir.listFiles()) {
|
||||
if (isValidExample(f))
|
||||
results.add(new Example(f));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
boolean isValidExample(File f) {
|
||||
return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
|
||||
(f.isFile() && f.getName().endsWith(".java"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the contents of the "not-yet" list.
|
||||
*/
|
||||
Set<String> getNotYetList(File file) {
|
||||
Set<String> results = new TreeSet<String>();
|
||||
try {
|
||||
String[] lines = read(file).split("[\r\n]");
|
||||
for (String line: lines) {
|
||||
int hash = line.indexOf("#");
|
||||
if (hash != -1)
|
||||
line = line.substring(0, hash).trim();
|
||||
if (line.matches("[A-Za-z0-9-_.]+"))
|
||||
results.add(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents of a file.
|
||||
*/
|
||||
String read(File f) throws IOException {
|
||||
byte[] bytes = new byte[(int) f.length()];
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(f));
|
||||
try {
|
||||
in.readFully(bytes);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report an error.
|
||||
*/
|
||||
void error(String msg) {
|
||||
System.err.println("Error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
static boolean jtreg;
|
||||
|
||||
int errors;
|
||||
|
||||
/**
|
||||
* Clean the contents of a directory.
|
||||
*/
|
||||
static boolean clean(File dir) {
|
||||
boolean ok = true;
|
||||
for (File f: dir.listFiles()) {
|
||||
if (f.isDirectory())
|
||||
ok &= clean(f);
|
||||
ok &= f.delete();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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
|
||||
@ -25,7 +25,7 @@
|
||||
* @test
|
||||
* @bug 6968063
|
||||
* @summary provide examples of code that generate diagnostics
|
||||
* @build Example HTMLWriter RunExamples
|
||||
* @build ArgTypeCompilerFactory Example HTMLWriter RunExamples
|
||||
* @run main RunExamples
|
||||
*/
|
||||
|
||||
@ -97,6 +97,7 @@ public class RunExamples {
|
||||
boolean raw = false;
|
||||
boolean showFiles = false;
|
||||
boolean verbose = false;
|
||||
boolean argTypes = false;
|
||||
String title = null;
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
@ -115,6 +116,8 @@ public class RunExamples {
|
||||
outFile = new File(args[++i]);
|
||||
else if (arg.equals("-title") && (i + 1) < args.length)
|
||||
title = args[++i];
|
||||
else if (arg.equals("-argtypes"))
|
||||
argTypes = true;
|
||||
else if (arg.startsWith("-")) {
|
||||
error("unknown option: " + arg);
|
||||
return false;
|
||||
@ -127,6 +130,11 @@ public class RunExamples {
|
||||
}
|
||||
}
|
||||
|
||||
// special mode to show message keys and the types of the args that
|
||||
// are used.
|
||||
if (argTypes)
|
||||
Example.Compiler.factory = new ArgTypeCompilerFactory();
|
||||
|
||||
if (selectedKeys.size() > 0) {
|
||||
Set<Example> examples = getExamples(examplesDir);
|
||||
nextKey:
|
||||
@ -138,7 +146,7 @@ public class RunExamples {
|
||||
error("Key " + k + ": no examples found");
|
||||
}
|
||||
} else {
|
||||
if (selectedExamples.size() == 0)
|
||||
if (selectedExamples.isEmpty())
|
||||
selectedExamples = getExamples(examplesDir);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user