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 @SuppressWarnings("fallthrough") 196 public synchronized boolean compile(String argv[]) { 197 String sourcePathArg = null; 198 String classPathArg = null; 199 String sysClassPathArg = null; 200 String extDirsArg = null; 201 boolean verbosePath = false; 202 203 String targetArg = null; 204 short majorVersion = JAVA_DEFAULT_VERSION; 205 short minorVersion = JAVA_DEFAULT_MINOR_VERSION; 206 207 File destDir = null; 208 //JCOV 209 File covFile = null; 210 String optJcov = "-Xjcov"; 211 String optJcovFile = "-Xjcov:file="; 212 //end JCOV 213 int flags = F_WARNINGS | F_DEBUG_LINES | F_DEBUG_SOURCE; 214 long tm = System.currentTimeMillis(); 215 Vector<String> v = new Vector<>(); 216 boolean nowrite = false; 217 String props = null; 218 String encoding = null; 219 220 // These flags are used to make sure conflicting -O and -g 221 // options aren't given. 222 String prior_g = null; 223 String prior_O = null; 224 225 exitStatus = EXIT_OK; 226 227 // Pre-process command line for @file arguments 228 try { 229 argv = CommandLine.parse(argv); 230 } catch (FileNotFoundException e) { 231 error("javac.err.cant.read", e.getMessage()); 232 System.exit(1); 233 } catch (IOException e) { 234 e.printStackTrace(); 235 System.exit(1); 236 } 237 238 // Parse arguments 239 for (int i = 0 ; i < argv.length ; i++) { 240 if (argv[i].equals("-g")) { 241 if (prior_g!=null && !(prior_g.equals("-g"))) 242 error("main.conflicting.options", prior_g, "-g"); 243 prior_g = "-g"; 244 flags |= F_DEBUG_LINES; 245 flags |= F_DEBUG_VARS; 246 flags |= F_DEBUG_SOURCE; 247 } else if (argv[i].equals("-g:none")) { 248 if (prior_g!=null && !(prior_g.equals("-g:none"))) 249 error("main.conflicting.options", prior_g, "-g:none"); 250 prior_g = "-g:none"; 251 flags &= ~F_DEBUG_LINES; 252 flags &= ~F_DEBUG_VARS; 253 flags &= ~F_DEBUG_SOURCE; 254 } else if (argv[i].startsWith("-g:")) { 255 // We choose to have debugging options conflict even 256 // if they amount to the same thing (for example, 257 // -g:source,lines and -g:lines,source). However, multiple 258 // debugging options are allowed if they are textually 259 // identical. 260 if (prior_g!=null && !(prior_g.equals(argv[i]))) 261 error("main.conflicting.options", prior_g, argv[i]); 262 prior_g = argv[i]; 263 String args = argv[i].substring("-g:".length()); 264 flags &= ~F_DEBUG_LINES; 265 flags &= ~F_DEBUG_VARS; 266 flags &= ~F_DEBUG_SOURCE; 267 while (true) { 268 if (args.startsWith("lines")) { 269 flags |= F_DEBUG_LINES; 270 args = args.substring("lines".length()); 271 } else if (args.startsWith("vars")) { 272 flags |= F_DEBUG_VARS; 273 args = args.substring("vars".length()); 274 } else if (args.startsWith("source")) { 275 flags |= F_DEBUG_SOURCE; 276 args = args.substring("source".length()); 277 } else { 278 error("main.bad.debug.option",argv[i]); 279 usage_error(); 280 return false; // Stop processing now 281 } 282 if (args.length() == 0) break; 283 if (args.startsWith(",")) 284 args = args.substring(",".length()); 285 } 286 } else if (argv[i].equals("-O")) { 287 // -O is accepted for backward compatibility, but 288 // is no longer effective. Use the undocumented 289 // -XO option to get the old behavior. 290 if (prior_O!=null && !(prior_O.equals("-O"))) 291 error("main.conflicting.options", prior_O, "-O"); 292 prior_O = "-O"; 293 } else if (argv[i].equals("-nowarn")) { 294 flags &= ~F_WARNINGS; 295 } else if (argv[i].equals("-deprecation")) { 296 flags |= F_DEPRECATION; 297 } else if (argv[i].equals("-verbose")) { 298 flags |= F_VERBOSE; 299 } else if (argv[i].equals("-nowrite")) { 300 nowrite = true; 301 } else if (argv[i].equals("-classpath")) { 302 if ((i + 1) < argv.length) { 303 if (classPathArg!=null) { 304 error("main.option.already.seen","-classpath"); 305 } 306 classPathArg = argv[++i]; 307 } else { 308 error("main.option.requires.argument","-classpath"); 309 usage_error(); 310 return false; // Stop processing now 311 } 312 } else if (argv[i].equals("-sourcepath")) { 313 if ((i + 1) < argv.length) { 314 if (sourcePathArg != null) { 315 error("main.option.already.seen","-sourcepath"); 316 } 317 sourcePathArg = argv[++i]; 318 } else { 319 error("main.option.requires.argument","-sourcepath"); 320 usage_error(); 321 return false; // Stop processing now 322 } 323 } else if (argv[i].equals("-sysclasspath")) { 324 if ((i + 1) < argv.length) { 325 if (sysClassPathArg != null) { 326 error("main.option.already.seen","-sysclasspath"); 327 } 328 sysClassPathArg = argv[++i]; 329 } else { 330 error("main.option.requires.argument","-sysclasspath"); 331 usage_error(); 332 return false; // Stop processing now 333 } 334 } else if (argv[i].equals("-bootclasspath")) { 335 if ((i + 1) < argv.length) { 336 if (sysClassPathArg != null) { 337 error("main.option.already.seen","-bootclasspath"); 338 } 339 sysClassPathArg = argv[++i]; 340 } else { 341 error("main.option.requires.argument","-bootclasspath"); 342 usage_error(); 343 return false; // Stop processing now 344 } 345 } else if (argv[i].equals("-extdirs")) { 346 if ((i + 1) < argv.length) { 347 if (extDirsArg != null) { 348 error("main.option.already.seen","-extdirs"); 349 } 350 extDirsArg = argv[++i]; 351 } else { 352 error("main.option.requires.argument","-extdirs"); 353 usage_error(); 354 return false; // Stop processing now 355 } 356 } else if (argv[i].equals("-encoding")) { 357 if ((i + 1) < argv.length) { 358 if (encoding!=null) 359 error("main.option.already.seen","-encoding"); 360 encoding = argv[++i]; 361 } else { 362 error("main.option.requires.argument","-encoding"); 363 usage_error(); 364 return false; // Stop processing now 365 } 366 } else if (argv[i].equals("-target")) { 367 if ((i + 1) < argv.length) { 368 if (targetArg!=null) 369 error("main.option.already.seen","-target"); 370 targetArg = argv[++i]; 371 int j; 372 for (j=0; j<releases.length; j++) { 373 if (releases[j].equals(targetArg)) { 374 majorVersion = majorVersions[j]; 375 minorVersion = minorVersions[j]; 376 break; 377 } 378 } 379 if (j==releases.length) { 380 error("main.unknown.release",targetArg); 381 usage_error(); 382 return false; // Stop processing now 383 } 384 } else { 385 error("main.option.requires.argument","-target"); 386 usage_error(); 387 return false; // Stop processing now 388 } 389 } else if (argv[i].equals("-d")) { 390 if ((i + 1) < argv.length) { 391 if (destDir!=null) 392 error("main.option.already.seen","-d"); 393 destDir = new File(argv[++i]); 394 if (!destDir.exists()) { 395 error("main.no.such.directory",destDir.getPath()); 396 usage_error(); 397 return false; // Stop processing now 398 } 399 } else { 400 error("main.option.requires.argument","-d"); 401 usage_error(); 402 return false; // Stop processing now 403 } 404 // JCOV 405 } else if (argv[i].equals(optJcov)) { 406 flags |= F_COVERAGE; 407 flags &= ~F_OPT; 408 flags &= ~F_OPT_INTERCLASS; 409 } else if ((argv[i].startsWith(optJcovFile)) && 410 (argv[i].length() > optJcovFile.length())) { 411 covFile = new File(argv[i].substring(optJcovFile.length())); 412 flags &= ~F_OPT; 413 flags &= ~F_OPT_INTERCLASS; 414 flags |= F_COVERAGE; 415 flags |= F_COVDATA; 416 // end JCOV 417 } else if (argv[i].equals("-XO")) { 418 // This is what -O used to be. Now undocumented. 419 if (prior_O!=null && !(prior_O.equals("-XO"))) 420 error("main.conflicting.options", prior_O, "-XO"); 421 prior_O = "-XO"; 422 flags |= F_OPT; 423 } else if (argv[i].equals("-Xinterclass")) { 424 if (prior_O!=null && !(prior_O.equals("-Xinterclass"))) 425 error("main.conflicting.options", prior_O, "-Xinterclass"); 426 prior_O = "-Xinterclass"; 427 flags |= F_OPT; 428 flags |= F_OPT_INTERCLASS; 429 flags |= F_DEPENDENCIES; 430 } else if (argv[i].equals("-Xdepend")) { 431 flags |= F_DEPENDENCIES; 432 } else if (argv[i].equals("-Xdebug")) { 433 flags |= F_DUMP; 434 // Unadvertised option used by JWS. The non-X version should 435 // be removed, but we'll leave it in until we find out for 436 // sure that no one still depends on that option syntax. 437 } else if (argv[i].equals("-xdepend") || argv[i].equals("-Xjws")) { 438 flags |= F_PRINT_DEPENDENCIES; 439 // change the default output in this case: 440 if (out == System.err) { 441 out = System.out; 442 } 443 } else if (argv[i].equals("-Xstrictdefault")) { 444 // Make strict floating point the default 445 flags |= F_STRICTDEFAULT; 446 } else if (argv[i].equals("-Xverbosepath")) { 447 verbosePath = true; 448 } else if (argv[i].equals("-Xstdout")) { 449 out = System.out; 450 } else if (argv[i].equals("-X")) { 451 error("main.unsupported.usage"); 452 return false; // Stop processing now 453 } else if (argv[i].equals("-Xversion1.2")) { 454 // Inform the compiler that it need not target VMs 455 // earlier than version 1.2. This option is here 456 // for testing purposes only. It is deliberately 457 // kept orthogonal to the -target option in 1.2.0 458 // for the sake of stability. These options will 459 // be merged in a future release. 460 flags |= F_VERSION12; 461 } else if (argv[i].endsWith(".java")) { 462 v.addElement(argv[i]); 463 } else { 464 error("main.no.such.option",argv[i]); 465 usage_error(); 466 return false; // Stop processing now 467 } 468 } 469 if (v.size() == 0 || exitStatus == EXIT_CMDERR) { 470 usage_error(); 471 return false; 472 } 473 474 // Create our Environment. 475 BatchEnvironment env = BatchEnvironment.create(out, 476 sourcePathArg, 477 classPathArg, 478 sysClassPathArg, 479 extDirsArg); 480 if (verbosePath) { 481 output(getText("main.path.msg", 482 env.sourcePath.toString(), 483 env.binaryPath.toString())); 484 } 485 486 env.flags |= flags; 487 env.majorVersion = majorVersion; 488 env.minorVersion = minorVersion; 489 // JCOV 490 env.covFile = covFile; 491 // end JCOV 492 env.setCharacterEncoding(encoding); 493 494 // Preload the "out of memory" error string just in case we run 495 // out of memory during the compile. 496 String noMemoryErrorString = getText("main.no.memory"); 497 String stackOverflowErrorString = getText("main.stack.overflow"); 498 499 env.error(0, "warn.class.is.deprecated", "sun.tools.javac.Main"); 500 501 try { 502 // Parse all input files 503 for (Enumeration<String> e = v.elements() ; e.hasMoreElements() ;) { 504 File file = new File(e.nextElement()); 505 try { 506 env.parseFile(new ClassFile(file)); 507 } catch (FileNotFoundException ee) { 508 env.error(0, "cant.read", file.getPath()); 509 exitStatus = EXIT_CMDERR; 510 } 511 } 512 513 // Do a post-read check on all newly-parsed classes, 514 // after they have all been read. 515 for (Enumeration<ClassDeclaration> e = env.getClasses() ; e.hasMoreElements() ; ) { 516 ClassDeclaration c = e.nextElement(); 517 if (c.getStatus() == CS_PARSED) { 518 if (c.getClassDefinition().isLocal()) 519 continue; 520 try { 521 c.getClassDefinition(env); 522 } catch (ClassNotFound ee) { 523 } 524 } 525 } 526 527 // compile all classes that need compilation 528 ByteArrayOutputStream buf = new ByteArrayOutputStream(4096); 529 boolean done; 530 531 do { 532 done = true; 533 env.flushErrors(); 534 for (Enumeration<ClassDeclaration> e = env.getClasses() ; e.hasMoreElements() ; ) { 535 ClassDeclaration c = e.nextElement(); 536 SourceClass src; 537 538 switch (c.getStatus()) { 539 case CS_UNDEFINED: 540 if (!env.dependencies()) { 541 break; 542 } 543 // fall through 544 545 case CS_SOURCE: 546 if (tracing) 547 env.dtEvent("Main.compile (SOURCE): loading, " + c); 548 done = false; 549 env.loadDefinition(c); 550 if (c.getStatus() != CS_PARSED) { 551 if (tracing) 552 env.dtEvent("Main.compile (SOURCE): not parsed, " + c); 553 break; 554 } 555 // fall through 556 557 case CS_PARSED: 558 if (c.getClassDefinition().isInsideLocal()) { 559 // the enclosing block will check this one 560 if (tracing) 561 env.dtEvent("Main.compile (PARSED): skipping local class, " + c); 562 continue; 563 } 564 done = false; 565 if (tracing) env.dtEvent("Main.compile (PARSED): checking, " + c); 566 src = (SourceClass)c.getClassDefinition(env); 567 src.check(env); 568 c.setDefinition(src, CS_CHECKED); 569 // fall through 570 571 case CS_CHECKED: 572 src = (SourceClass)c.getClassDefinition(env); 573 // bail out if there were any errors 574 if (src.getError()) { 575 if (tracing) 576 env.dtEvent("Main.compile (CHECKED): bailing out on error, " + c); 577 c.setDefinition(src, CS_COMPILED); 578 break; 579 } 580 done = false; 581 buf.reset(); 582 if (tracing) 583 env.dtEvent("Main.compile (CHECKED): compiling, " + c); 584 src.compile(buf); 585 c.setDefinition(src, CS_COMPILED); 586 src.cleanup(env); 587 588 if (src.getNestError() || nowrite) { 589 continue; 590 } 591 592 String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar); 593 String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class"; 594 595 File file; 596 if (destDir != null) { 597 if (pkgName.length() > 0) { 598 file = new File(destDir, pkgName); 599 if (!file.exists()) { 600 file.mkdirs(); 601 } 602 file = new File(file, className); 603 } else { 604 file = new File(destDir, className); 605 } 606 } else { 607 ClassFile classfile = (ClassFile)src.getSource(); 608 if (classfile.isZipped()) { 609 env.error(0, "cant.write", classfile.getPath()); 610 exitStatus = EXIT_CMDERR; 611 continue; 612 } 613 file = new File(classfile.getPath()); 614 file = new File(file.getParent(), className); 615 } 616 617 // Create the file 618 try { 619 FileOutputStream out = new FileOutputStream(file.getPath()); 620 buf.writeTo(out); 621 out.close(); 622 623 if (env.verbose()) { 624 output(getText("main.wrote", file.getPath())); 625 } 626 } catch (IOException ee) { 627 env.error(0, "cant.write", file.getPath()); 628 exitStatus = EXIT_CMDERR; 629 } 630 631 // Print class dependencies if requested (-xdepend) 632 if (env.print_dependencies()) { 633 src.printClassDependencies(env); 634 } 635 } 636 } 637 } while (!done); 638 } catch (OutOfMemoryError ee) { 639 // The compiler has run out of memory. Use the error string 640 // which we preloaded. 641 env.output(noMemoryErrorString); 642 exitStatus = EXIT_SYSERR; 643 return false; 644 } catch (StackOverflowError ee) { 645 env.output(stackOverflowErrorString); 646 exitStatus = EXIT_SYSERR; 647 return false; 648 } catch (Error ee) { 649 // We allow the compiler to take an exception silently if a program 650 // error has previously been detected. Presumably, this makes the 651 // compiler more robust in the face of bad error recovery. 652 if (env.nerrors == 0 || env.dump()) { 653 ee.printStackTrace(); 654 env.error(0, "fatal.error"); 655 exitStatus = EXIT_ABNORMAL; 656 } 657 } catch (Exception ee) { 658 if (env.nerrors == 0 || env.dump()) { 659 ee.printStackTrace(); 660 env.error(0, "fatal.exception"); 661 exitStatus = EXIT_ABNORMAL; 662 } 663 } 664 665 int ndepfiles = env.deprecationFiles.size(); 666 if (ndepfiles > 0 && env.warnings()) { 667 int ndeps = env.ndeprecations; 668 Object file1 = env.deprecationFiles.elementAt(0); 669 if (env.deprecation()) { 670 if (ndepfiles > 1) { 671 env.error(0, "warn.note.deprecations", 672 ndepfiles, ndeps); 673 } else { 674 env.error(0, "warn.note.1deprecation", 675 file1, ndeps); 676 } 677 } else { 678 if (ndepfiles > 1) { 679 env.error(0, "warn.note.deprecations.silent", 680 ndepfiles, ndeps); 681 } else { 682 env.error(0, "warn.note.1deprecation.silent", 683 file1, ndeps); 684 } 685 } 686 } 687 688 env.flushErrors(); 689 env.shutdown(); 690 691 boolean status = true; 692 if (env.nerrors > 0) { 693 String msg = ""; 694 if (env.nerrors > 1) { 695 msg = getText("main.errors", env.nerrors); 696 } else { 697 msg = getText("main.1error"); 698 } 699 if (env.nwarnings > 0) { 700 if (env.nwarnings > 1) { 701 msg += ", " + getText("main.warnings", env.nwarnings); 702 } else { 703 msg += ", " + getText("main.1warning"); 704 } 705 } 706 output(msg); 707 if (exitStatus == EXIT_OK) { 708 // Allow EXIT_CMDERR or EXIT_ABNORMAL to take precedence. 709 exitStatus = EXIT_ERROR; 710 } 711 status = false; 712 } else { 713 if (env.nwarnings > 0) { 714 if (env.nwarnings > 1) { 715 output(getText("main.warnings", env.nwarnings)); 716 } else { 717 output(getText("main.1warning")); 718 } 719 } 720 } 721 //JCOV 722 if (env.covdata()) { 723 Assembler CovAsm = new Assembler(); 724 CovAsm.GenJCov(env); 725 } 726 // end JCOV 727 728 // We're done 729 if (env.verbose()) { 730 tm = System.currentTimeMillis() - tm; 731 output(getText("main.done_in", Long.toString(tm))); 732 } 733 734 return status; 735 } 736 737 /** 738 * Main program 739 */ 740 public static void main(String argv[]) { 741 OutputStream out = System.err; 742 743 // This is superceeded by the -Xstdout option, but we leave 744 // in the old property check for compatibility. 745 if (Boolean.getBoolean("javac.pipe.output")) { 746 out = System.out; 747 } 748 749 Main compiler = new Main(out, "javac"); 750 System.exit(compiler.compile(argv) ? 0 : compiler.exitStatus); 751 } 752 }