Showing the changes to java/pkg/sun/tools/javac/Main.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,751 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package sun.tools.javac; | ||
| 27 | |||
| 28 | import sun.tools.java.*; | ||
| 29 | import sun.tools.util.CommandLine; | ||
| 30 | // JCOV | ||
| 31 | import sun.tools.asm.Assembler; | ||
| 32 | // end JCOV | ||
| 33 | |||
| 34 | import java.util.*; | ||
| 35 | import java.io.*; | ||
| 36 | import java.text.MessageFormat; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Main program of the Java compiler | ||
| 40 | * | ||
| 41 | * WARNING: The contents of this source file are not part of any | ||
| 42 | * supported API. Code that depends on them does so at its own risk: | ||
| 43 | * they are subject to change or removal without notice. | ||
| 44 | * | ||
| 45 | * @deprecated As of J2SE 1.3, the preferred way to compile Java | ||
| 46 | * language sources is by using the new compiler, | ||
| 47 | * com.sun.tools.javac.Main. | ||
| 48 | */ | ||
| 49 | @Deprecated | ||
| 50 | public | ||
| 51 | class Main implements Constants { | ||
| 52 | /** | ||
| 53 | * Name of the program. | ||
| 54 | */ | ||
| 55 | String program; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * The stream where error message are printed. | ||
| 59 | */ | ||
| 60 | OutputStream out; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Constructor. | ||
| 64 | */ | ||
| 65 | public Main(OutputStream out, String program) { | ||
| 66 | this.out = out; | ||
| 67 | this.program = program; | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * Exit status. | ||
| 72 | * We introduce a separate integer status variable, and do not alter the | ||
| 73 | * convention that 'compile' returns a boolean true upon a successful | ||
| 74 | * compilation with no errors. (JavaTest relies on this.) | ||
| 75 | */ | ||
| 76 | |||
| 77 | public static final int EXIT_OK = 0; // Compilation completed with no errors. | ||
| 78 | public static final int EXIT_ERROR = 1; // Compilation completed but reported errors. | ||
| 79 | public static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches. | ||
| 80 | public static final int EXIT_SYSERR = 3; // System error or resource exhaustion. | ||
| 81 | public static final int EXIT_ABNORMAL = 4; // Compiler terminated abnormally. | ||
| 82 | |||
| 83 | private int exitStatus; | ||
| 84 | |||
| 85 | public int getExitStatus() { | ||
| 86 | return exitStatus; | ||
| 87 | } | ||
| 88 | |||
| 89 | public boolean compilationPerformedSuccessfully() { | ||
| 90 | return exitStatus == EXIT_OK || exitStatus == EXIT_ERROR; | ||
| 91 | } | ||
| 92 | |||
| 93 | public boolean compilationReportedErrors () { | ||
| 94 | return exitStatus != EXIT_OK; | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Output a message. | ||
| 99 | */ | ||
| 100 | private void output(String msg) { | ||
| 101 | PrintStream out = | ||
| 102 | this.out instanceof PrintStream ? (PrintStream)this.out | ||
| 103 | : new PrintStream(this.out, true); | ||
| 104 | out.println(msg); | ||
| 105 | } | ||
| 106 | |||
| 107 | /** | ||
| 108 | * Top level error message. This method is called when the | ||
| 109 | * environment could not be set up yet. | ||
| 110 | */ | ||
| 111 | private void error(String msg) { | ||
| 112 | exitStatus = EXIT_CMDERR; | ||
| 113 | output(getText(msg)); | ||
| 114 | } | ||
| 115 | |||
| 116 | private void error(String msg, String arg1) { | ||
| 117 | exitStatus = EXIT_CMDERR; | ||
| 118 | output(getText(msg, arg1)); | ||
| 119 | } | ||
| 120 | |||
| 121 | private void error(String msg, String arg1, String arg2) { | ||
| 122 | exitStatus = EXIT_CMDERR; | ||
| 123 | output(getText(msg, arg1, arg2)); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Print usage message and make exit status an error. | ||
| 128 | * Note: 'javac' invoked without any arguments is considered | ||
| 129 | * be an error. | ||
| 130 | */ | ||
| 131 | public void usage_error() { | ||
| 132 | error("main.usage", program); | ||
| 133 | } | ||
| 134 | |||
| 135 | private static ResourceBundle messageRB; | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Initialize ResourceBundle | ||
| 139 | */ | ||
| 140 | static void initResource() { | ||
| 141 | try { | ||
| 142 | messageRB = | ||
| 143 | ResourceBundle.getBundle("sun.tools.javac.resources.javac"); | ||
| 144 | } catch (MissingResourceException e) { | ||
| 145 | throw new Error("Fatal: Resource for javac is missing"); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * get and format message string from resource | ||
| 151 | */ | ||
| 152 | public static String getText(String key) { | ||
| 153 | return getText(key, (String)null); | ||
| 154 | } | ||
| 155 | |||
| 156 | public static String getText(String key, int num) { | ||
| 157 | return getText(key, Integer.toString(num)); | ||
| 158 | } | ||
| 159 | |||
| 160 | public static String getText(String key, String fixed) { | ||
| 161 | return getText(key, fixed, null); | ||
| 162 | } | ||
| 163 | |||
| 164 | public static String getText(String key, String fixed1, String fixed2) { | ||
| 165 | return getText(key, fixed1, fixed2, null); | ||
| 166 | } | ||
| 167 | |||
| 168 | public static String getText(String key, String fixed1, | ||
| 169 | String fixed2, String fixed3) { | ||
| 170 | if (messageRB == null) { | ||
| 171 | initResource(); | ||
| 172 | } | ||
| 173 | try { | ||
| 174 | String message = messageRB.getString(key); | ||
| 175 | return MessageFormat.format(message, fixed1, fixed2, fixed3); | ||
| 176 | } catch (MissingResourceException e) { | ||
| 177 | if (fixed1 == null) fixed1 = "null"; | ||
| 178 | if (fixed2 == null) fixed2 = "null"; | ||
| 179 | if (fixed3 == null) fixed3 = "null"; | ||
| 180 | String message = "JAVAC MESSAGE FILE IS BROKEN: key={0}, arguments={1}, {2}, {3}"; | ||
| 181 | return MessageFormat.format(message, key, fixed1, fixed2, fixed3); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | // What major and minor version numbers to use for the -target flag. | ||
| 186 | // This should grow every time the minor version number accepted by | ||
| 187 | // the VM is incremented. | ||
| 188 | private static final String[] releases = { "1.1", "1.2", "1.3", "1.4" }; | ||
| 189 | private static final short[] majorVersions = { 45, 46, 47, 48 }; | ||
| 190 | private static final short[] minorVersions = { 3, 0, 0, 0 }; | ||
| 191 | |||
| 192 | /** | ||
| 193 | * Run the compiler | ||
| 194 | */ | ||
| 195 | public synchronized boolean compile(String argv[]) { | ||
| 196 | String sourcePathArg = null; | ||
| 197 | String classPathArg = null; | ||
| 198 | String sysClassPathArg = null; | ||
| 199 | String extDirsArg = null; | ||
| 200 | boolean verbosePath = false; | ||
| 201 | |||
| 202 | String targetArg = null; | ||
| 203 | short majorVersion = JAVA_DEFAULT_VERSION; | ||
| 204 | short minorVersion = JAVA_DEFAULT_MINOR_VERSION; | ||
| 205 | |||
| 206 | File destDir = null; | ||
| 207 | //JCOV | ||
| 208 | File covFile = null; | ||
| 209 | String optJcov = "-Xjcov"; | ||
| 210 | String optJcovFile = "-Xjcov:file="; | ||
| 211 | //end JCOV | ||
| 212 | int flags = F_WARNINGS | F_DEBUG_LINES | F_DEBUG_SOURCE; | ||
| 213 | long tm = System.currentTimeMillis(); | ||
| 214 | Vector v = new Vector(); | ||
| 215 | boolean nowrite = false; | ||
| 216 | String props = null; | ||
| 217 | String encoding = null; | ||
| 218 | |||
| 219 | // These flags are used to make sure conflicting -O and -g | ||
| 220 | // options aren't given. | ||
| 221 | String prior_g = null; | ||
| 222 | String prior_O = null; | ||
| 223 | |||
| 224 | exitStatus = EXIT_OK; | ||
| 225 | |||
| 226 | // Pre-process command line for @file arguments | ||
| 227 | try { | ||
| 228 | argv = CommandLine.parse(argv); | ||
| 229 | } catch (FileNotFoundException e) { | ||
| 230 | error("javac.err.cant.read", e.getMessage()); | ||
| 231 | System.exit(1); | ||
| 232 | } catch (IOException e) { | ||
| 233 | e.printStackTrace(); | ||
| 234 | System.exit(1); | ||
| 235 | } | ||
| 236 | |||
| 237 | // Parse arguments | ||
| 238 | for (int i = 0 ; i < argv.length ; i++) { | ||
| 239 | if (argv[i].equals("-g")) { | ||
| 240 | if (prior_g!=null && !(prior_g.equals("-g"))) | ||
| 241 | error("main.conflicting.options", prior_g, "-g"); | ||
| 242 | prior_g = "-g"; | ||
| 243 | flags |= F_DEBUG_LINES; | ||
| 244 | flags |= F_DEBUG_VARS; | ||
| 245 | flags |= F_DEBUG_SOURCE; | ||
| 246 | } else if (argv[i].equals("-g:none")) { | ||
| 247 | if (prior_g!=null && !(prior_g.equals("-g:none"))) | ||
| 248 | error("main.conflicting.options", prior_g, "-g:none"); | ||
| 249 | prior_g = "-g:none"; | ||
| 250 | flags &= ~F_DEBUG_LINES; | ||
| 251 | flags &= ~F_DEBUG_VARS; | ||
| 252 | flags &= ~F_DEBUG_SOURCE; | ||
| 253 | } else if (argv[i].startsWith("-g:")) { | ||
| 254 | // We choose to have debugging options conflict even | ||
| 255 | // if they amount to the same thing (for example, | ||
| 256 | // -g:source,lines and -g:lines,source). However, multiple | ||
| 257 | // debugging options are allowed if they are textually | ||
| 258 | // identical. | ||
| 259 | if (prior_g!=null && !(prior_g.equals(argv[i]))) | ||
| 260 | error("main.conflicting.options", prior_g, argv[i]); | ||
| 261 | prior_g = argv[i]; | ||
| 262 | String args = argv[i].substring("-g:".length()); | ||
| 263 | flags &= ~F_DEBUG_LINES; | ||
| 264 | flags &= ~F_DEBUG_VARS; | ||
| 265 | flags &= ~F_DEBUG_SOURCE; | ||
| 266 | while (true) { | ||
| 267 | if (args.startsWith("lines")) { | ||
| 268 | flags |= F_DEBUG_LINES; | ||
| 269 | args = args.substring("lines".length()); | ||
| 270 | } else if (args.startsWith("vars")) { | ||
| 271 | flags |= F_DEBUG_VARS; | ||
| 272 | args = args.substring("vars".length()); | ||
| 273 | } else if (args.startsWith("source")) { | ||
| 274 | flags |= F_DEBUG_SOURCE; | ||
| 275 | args = args.substring("source".length()); | ||
| 276 | } else { | ||
| 277 | error("main.bad.debug.option",argv[i]); | ||
| 278 | usage_error(); | ||
| 279 | return false; // Stop processing now | ||
| 280 | } | ||
| 281 | if (args.length() == 0) break; | ||
| 282 | if (args.startsWith(",")) | ||
| 283 | args = args.substring(",".length()); | ||
| 284 | } | ||
| 285 | } else if (argv[i].equals("-O")) { | ||
| 286 | // -O is accepted for backward compatibility, but | ||
| 287 | // is no longer effective. Use the undocumented | ||
| 288 | // -XO option to get the old behavior. | ||
| 289 | if (prior_O!=null && !(prior_O.equals("-O"))) | ||
| 290 | error("main.conflicting.options", prior_O, "-O"); | ||
| 291 | prior_O = "-O"; | ||
| 292 | } else if (argv[i].equals("-nowarn")) { | ||
| 293 | flags &= ~F_WARNINGS; | ||
| 294 | } else if (argv[i].equals("-deprecation")) { | ||
| 295 | flags |= F_DEPRECATION; | ||
| 296 | } else if (argv[i].equals("-verbose")) { | ||
| 297 | flags |= F_VERBOSE; | ||
| 298 | } else if (argv[i].equals("-nowrite")) { | ||
| 299 | nowrite = true; | ||
| 300 | } else if (argv[i].equals("-classpath")) { | ||
| 301 | if ((i + 1) < argv.length) { | ||
| 302 | if (classPathArg!=null) { | ||
| 303 | error("main.option.already.seen","-classpath"); | ||
| 304 | } | ||
| 305 | classPathArg = argv[++i]; | ||
| 306 | } else { | ||
| 307 | error("main.option.requires.argument","-classpath"); | ||
| 308 | usage_error(); | ||
| 309 | return false; // Stop processing now | ||
| 310 | } | ||
| 311 | } else if (argv[i].equals("-sourcepath")) { | ||
| 312 | if ((i + 1) < argv.length) { | ||
| 313 | if (sourcePathArg != null) { | ||
| 314 | error("main.option.already.seen","-sourcepath"); | ||
| 315 | } | ||
| 316 | sourcePathArg = argv[++i]; | ||
| 317 | } else { | ||
| 318 | error("main.option.requires.argument","-sourcepath"); | ||
| 319 | usage_error(); | ||
| 320 | return false; // Stop processing now | ||
| 321 | } | ||
| 322 | } else if (argv[i].equals("-sysclasspath")) { | ||
| 323 | if ((i + 1) < argv.length) { | ||
| 324 | if (sysClassPathArg != null) { | ||
| 325 | error("main.option.already.seen","-sysclasspath"); | ||
| 326 | } | ||
| 327 | sysClassPathArg = argv[++i]; | ||
| 328 | } else { | ||
| 329 | error("main.option.requires.argument","-sysclasspath"); | ||
| 330 | usage_error(); | ||
| 331 | return false; // Stop processing now | ||
| 332 | } | ||
| 333 | } else if (argv[i].equals("-bootclasspath")) { | ||
| 334 | if ((i + 1) < argv.length) { | ||
| 335 | if (sysClassPathArg != null) { | ||
| 336 | error("main.option.already.seen","-bootclasspath"); | ||
| 337 | } | ||
| 338 | sysClassPathArg = argv[++i]; | ||
| 339 | } else { | ||
| 340 | error("main.option.requires.argument","-bootclasspath"); | ||
| 341 | usage_error(); | ||
| 342 | return false; // Stop processing now | ||
| 343 | } | ||
| 344 | } else if (argv[i].equals("-extdirs")) { | ||
| 345 | if ((i + 1) < argv.length) { | ||
| 346 | if (extDirsArg != null) { | ||
| 347 | error("main.option.already.seen","-extdirs"); | ||
| 348 | } | ||
| 349 | extDirsArg = argv[++i]; | ||
| 350 | } else { | ||
| 351 | error("main.option.requires.argument","-extdirs"); | ||
| 352 | usage_error(); | ||
| 353 | return false; // Stop processing now | ||
| 354 | } | ||
| 355 | } else if (argv[i].equals("-encoding")) { | ||
| 356 | if ((i + 1) < argv.length) { | ||
| 357 | if (encoding!=null) | ||
| 358 | error("main.option.already.seen","-encoding"); | ||
| 359 | encoding = argv[++i]; | ||
| 360 | } else { | ||
| 361 | error("main.option.requires.argument","-encoding"); | ||
| 362 | usage_error(); | ||
| 363 | return false; // Stop processing now | ||
| 364 | } | ||
| 365 | } else if (argv[i].equals("-target")) { | ||
| 366 | if ((i + 1) < argv.length) { | ||
| 367 | if (targetArg!=null) | ||
| 368 | error("main.option.already.seen","-target"); | ||
| 369 | targetArg = argv[++i]; | ||
| 370 | int j; | ||
| 371 | for (j=0; j<releases.length; j++) { | ||
| 372 | if (releases[j].equals(targetArg)) { | ||
| 373 | majorVersion = majorVersions[j]; | ||
| 374 | minorVersion = minorVersions[j]; | ||
| 375 | break; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | if (j==releases.length) { | ||
| 379 | error("main.unknown.release",targetArg); | ||
| 380 | usage_error(); | ||
| 381 | return false; // Stop processing now | ||
| 382 | } | ||
| 383 | } else { | ||
| 384 | error("main.option.requires.argument","-target"); | ||
| 385 | usage_error(); | ||
| 386 | return false; // Stop processing now | ||
| 387 | } | ||
| 388 | } else if (argv[i].equals("-d")) { | ||
| 389 | if ((i + 1) < argv.length) { | ||
| 390 | if (destDir!=null) | ||
| 391 | error("main.option.already.seen","-d"); | ||
| 392 | destDir = new File(argv[++i]); | ||
| 393 | if (!destDir.exists()) { | ||
| 394 | error("main.no.such.directory",destDir.getPath()); | ||
| 395 | usage_error(); | ||
| 396 | return false; // Stop processing now | ||
| 397 | } | ||
| 398 | } else { | ||
| 399 | error("main.option.requires.argument","-d"); | ||
| 400 | usage_error(); | ||
| 401 | return false; // Stop processing now | ||
| 402 | } | ||
| 403 | // JCOV | ||
| 404 | } else if (argv[i].equals(optJcov)) { | ||
| 405 | flags |= F_COVERAGE; | ||
| 406 | flags &= ~F_OPT; | ||
| 407 | flags &= ~F_OPT_INTERCLASS; | ||
| 408 | } else if ((argv[i].startsWith(optJcovFile)) && | ||
| 409 | (argv[i].length() > optJcovFile.length())) { | ||
| 410 | covFile = new File(argv[i].substring(optJcovFile.length())); | ||
| 411 | flags &= ~F_OPT; | ||
| 412 | flags &= ~F_OPT_INTERCLASS; | ||
| 413 | flags |= F_COVERAGE; | ||
| 414 | flags |= F_COVDATA; | ||
| 415 | // end JCOV | ||
| 416 | } else if (argv[i].equals("-XO")) { | ||
| 417 | // This is what -O used to be. Now undocumented. | ||
| 418 | if (prior_O!=null && !(prior_O.equals("-XO"))) | ||
| 419 | error("main.conflicting.options", prior_O, "-XO"); | ||
| 420 | prior_O = "-XO"; | ||
| 421 | flags |= F_OPT; | ||
| 422 | } else if (argv[i].equals("-Xinterclass")) { | ||
| 423 | if (prior_O!=null && !(prior_O.equals("-Xinterclass"))) | ||
| 424 | error("main.conflicting.options", prior_O, "-Xinterclass"); | ||
| 425 | prior_O = "-Xinterclass"; | ||
| 426 | flags |= F_OPT; | ||
| 427 | flags |= F_OPT_INTERCLASS; | ||
| 428 | flags |= F_DEPENDENCIES; | ||
| 429 | } else if (argv[i].equals("-Xdepend")) { | ||
| 430 | flags |= F_DEPENDENCIES; | ||
| 431 | } else if (argv[i].equals("-Xdebug")) { | ||
| 432 | flags |= F_DUMP; | ||
| 433 | // Unadvertised option used by JWS. The non-X version should | ||
| 434 | // be removed, but we'll leave it in until we find out for | ||
| 435 | // sure that no one still depends on that option syntax. | ||
| 436 | } else if (argv[i].equals("-xdepend") || argv[i].equals("-Xjws")) { | ||
| 437 | flags |= F_PRINT_DEPENDENCIES; | ||
| 438 | // change the default output in this case: | ||
| 439 | if (out == System.err) { | ||
| 440 | out = System.out; | ||
| 441 | } | ||
| 442 | } else if (argv[i].equals("-Xstrictdefault")) { | ||
| 443 | // Make strict floating point the default | ||
| 444 | flags |= F_STRICTDEFAULT; | ||
| 445 | } else if (argv[i].equals("-Xverbosepath")) { | ||
| 446 | verbosePath = true; | ||
| 447 | } else if (argv[i].equals("-Xstdout")) { | ||
| 448 | out = System.out; | ||
| 449 | } else if (argv[i].equals("-X")) { | ||
| 450 | error("main.unsupported.usage"); | ||
| 451 | return false; // Stop processing now | ||
| 452 | } else if (argv[i].equals("-Xversion1.2")) { | ||
| 453 | // Inform the compiler that it need not target VMs | ||
| 454 | // earlier than version 1.2. This option is here | ||
| 455 | // for testing purposes only. It is deliberately | ||
| 456 | // kept orthogonal to the -target option in 1.2.0 | ||
| 457 | // for the sake of stability. These options will | ||
| 458 | // be merged in a future release. | ||
| 459 | flags |= F_VERSION12; | ||
| 460 | } else if (argv[i].endsWith(".java")) { | ||
| 461 | v.addElement(argv[i]); | ||
| 462 | } else { | ||
| 463 | error("main.no.such.option",argv[i]); | ||
| 464 | usage_error(); | ||
| 465 | return false; // Stop processing now | ||
| 466 | } | ||
| 467 | } | ||
| 468 | if (v.size() == 0 || exitStatus == EXIT_CMDERR) { | ||
| 469 | usage_error(); | ||
| 470 | return false; | ||
| 471 | } | ||
| 472 | |||
| 473 | // Create our Environment. | ||
| 474 | BatchEnvironment env = BatchEnvironment.create(out, | ||
| 475 | sourcePathArg, | ||
| 476 | classPathArg, | ||
| 477 | sysClassPathArg, | ||
| 478 | extDirsArg); | ||
| 479 | if (verbosePath) { | ||
| 480 | output(getText("main.path.msg", | ||
| 481 | env.sourcePath.toString(), | ||
| 482 | env.binaryPath.toString())); | ||
| 483 | } | ||
| 484 | |||
| 485 | env.flags |= flags; | ||
| 486 | env.majorVersion = majorVersion; | ||
| 487 | env.minorVersion = minorVersion; | ||
| 488 | // JCOV | ||
| 489 | env.covFile = covFile; | ||
| 490 | // end JCOV | ||
| 491 | env.setCharacterEncoding(encoding); | ||
| 492 | |||
| 493 | // Preload the "out of memory" error string just in case we run | ||
| 494 | // out of memory during the compile. | ||
| 495 | String noMemoryErrorString = getText("main.no.memory"); | ||
| 496 | String stackOverflowErrorString = getText("main.stack.overflow"); | ||
| 497 | |||
| 498 | env.error(0, "warn.class.is.deprecated", "sun.tools.javac.Main"); | ||
| 499 | |||
| 500 | try { | ||
| 501 | // Parse all input files | ||
| 502 | for (Enumeration e = v.elements() ; e.hasMoreElements() ;) { | ||
| 503 | File file = new File((String)e.nextElement()); | ||
| 504 | try { | ||
| 505 | env.parseFile(new ClassFile(file)); | ||
| 506 | } catch (FileNotFoundException ee) { | ||
| 507 | env.error(0, "cant.read", file.getPath()); | ||
| 508 | exitStatus = EXIT_CMDERR; | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | // Do a post-read check on all newly-parsed classes, | ||
| 513 | // after they have all been read. | ||
| 514 | for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) { | ||
| 515 | ClassDeclaration c = (ClassDeclaration)e.nextElement(); | ||
| 516 | if (c.getStatus() == CS_PARSED) { | ||
| 517 | if (c.getClassDefinition().isLocal()) | ||
| 518 | continue; | ||
| 519 | try { | ||
| 520 | c.getClassDefinition(env); | ||
| 521 | } catch (ClassNotFound ee) { | ||
| 522 | } | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 526 | // compile all classes that need compilation | ||
| 527 | ByteArrayOutputStream buf = new ByteArrayOutputStream(4096); | ||
| 528 | boolean done; | ||
| 529 | |||
| 530 | do { | ||
| 531 | done = true; | ||
| 532 | env.flushErrors(); | ||
| 533 | for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) { | ||
| 534 | ClassDeclaration c = (ClassDeclaration)e.nextElement(); | ||
| 535 | SourceClass src; | ||
| 536 | |||
| 537 | switch (c.getStatus()) { | ||
| 538 | case CS_UNDEFINED: | ||
| 539 | if (!env.dependencies()) { | ||
| 540 | break; | ||
| 541 | } | ||
| 542 | // fall through | ||
| 543 | |||
| 544 | case CS_SOURCE: | ||
| 545 | if (tracing) | ||
| 546 | env.dtEvent("Main.compile (SOURCE): loading, " + c); | ||
| 547 | done = false; | ||
| 548 | env.loadDefinition(c); | ||
| 549 | if (c.getStatus() != CS_PARSED) { | ||
| 550 | if (tracing) | ||
| 551 | env.dtEvent("Main.compile (SOURCE): not parsed, " + c); | ||
| 552 | break; | ||
| 553 | } | ||
| 554 | // fall through | ||
| 555 | |||
| 556 | case CS_PARSED: | ||
| 557 | if (c.getClassDefinition().isInsideLocal()) { | ||
| 558 | // the enclosing block will check this one | ||
| 559 | if (tracing) | ||
| 560 | env.dtEvent("Main.compile (PARSED): skipping local class, " + c); | ||
| 561 | continue; | ||
| 562 | } | ||
| 563 | done = false; | ||
| 564 | if (tracing) env.dtEvent("Main.compile (PARSED): checking, " + c); | ||
| 565 | src = (SourceClass)c.getClassDefinition(env); | ||
| 566 | src.check(env); | ||
| 567 | c.setDefinition(src, CS_CHECKED); | ||
| 568 | // fall through | ||
| 569 | |||
| 570 | case CS_CHECKED: | ||
| 571 | src = (SourceClass)c.getClassDefinition(env); | ||
| 572 | // bail out if there were any errors | ||
| 573 | if (src.getError()) { | ||
| 574 | if (tracing) | ||
| 575 | env.dtEvent("Main.compile (CHECKED): bailing out on error, " + c); | ||
| 576 | c.setDefinition(src, CS_COMPILED); | ||
| 577 | break; | ||
| 578 | } | ||
| 579 | done = false; | ||
| 580 | buf.reset(); | ||
| 581 | if (tracing) | ||
| 582 | env.dtEvent("Main.compile (CHECKED): compiling, " + c); | ||
| 583 | src.compile(buf); | ||
| 584 | c.setDefinition(src, CS_COMPILED); | ||
| 585 | src.cleanup(env); | ||
| 586 | |||
| 587 | if (src.getNestError() || nowrite) { | ||
| 588 | continue; | ||
| 589 | } | ||
| 590 | |||
| 591 | String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar); | ||
| 592 | String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class"; | ||
| 593 | |||
| 594 | File file; | ||
| 595 | if (destDir != null) { | ||
| 596 | if (pkgName.length() > 0) { | ||
| 597 | file = new File(destDir, pkgName); | ||
| 598 | if (!file.exists()) { | ||
| 599 | file.mkdirs(); | ||
| 600 | } | ||
| 601 | file = new File(file, className); | ||
| 602 | } else { | ||
| 603 | file = new File(destDir, className); | ||
| 604 | } | ||
| 605 | } else { | ||
| 606 | ClassFile classfile = (ClassFile)src.getSource(); | ||
| 607 | if (classfile.isZipped()) { | ||
| 608 | env.error(0, "cant.write", classfile.getPath()); | ||
| 609 | exitStatus = EXIT_CMDERR; | ||
| 610 | continue; | ||
| 611 | } | ||
| 612 | file = new File(classfile.getPath()); | ||
| 613 | file = new File(file.getParent(), className); | ||
| 614 | } | ||
| 615 | |||
| 616 | // Create the file | ||
| 617 | try { | ||
| 618 | FileOutputStream out = new FileOutputStream(file.getPath()); | ||
| 619 | buf.writeTo(out); | ||
| 620 | out.close(); | ||
| 621 | |||
| 622 | if (env.verbose()) { | ||
| 623 | output(getText("main.wrote", file.getPath())); | ||
| 624 | } | ||
| 625 | } catch (IOException ee) { | ||
| 626 | env.error(0, "cant.write", file.getPath()); | ||
| 627 | exitStatus = EXIT_CMDERR; | ||
| 628 | } | ||
| 629 | |||
| 630 | // Print class dependencies if requested (-xdepend) | ||
| 631 | if (env.print_dependencies()) { | ||
| 632 | src.printClassDependencies(env); | ||
| 633 | } | ||
| 634 | } | ||
| 635 | } | ||
| 636 | } while (!done); | ||
| 637 | } catch (OutOfMemoryError ee) { | ||
| 638 | // The compiler has run out of memory. Use the error string | ||
| 639 | // which we preloaded. | ||
| 640 | env.output(noMemoryErrorString); | ||
| 641 | exitStatus = EXIT_SYSERR; | ||
| 642 | return false; | ||
| 643 | } catch (StackOverflowError ee) { | ||
| 644 | env.output(stackOverflowErrorString); | ||
| 645 | exitStatus = EXIT_SYSERR; | ||
| 646 | return false; | ||
| 647 | } catch (Error ee) { | ||
| 648 | // We allow the compiler to take an exception silently if a program | ||
| 649 | // error has previously been detected. Presumably, this makes the | ||
| 650 | // compiler more robust in the face of bad error recovery. | ||
| 651 | if (env.nerrors == 0 || env.dump()) { | ||
| 652 | ee.printStackTrace(); | ||
| 653 | env.error(0, "fatal.error"); | ||
| 654 | exitStatus = EXIT_ABNORMAL; | ||
| 655 | } | ||
| 656 | } catch (Exception ee) { | ||
| 657 | if (env.nerrors == 0 || env.dump()) { | ||
| 658 | ee.printStackTrace(); | ||
| 659 | env.error(0, "fatal.exception"); | ||
| 660 | exitStatus = EXIT_ABNORMAL; | ||
| 661 | } | ||
| 662 | } | ||
| 663 | |||
| 664 | int ndepfiles = env.deprecationFiles.size(); | ||
| 665 | if (ndepfiles > 0 && env.warnings()) { | ||
| 666 | int ndeps = env.ndeprecations; | ||
| 667 | Object file1 = env.deprecationFiles.elementAt(0); | ||
| 668 | if (env.deprecation()) { | ||
| 669 | if (ndepfiles > 1) { | ||
| 670 | env.error(0, "warn.note.deprecations", | ||
| 671 | new Integer(ndepfiles), new Integer(ndeps)); | ||
| 672 | } else { | ||
| 673 | env.error(0, "warn.note.1deprecation", | ||
| 674 | file1, new Integer(ndeps)); | ||
| 675 | } | ||
| 676 | } else { | ||
| 677 | if (ndepfiles > 1) { | ||
| 678 | env.error(0, "warn.note.deprecations.silent", | ||
| 679 | new Integer(ndepfiles), new Integer(ndeps)); | ||
| 680 | } else { | ||
| 681 | env.error(0, "warn.note.1deprecation.silent", | ||
| 682 | file1, new Integer(ndeps)); | ||
| 683 | } | ||
| 684 | } | ||
| 685 | } | ||
| 686 | |||
| 687 | env.flushErrors(); | ||
| 688 | env.shutdown(); | ||
| 689 | |||
| 690 | boolean status = true; | ||
| 691 | if (env.nerrors > 0) { | ||
| 692 | String msg = ""; | ||
| 693 | if (env.nerrors > 1) { | ||
| 694 | msg = getText("main.errors", env.nerrors); | ||
| 695 | } else { | ||
| 696 | msg = getText("main.1error"); | ||
| 697 | } | ||
| 698 | if (env.nwarnings > 0) { | ||
| 699 | if (env.nwarnings > 1) { | ||
| 700 | msg += ", " + getText("main.warnings", env.nwarnings); | ||
| 701 | } else { | ||
| 702 | msg += ", " + getText("main.1warning"); | ||
| 703 | } | ||
| 704 | } | ||
| 705 | output(msg); | ||
| 706 | if (exitStatus == EXIT_OK) { | ||
| 707 | // Allow EXIT_CMDERR or EXIT_ABNORMAL to take precedence. | ||
| 708 | exitStatus = EXIT_ERROR; | ||
| 709 | } | ||
| 710 | status = false; | ||
| 711 | } else { | ||
| 712 | if (env.nwarnings > 0) { | ||
| 713 | if (env.nwarnings > 1) { | ||
| 714 | output(getText("main.warnings", env.nwarnings)); | ||
| 715 | } else { | ||
| 716 | output(getText("main.1warning")); | ||
| 717 | } | ||
| 718 | } | ||
| 719 | } | ||
| 720 | //JCOV | ||
| 721 | if (env.covdata()) { | ||
| 722 | Assembler CovAsm = new Assembler(); | ||
| 723 | CovAsm.GenJCov(env); | ||
| 724 | } | ||
| 725 | // end JCOV | ||
| 726 | |||
| 727 | // We're done | ||
| 728 | if (env.verbose()) { | ||
| 729 | tm = System.currentTimeMillis() - tm; | ||
| 730 | output(getText("main.done_in", Long.toString(tm))); | ||
| 731 | } | ||
| 732 | |||
| 733 | return status; | ||
| 734 | } | ||
| 735 | |||
| 736 | /** | ||
| 737 | * Main program | ||
| 738 | */ | ||
| 739 | public static void main(String argv[]) { | ||
| 740 | OutputStream out = System.err; | ||
| 741 | |||
| 742 | // This is superceeded by the -Xstdout option, but we leave | ||
| 743 | // in the old property check for compatibility. | ||
| 744 | if (Boolean.getBoolean("javac.pipe.output")) { | ||
| 745 | out = System.out; | ||
| 746 | } | ||
| 747 | |||
| 748 | Main compiler = new Main(out, "javac"); | ||
| 749 | System.exit(compiler.compile(argv) ? 0 : compiler.exitStatus); | ||
| 750 | } | ||
| 751 | } | ||