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 */ Main(OutputStream out, String program)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 getExitStatus()85 public int getExitStatus() { 86 return exitStatus; 87 } 88 compilationPerformedSuccessfully()89 public boolean compilationPerformedSuccessfully() { 90 return exitStatus == EXIT_OK || exitStatus == EXIT_ERROR; 91 } 92 compilationReportedErrors()93 public boolean compilationReportedErrors () { 94 return exitStatus != EXIT_OK; 95 } 96 97 /** 98 * Output a message. 99 */ output(String msg)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 */ error(String msg)111 private void error(String msg) { 112 exitStatus = EXIT_CMDERR; 113 output(getText(msg)); 114 } 115 error(String msg, String arg1)116 private void error(String msg, String arg1) { 117 exitStatus = EXIT_CMDERR; 118 output(getText(msg, arg1)); 119 } 120 error(String msg, String arg1, String arg2)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 */ usage_error()131 public void usage_error() { 132 error("main.usage", program); 133 } 134 135 private static ResourceBundle messageRB; 136 137 /** 138 * Initialize ResourceBundle 139 */ initResource()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 */ getText(String key)152 public static String getText(String key) { 153 return getText(key, (String)null); 154 } 155 getText(String key, int num)156 public static String getText(String key, int num) { 157 return getText(key, Integer.toString(num)); 158 } 159 getText(String key, String fixed)160 public static String getText(String key, String fixed) { 161 return getText(key, fixed, null); 162 } 163 getText(String key, String fixed1, String fixed2)164 public static String getText(String key, String fixed1, String fixed2) { 165 return getText(key, fixed1, fixed2, null); 166 } 167 getText(String key, String fixed1, String fixed2, String fixed3)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") compile(String argv[])196 public synchronized boolean compile(String argv[]) { 197 String sourcePathArg = null; 198 String classPathArg = null; 199 String sysClassPathArg = 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<String> 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("-encoding")) { 345 if ((i + 1) < argv.length) { 346 if (encoding!=null) 347 error("main.option.already.seen","-encoding"); 348 encoding = argv[++i]; 349 } else { 350 error("main.option.requires.argument","-encoding"); 351 usage_error(); 352 return false; // Stop processing now 353 } 354 } else if (argv[i].equals("-target")) { 355 if ((i + 1) < argv.length) { 356 if (targetArg!=null) 357 error("main.option.already.seen","-target"); 358 targetArg = argv[++i]; 359 int j; 360 for (j=0; j<releases.length; j++) { 361 if (releases[j].equals(targetArg)) { 362 majorVersion = majorVersions[j]; 363 minorVersion = minorVersions[j]; 364 break; 365 } 366 } 367 if (j==releases.length) { 368 error("main.unknown.release",targetArg); 369 usage_error(); 370 return false; // Stop processing now 371 } 372 } else { 373 error("main.option.requires.argument","-target"); 374 usage_error(); 375 return false; // Stop processing now 376 } 377 } else if (argv[i].equals("-d")) { 378 if ((i + 1) < argv.length) { 379 if (destDir!=null) 380 error("main.option.already.seen","-d"); 381 destDir = new File(argv[++i]); 382 if (!destDir.exists()) { 383 error("main.no.such.directory",destDir.getPath()); 384 usage_error(); 385 return false; // Stop processing now 386 } 387 } else { 388 error("main.option.requires.argument","-d"); 389 usage_error(); 390 return false; // Stop processing now 391 } 392 // JCOV 393 } else if (argv[i].equals(optJcov)) { 394 flags |= F_COVERAGE; 395 flags &= ~F_OPT; 396 flags &= ~F_OPT_INTERCLASS; 397 } else if ((argv[i].startsWith(optJcovFile)) && 398 (argv[i].length() > optJcovFile.length())) { 399 covFile = new File(argv[i].substring(optJcovFile.length())); 400 flags &= ~F_OPT; 401 flags &= ~F_OPT_INTERCLASS; 402 flags |= F_COVERAGE; 403 flags |= F_COVDATA; 404 // end JCOV 405 } else if (argv[i].equals("-XO")) { 406 // This is what -O used to be. Now undocumented. 407 if (prior_O!=null && !(prior_O.equals("-XO"))) 408 error("main.conflicting.options", prior_O, "-XO"); 409 prior_O = "-XO"; 410 flags |= F_OPT; 411 } else if (argv[i].equals("-Xinterclass")) { 412 if (prior_O!=null && !(prior_O.equals("-Xinterclass"))) 413 error("main.conflicting.options", prior_O, "-Xinterclass"); 414 prior_O = "-Xinterclass"; 415 flags |= F_OPT; 416 flags |= F_OPT_INTERCLASS; 417 flags |= F_DEPENDENCIES; 418 } else if (argv[i].equals("-Xdepend")) { 419 flags |= F_DEPENDENCIES; 420 } else if (argv[i].equals("-Xdebug")) { 421 flags |= F_DUMP; 422 // Unadvertised option used by JWS. The non-X version should 423 // be removed, but we'll leave it in until we find out for 424 // sure that no one still depends on that option syntax. 425 } else if (argv[i].equals("-xdepend") || argv[i].equals("-Xjws")) { 426 flags |= F_PRINT_DEPENDENCIES; 427 // change the default output in this case: 428 if (out == System.err) { 429 out = System.out; 430 } 431 } else if (argv[i].equals("-Xstrictdefault")) { 432 // Make strict floating point the default 433 flags |= F_STRICTDEFAULT; 434 } else if (argv[i].equals("-Xverbosepath")) { 435 verbosePath = true; 436 } else if (argv[i].equals("-Xstdout")) { 437 out = System.out; 438 } else if (argv[i].equals("-X")) { 439 error("main.unsupported.usage"); 440 return false; // Stop processing now 441 } else if (argv[i].equals("-Xversion1.2")) { 442 // Inform the compiler that it need not target VMs 443 // earlier than version 1.2. This option is here 444 // for testing purposes only. It is deliberately 445 // kept orthogonal to the -target option in 1.2.0 446 // for the sake of stability. These options will 447 // be merged in a future release. 448 flags |= F_VERSION12; 449 } else if (argv[i].endsWith(".java")) { 450 v.addElement(argv[i]); 451 } else { 452 error("main.no.such.option",argv[i]); 453 usage_error(); 454 return false; // Stop processing now 455 } 456 } 457 if (v.size() == 0 || exitStatus == EXIT_CMDERR) { 458 usage_error(); 459 return false; 460 } 461 462 // Create our Environment. 463 BatchEnvironment env = BatchEnvironment.create(out, 464 sourcePathArg, 465 classPathArg, 466 sysClassPathArg); 467 if (verbosePath) { 468 output(getText("main.path.msg", 469 env.sourcePath.toString(), 470 env.binaryPath.toString())); 471 } 472 473 env.flags |= flags; 474 env.majorVersion = majorVersion; 475 env.minorVersion = minorVersion; 476 // JCOV 477 env.covFile = covFile; 478 // end JCOV 479 env.setCharacterEncoding(encoding); 480 481 // Preload the "out of memory" error string just in case we run 482 // out of memory during the compile. 483 String noMemoryErrorString = getText("main.no.memory"); 484 String stackOverflowErrorString = getText("main.stack.overflow"); 485 486 env.error(0, "warn.class.is.deprecated", "sun.tools.javac.Main"); 487 488 try { 489 // Parse all input files 490 for (Enumeration<String> e = v.elements() ; e.hasMoreElements() ;) { 491 File file = new File(e.nextElement()); 492 try { 493 env.parseFile(ClassFile.newClassFile(file)); 494 } catch (FileNotFoundException ee) { 495 env.error(0, "cant.read", file.getPath()); 496 exitStatus = EXIT_CMDERR; 497 } 498 } 499 500 // Do a post-read check on all newly-parsed classes, 501 // after they have all been read. 502 for (Enumeration<ClassDeclaration> e = env.getClasses() ; e.hasMoreElements() ; ) { 503 ClassDeclaration c = e.nextElement(); 504 if (c.getStatus() == CS_PARSED) { 505 if (c.getClassDefinition().isLocal()) 506 continue; 507 try { 508 c.getClassDefinition(env); 509 } catch (ClassNotFound ee) { 510 } 511 } 512 } 513 514 // compile all classes that need compilation 515 ByteArrayOutputStream buf = new ByteArrayOutputStream(4096); 516 boolean done; 517 518 do { 519 done = true; 520 env.flushErrors(); 521 for (Enumeration<ClassDeclaration> e = env.getClasses() ; e.hasMoreElements() ; ) { 522 ClassDeclaration c = e.nextElement(); 523 SourceClass src; 524 525 switch (c.getStatus()) { 526 case CS_UNDEFINED: 527 if (!env.dependencies()) { 528 break; 529 } 530 // fall through 531 532 case CS_SOURCE: 533 if (tracing) 534 env.dtEvent("Main.compile (SOURCE): loading, " + c); 535 done = false; 536 env.loadDefinition(c); 537 if (c.getStatus() != CS_PARSED) { 538 if (tracing) 539 env.dtEvent("Main.compile (SOURCE): not parsed, " + c); 540 break; 541 } 542 // fall through 543 544 case CS_PARSED: 545 if (c.getClassDefinition().isInsideLocal()) { 546 // the enclosing block will check this one 547 if (tracing) 548 env.dtEvent("Main.compile (PARSED): skipping local class, " + c); 549 continue; 550 } 551 done = false; 552 if (tracing) env.dtEvent("Main.compile (PARSED): checking, " + c); 553 src = (SourceClass)c.getClassDefinition(env); 554 src.check(env); 555 c.setDefinition(src, CS_CHECKED); 556 // fall through 557 558 case CS_CHECKED: 559 src = (SourceClass)c.getClassDefinition(env); 560 // bail out if there were any errors 561 if (src.getError()) { 562 if (tracing) 563 env.dtEvent("Main.compile (CHECKED): bailing out on error, " + c); 564 c.setDefinition(src, CS_COMPILED); 565 break; 566 } 567 done = false; 568 buf.reset(); 569 if (tracing) 570 env.dtEvent("Main.compile (CHECKED): compiling, " + c); 571 src.compile(buf); 572 c.setDefinition(src, CS_COMPILED); 573 src.cleanup(env); 574 575 if (src.getNestError() || nowrite) { 576 continue; 577 } 578 579 String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar); 580 String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class"; 581 582 File file; 583 if (destDir != null) { 584 if (pkgName.length() > 0) { 585 file = new File(destDir, pkgName); 586 if (!file.exists()) { 587 file.mkdirs(); 588 } 589 file = new File(file, className); 590 } else { 591 file = new File(destDir, className); 592 } 593 } else { 594 ClassFile classfile = (ClassFile)src.getSource(); 595 if (classfile.isZipped()) { 596 env.error(0, "cant.write", classfile.getPath()); 597 exitStatus = EXIT_CMDERR; 598 continue; 599 } 600 file = new File(classfile.getPath()); 601 file = new File(file.getParent(), className); 602 } 603 604 // Create the file 605 try { 606 FileOutputStream out = new FileOutputStream(file.getPath()); 607 buf.writeTo(out); 608 out.close(); 609 610 if (env.verbose()) { 611 output(getText("main.wrote", file.getPath())); 612 } 613 } catch (IOException ee) { 614 env.error(0, "cant.write", file.getPath()); 615 exitStatus = EXIT_CMDERR; 616 } 617 618 // Print class dependencies if requested (-xdepend) 619 if (env.print_dependencies()) { 620 src.printClassDependencies(env); 621 } 622 } 623 } 624 } while (!done); 625 } catch (OutOfMemoryError ee) { 626 // The compiler has run out of memory. Use the error string 627 // which we preloaded. 628 env.output(noMemoryErrorString); 629 exitStatus = EXIT_SYSERR; 630 return false; 631 } catch (StackOverflowError ee) { 632 env.output(stackOverflowErrorString); 633 exitStatus = EXIT_SYSERR; 634 return false; 635 } catch (Error ee) { 636 // We allow the compiler to take an exception silently if a program 637 // error has previously been detected. Presumably, this makes the 638 // compiler more robust in the face of bad error recovery. 639 if (env.nerrors == 0 || env.dump()) { 640 ee.printStackTrace(); 641 env.error(0, "fatal.error"); 642 exitStatus = EXIT_ABNORMAL; 643 } 644 } catch (Exception ee) { 645 if (env.nerrors == 0 || env.dump()) { 646 ee.printStackTrace(); 647 env.error(0, "fatal.exception"); 648 exitStatus = EXIT_ABNORMAL; 649 } 650 } 651 652 int ndepfiles = env.deprecationFiles.size(); 653 if (ndepfiles > 0 && env.warnings()) { 654 int ndeps = env.ndeprecations; 655 Object file1 = env.deprecationFiles.elementAt(0); 656 if (env.deprecation()) { 657 if (ndepfiles > 1) { 658 env.error(0, "warn.note.deprecations", 659 ndepfiles, ndeps); 660 } else { 661 env.error(0, "warn.note.1deprecation", 662 file1, ndeps); 663 } 664 } else { 665 if (ndepfiles > 1) { 666 env.error(0, "warn.note.deprecations.silent", 667 ndepfiles, ndeps); 668 } else { 669 env.error(0, "warn.note.1deprecation.silent", 670 file1, ndeps); 671 } 672 } 673 } 674 675 env.flushErrors(); 676 env.shutdown(); 677 678 boolean status = true; 679 if (env.nerrors > 0) { 680 String msg = ""; 681 if (env.nerrors > 1) { 682 msg = getText("main.errors", env.nerrors); 683 } else { 684 msg = getText("main.1error"); 685 } 686 if (env.nwarnings > 0) { 687 if (env.nwarnings > 1) { 688 msg += ", " + getText("main.warnings", env.nwarnings); 689 } else { 690 msg += ", " + getText("main.1warning"); 691 } 692 } 693 output(msg); 694 if (exitStatus == EXIT_OK) { 695 // Allow EXIT_CMDERR or EXIT_ABNORMAL to take precedence. 696 exitStatus = EXIT_ERROR; 697 } 698 status = false; 699 } else { 700 if (env.nwarnings > 0) { 701 if (env.nwarnings > 1) { 702 output(getText("main.warnings", env.nwarnings)); 703 } else { 704 output(getText("main.1warning")); 705 } 706 } 707 } 708 //JCOV 709 if (env.covdata()) { 710 Assembler CovAsm = new Assembler(); 711 CovAsm.GenJCov(env); 712 } 713 // end JCOV 714 715 // We're done 716 if (env.verbose()) { 717 tm = System.currentTimeMillis() - tm; 718 output(getText("main.done_in", Long.toString(tm))); 719 } 720 721 return status; 722 } 723 724 /** 725 * Main program 726 */ main(String argv[])727 public static void main(String argv[]) { 728 OutputStream out = System.err; 729 730 // This is superceeded by the -Xstdout option, but we leave 731 // in the old property check for compatibility. 732 if (Boolean.getBoolean("javac.pipe.output")) { 733 out = System.out; 734 } 735 736 Main compiler = new Main(out, "javac"); 737 System.exit(compiler.compile(argv) ? 0 : compiler.exitStatus); 738 } 739 } 740