test/tools/javac/diags/MessageInfo.java

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 2525
2eb010b6cb22
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset eb6ee6a5f2fe

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 /**
aoqi@0 25 * @test
aoqi@0 26 * @bug 7013272 7127924
aoqi@0 27 * @summary Automatically generate info about how compiler resource keys are used
aoqi@0 28 * @build Example ArgTypeCompilerFactory MessageFile MessageInfo
aoqi@0 29 * @run main/othervm MessageInfo
aoqi@0 30 */
aoqi@0 31 /*
aoqi@0 32 * See CR 7127924 for info on why othervm is used.
aoqi@0 33 */
aoqi@0 34
aoqi@0 35 import java.io.*;
aoqi@0 36 import java.text.SimpleDateFormat;
aoqi@0 37 import java.util.*;
aoqi@0 38
aoqi@0 39 /**
aoqi@0 40 * Utility to manipulate compiler.properties, and suggest info comments based
aoqi@0 41 * on information derived from running examples.
aoqi@0 42 *
aoqi@0 43 * Options:
aoqi@0 44 * -examples dir location of examples directory
aoqi@0 45 * -o file output file
aoqi@0 46 * -check just check message file
aoqi@0 47 * -ensureNewlines ensure newline after each entry
aoqi@0 48 * -fixIndent fix indentation of continuation lines
aoqi@0 49 * -sort sort messages
aoqi@0 50 * -verbose verbose output
aoqi@0 51 * -replace replace comments instead of merging comments
aoqi@0 52 * file javac compiler.properties file
aoqi@0 53 *
aoqi@0 54 */
aoqi@0 55 public class MessageInfo {
aoqi@0 56 public static void main(String... args) throws Exception {
aoqi@0 57 jtreg = (System.getProperty("test.src") != null);
aoqi@0 58 File tmpDir;
aoqi@0 59 if (jtreg) {
aoqi@0 60 // use standard jtreg scratch directory: the current directory
aoqi@0 61 tmpDir = new File(System.getProperty("user.dir"));
aoqi@0 62 } else {
aoqi@0 63 tmpDir = new File(System.getProperty("java.io.tmpdir"),
aoqi@0 64 MessageInfo.class.getName()
aoqi@0 65 + (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
aoqi@0 66 }
aoqi@0 67 Example.setTempDir(tmpDir);
aoqi@0 68 Example.Compiler.factory = new ArgTypeCompilerFactory();
aoqi@0 69
aoqi@0 70 MessageInfo mi = new MessageInfo();
aoqi@0 71
aoqi@0 72 try {
aoqi@0 73 if (mi.run(args))
aoqi@0 74 return;
aoqi@0 75 } finally {
aoqi@0 76 /* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
aoqi@0 77 * jtreg scratch directory, which is the current directory.
aoqi@0 78 * In case someone is faking jtreg mode, make sure to only
aoqi@0 79 * clean tmpDir when it is reasonable to do so.
aoqi@0 80 */
aoqi@0 81 if (tmpDir.isDirectory() &&
aoqi@0 82 tmpDir.getName().startsWith(MessageInfo.class.getName())) {
aoqi@0 83 if (clean(tmpDir))
aoqi@0 84 tmpDir.delete();
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 if (jtreg)
aoqi@0 89 throw new Exception(mi.errors + " errors occurred");
aoqi@0 90 else
aoqi@0 91 System.exit(1);
aoqi@0 92 }
aoqi@0 93
aoqi@0 94 void usage() {
aoqi@0 95 System.out.println("Usage:");
aoqi@0 96 System.out.println(" java MessageInfo [options] [file]");
aoqi@0 97 System.out.println("where options include");
aoqi@0 98 System.out.println(" -examples dir location of examples directory");
aoqi@0 99 System.out.println(" -o file output file");
aoqi@0 100 System.out.println(" -check just check message file");
aoqi@0 101 System.out.println(" -ensureNewlines ensure newline after each entry");
aoqi@0 102 System.out.println(" -fixIndent fix indentation of continuation lines");
aoqi@0 103 System.out.println(" -sort sort messages");
aoqi@0 104 System.out.println(" -verbose verbose output");
aoqi@0 105 System.out.println(" -replace replace comments instead of merging comments");
aoqi@0 106 System.out.println(" file javac compiler.properties file");
aoqi@0 107 }
aoqi@0 108
aoqi@0 109 boolean run(String... args) {
aoqi@0 110 File testSrc = new File(System.getProperty("test.src", "."));
aoqi@0 111 File examplesDir = new File(testSrc, "examples");
aoqi@0 112 File notYetFile = null;
aoqi@0 113 File msgFile = null;
aoqi@0 114 File outFile = null;
aoqi@0 115 boolean verbose = false;
aoqi@0 116 boolean ensureNewlines = false;
aoqi@0 117 boolean fixIndent = false;
aoqi@0 118 boolean sort = false;
aoqi@0 119 boolean replace = false;
aoqi@0 120 boolean check = jtreg; // default true in jtreg mode
aoqi@0 121
aoqi@0 122 for (int i = 0; i < args.length; i++) {
aoqi@0 123 String arg = args[i];
aoqi@0 124 if (arg.equals("-examples") && (i + 1) < args.length)
aoqi@0 125 examplesDir = new File(args[++i]);
aoqi@0 126 else if(arg.equals("-notyet") && (i + 1) < args.length)
aoqi@0 127 notYetFile = new File(args[++i]);
aoqi@0 128 else if (arg.equals("-ensureNewlines"))
aoqi@0 129 ensureNewlines = true;
aoqi@0 130 else if (arg.equals("-fixIndent"))
aoqi@0 131 fixIndent = true;
aoqi@0 132 else if (arg.equals("-sort"))
aoqi@0 133 sort = true;
aoqi@0 134 else if (arg.equals("-verbose"))
aoqi@0 135 verbose = true;
aoqi@0 136 else if (arg.equals("-replace"))
aoqi@0 137 replace = true;
aoqi@0 138 else if (arg.equals("-check"))
aoqi@0 139 check = true;
aoqi@0 140 else if (arg.equals("-o") && (i + 1) < args.length)
aoqi@0 141 outFile = new File(args[++i]);
aoqi@0 142 else if (arg.startsWith("-")) {
aoqi@0 143 error("unknown option: " + arg);
aoqi@0 144 return false;
aoqi@0 145 } else if (i == args.length - 1) {
aoqi@0 146 msgFile = new File(arg);
aoqi@0 147 } else {
aoqi@0 148 error("unknown arg: " + arg);
aoqi@0 149 return false;
aoqi@0 150 }
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 if (!check && outFile == null) {
aoqi@0 154 usage();
aoqi@0 155 return true;
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 if ((ensureNewlines || fixIndent || sort) && outFile == null) {
aoqi@0 159 error("must set output file for these options");
aoqi@0 160 return false;
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 if (notYetFile == null) {
aoqi@0 164 notYetFile = new File(examplesDir.getParentFile(), "examples.not-yet.txt");
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 if (msgFile == null) {
aoqi@0 168 for (File d = testSrc; d != null; d = d.getParentFile()) {
aoqi@0 169 if (new File(d, "TEST.ROOT").exists()) {
aoqi@0 170 d = d.getParentFile();
aoqi@0 171 File f = new File(d, "src/share/classes/com/sun/tools/javac/resources/compiler.properties");
aoqi@0 172 if (f.exists()) {
aoqi@0 173 msgFile = f;
aoqi@0 174 break;
aoqi@0 175 }
aoqi@0 176 }
aoqi@0 177 }
aoqi@0 178 if (msgFile == null) {
aoqi@0 179 if (jtreg) {
aoqi@0 180 System.err.println("Warning: no message file available, test skipped");
aoqi@0 181 return true;
aoqi@0 182 }
aoqi@0 183 error("no message file available");
aoqi@0 184 return false;
aoqi@0 185 }
aoqi@0 186 }
aoqi@0 187
aoqi@0 188 MessageFile mf;
aoqi@0 189 try {
aoqi@0 190 mf = new MessageFile(msgFile);
aoqi@0 191 } catch (IOException e) {
aoqi@0 192 error("problem reading message file: " + e);
aoqi@0 193 return false;
aoqi@0 194 }
aoqi@0 195
aoqi@0 196 Map<String, Set<String>> msgInfo = runExamples(examplesDir, verbose);
aoqi@0 197
aoqi@0 198 if (ensureNewlines)
aoqi@0 199 ensureNewlines(mf);
aoqi@0 200
aoqi@0 201 if (fixIndent)
aoqi@0 202 fixIndent(mf);
aoqi@0 203
aoqi@0 204 if (sort)
aoqi@0 205 sort(mf, true);
aoqi@0 206
aoqi@0 207 for (Map.Entry<String, Set<String>> e: msgInfo.entrySet()) {
aoqi@0 208 String k = e.getKey();
aoqi@0 209 Set<String> suggestions = e.getValue();
aoqi@0 210 MessageFile.Message m = mf.messages.get(k);
aoqi@0 211 if (m == null) {
aoqi@0 212 error("Can't find message for " + k + " in message file");
aoqi@0 213 continue;
aoqi@0 214 }
aoqi@0 215
aoqi@0 216 MessageFile.Info info = m.getInfo();
aoqi@0 217 Set<Integer> placeholders = m.getPlaceholders();
aoqi@0 218 MessageFile.Info suggestedInfo = new MessageFile.Info(suggestions);
aoqi@0 219 suggestedInfo.markUnused(placeholders);
aoqi@0 220
aoqi@0 221 if (!info.isEmpty()) {
aoqi@0 222 if (info.contains(suggestedInfo))
aoqi@0 223 continue;
aoqi@0 224 if (!replace) {
aoqi@0 225 if (info.fields.size() != suggestedInfo.fields.size())
aoqi@0 226 error("Cannot merge info for " + k);
aoqi@0 227 else
aoqi@0 228 suggestedInfo.merge(info);
aoqi@0 229 }
aoqi@0 230 }
aoqi@0 231
aoqi@0 232 if (outFile == null) {
aoqi@0 233 System.err.println("suggest for " + k);
aoqi@0 234 System.err.println(suggestedInfo.toComment());
aoqi@0 235 } else
aoqi@0 236 m.setInfo(suggestedInfo);
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 if (check)
aoqi@0 240 check(mf, notYetFile);
aoqi@0 241
aoqi@0 242 try {
aoqi@0 243 if (outFile != null)
aoqi@0 244 mf.write(outFile);
aoqi@0 245 } catch (IOException e) {
aoqi@0 246 error("problem writing file: " + e);
aoqi@0 247 return false;
aoqi@0 248 }
aoqi@0 249
aoqi@0 250 return (errors == 0);
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 void check(MessageFile mf, File notYetFile) {
aoqi@0 254 Set<String> notYetList = null;
aoqi@0 255 for (Map.Entry<String, MessageFile.Message> e: mf.messages.entrySet()) {
aoqi@0 256 String key = e.getKey();
aoqi@0 257 MessageFile.Message m = e.getValue();
aoqi@0 258 if (m.needInfo() && m.getInfo().isEmpty()) {
aoqi@0 259 if (notYetList == null)
aoqi@0 260 notYetList = getNotYetList(notYetFile);
aoqi@0 261 if (notYetList.contains(key))
aoqi@0 262 System.err.println("Warning: no info for " + key);
aoqi@0 263 else
aoqi@0 264 error("no info for " + key);
aoqi@0 265 }
aoqi@0 266 }
aoqi@0 267
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 void ensureNewlines(MessageFile mf) {
aoqi@0 271 for (MessageFile.Message m: mf.messages.values()) {
aoqi@0 272 MessageFile.Line l = m.firstLine;
aoqi@0 273 while (l.text.endsWith("\\"))
aoqi@0 274 l = l.next;
aoqi@0 275 if (l.next != null && !l.next.text.isEmpty())
aoqi@0 276 l.insertAfter("");
aoqi@0 277 }
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 void fixIndent(MessageFile mf) {
aoqi@0 281 for (MessageFile.Message m: mf.messages.values()) {
aoqi@0 282 MessageFile.Line l = m.firstLine;
aoqi@0 283 while (l.text.endsWith("\\") && l.next != null) {
aoqi@0 284 if (!l.next.text.matches("^ \\S.*"))
aoqi@0 285 l.next.text = " " + l.next.text.trim();
aoqi@0 286 l = l.next;
aoqi@0 287 }
aoqi@0 288 }
aoqi@0 289 }
aoqi@0 290
aoqi@0 291 void sort(MessageFile mf, boolean includePrecedingNewlines) {
aoqi@0 292 for (MessageFile.Message m: mf.messages.values()) {
aoqi@0 293 for (MessageFile.Line l: m.getLines(includePrecedingNewlines)) {
aoqi@0 294 l.remove();
aoqi@0 295 mf.lastLine.insertAfter(l);
aoqi@0 296 }
aoqi@0 297 }
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 Map<String, Set<String>> runExamples(File examplesDir, boolean verbose) {
aoqi@0 301 Map<String, Set<String>> map = new TreeMap<String, Set<String>>();
aoqi@0 302 for (Example e: getExamples(examplesDir)) {
aoqi@0 303 StringWriter sw = new StringWriter();
aoqi@0 304 PrintWriter pw = new PrintWriter(sw);
aoqi@0 305 e.run(pw, true, verbose);
aoqi@0 306 pw.close();
aoqi@0 307 String[] lines = sw.toString().split("\n");
aoqi@0 308 for (String line: lines) {
aoqi@0 309 if (!line.startsWith("compiler."))
aoqi@0 310 continue;
aoqi@0 311 int colon = line.indexOf(":");
aoqi@0 312 if (colon == -1)
aoqi@0 313 continue;
aoqi@0 314 String key = line.substring(0, colon);
aoqi@0 315 StringBuilder sb = new StringBuilder();
aoqi@0 316 sb.append("# ");
aoqi@0 317 int i = 0;
aoqi@0 318 String[] descs = line.substring(colon + 1).split(", *");
aoqi@0 319 for (String desc: descs) {
aoqi@0 320 if (i > 0) sb.append(", ");
aoqi@0 321 sb.append(i++);
aoqi@0 322 sb.append(": ");
aoqi@0 323 sb.append(desc.trim());
aoqi@0 324 }
aoqi@0 325 Set<String> set = map.get(key);
aoqi@0 326 if (set == null)
aoqi@0 327 map.put(key, set = new TreeSet<String>());
aoqi@0 328 set.add(sb.toString());
aoqi@0 329 }
aoqi@0 330 }
aoqi@0 331
aoqi@0 332 return map;
aoqi@0 333 }
aoqi@0 334
aoqi@0 335 /**
aoqi@0 336 * Get the complete set of examples to be checked.
aoqi@0 337 */
aoqi@0 338 Set<Example> getExamples(File examplesDir) {
aoqi@0 339 Set<Example> results = new TreeSet<Example>();
aoqi@0 340 for (File f: examplesDir.listFiles()) {
aoqi@0 341 if (isValidExample(f))
aoqi@0 342 results.add(new Example(f));
aoqi@0 343 }
aoqi@0 344 return results;
aoqi@0 345 }
aoqi@0 346
aoqi@0 347 boolean isValidExample(File f) {
aoqi@0 348 return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
aoqi@0 349 (f.isFile() && f.getName().endsWith(".java"));
aoqi@0 350 }
aoqi@0 351
aoqi@0 352 /**
aoqi@0 353 * Get the contents of the "not-yet" list.
aoqi@0 354 */
aoqi@0 355 Set<String> getNotYetList(File file) {
aoqi@0 356 Set<String> results = new TreeSet<String>();
aoqi@0 357 try {
aoqi@0 358 String[] lines = read(file).split("[\r\n]");
aoqi@0 359 for (String line: lines) {
aoqi@0 360 int hash = line.indexOf("#");
aoqi@0 361 if (hash != -1)
aoqi@0 362 line = line.substring(0, hash).trim();
aoqi@0 363 if (line.matches("[A-Za-z0-9-_.]+"))
aoqi@0 364 results.add(line);
aoqi@0 365 }
aoqi@0 366 } catch (IOException e) {
aoqi@0 367 throw new Error(e);
aoqi@0 368 }
aoqi@0 369 return results;
aoqi@0 370 }
aoqi@0 371
aoqi@0 372 /**
aoqi@0 373 * Read the contents of a file.
aoqi@0 374 */
aoqi@0 375 String read(File f) throws IOException {
aoqi@0 376 byte[] bytes = new byte[(int) f.length()];
aoqi@0 377 DataInputStream in = new DataInputStream(new FileInputStream(f));
aoqi@0 378 try {
aoqi@0 379 in.readFully(bytes);
aoqi@0 380 } finally {
aoqi@0 381 in.close();
aoqi@0 382 }
aoqi@0 383 return new String(bytes);
aoqi@0 384 }
aoqi@0 385
aoqi@0 386 /**
aoqi@0 387 * Report an error.
aoqi@0 388 */
aoqi@0 389 void error(String msg) {
aoqi@0 390 System.err.println("Error: " + msg);
aoqi@0 391 errors++;
aoqi@0 392 }
aoqi@0 393
aoqi@0 394 static boolean jtreg;
aoqi@0 395
aoqi@0 396 int errors;
aoqi@0 397
aoqi@0 398 /**
aoqi@0 399 * Clean the contents of a directory.
aoqi@0 400 */
aoqi@0 401 static boolean clean(File dir) {
aoqi@0 402 boolean ok = true;
aoqi@0 403 for (File f: dir.listFiles()) {
aoqi@0 404 if (f.isDirectory())
aoqi@0 405 ok &= clean(f);
aoqi@0 406 ok &= f.delete();
aoqi@0 407 }
aoqi@0 408 return ok;
aoqi@0 409 }
aoqi@0 410
aoqi@0 411 }

mercurial