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 }