src/share/classes/com/sun/tools/javah/JavahTask.java

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javah;
aoqi@0 27
aoqi@0 28 import java.io.File;
aoqi@0 29 import java.io.FileNotFoundException;
aoqi@0 30 import java.io.IOException;
aoqi@0 31 import java.io.OutputStream;
aoqi@0 32 import java.io.PrintWriter;
aoqi@0 33 import java.io.Writer;
aoqi@0 34 import java.text.MessageFormat;
aoqi@0 35 import java.util.ArrayList;
aoqi@0 36 import java.util.Arrays;
aoqi@0 37 import java.util.Collections;
aoqi@0 38 import java.util.HashMap;
aoqi@0 39 import java.util.Iterator;
aoqi@0 40 import java.util.LinkedHashSet;
aoqi@0 41 import java.util.List;
aoqi@0 42 import java.util.Locale;
aoqi@0 43 import java.util.Map;
aoqi@0 44 import java.util.MissingResourceException;
aoqi@0 45 import java.util.ResourceBundle;
aoqi@0 46 import java.util.Set;
aoqi@0 47
aoqi@0 48 import javax.annotation.processing.AbstractProcessor;
aoqi@0 49 import javax.annotation.processing.Messager;
aoqi@0 50 import javax.annotation.processing.ProcessingEnvironment;
aoqi@0 51 import javax.annotation.processing.RoundEnvironment;
aoqi@0 52 import javax.annotation.processing.SupportedAnnotationTypes;
aoqi@0 53
aoqi@0 54 import javax.lang.model.SourceVersion;
aoqi@0 55 import javax.lang.model.element.ExecutableElement;
aoqi@0 56 import javax.lang.model.element.TypeElement;
aoqi@0 57 import javax.lang.model.element.VariableElement;
aoqi@0 58 import javax.lang.model.type.ArrayType;
aoqi@0 59 import javax.lang.model.type.DeclaredType;
aoqi@0 60 import javax.lang.model.type.TypeMirror;
aoqi@0 61 import javax.lang.model.type.TypeVisitor;
aoqi@0 62 import javax.lang.model.util.ElementFilter;
aoqi@0 63 import javax.lang.model.util.SimpleTypeVisitor8;
aoqi@0 64 import javax.lang.model.util.Types;
aoqi@0 65
aoqi@0 66 import javax.tools.Diagnostic;
aoqi@0 67 import javax.tools.DiagnosticListener;
aoqi@0 68 import javax.tools.JavaCompiler;
aoqi@0 69 import javax.tools.JavaCompiler.CompilationTask;
aoqi@0 70 import javax.tools.JavaFileManager;
aoqi@0 71 import javax.tools.JavaFileObject;
aoqi@0 72 import javax.tools.StandardJavaFileManager;
aoqi@0 73 import javax.tools.StandardLocation;
aoqi@0 74 import javax.tools.ToolProvider;
aoqi@0 75 import static javax.tools.Diagnostic.Kind.*;
aoqi@0 76
aoqi@0 77 import com.sun.tools.javac.code.Symbol.CompletionFailure;
aoqi@0 78 import com.sun.tools.javac.main.CommandLine;
aoqi@0 79
aoqi@0 80 /**
aoqi@0 81 * Javah generates support files for native methods.
aoqi@0 82 * Parse commandline options and invokes javadoc to execute those commands.
aoqi@0 83 *
aoqi@0 84 * <p><b>This is NOT part of any supported API.
aoqi@0 85 * If you write code that depends on this, you do so at your own
aoqi@0 86 * risk. This code and its internal interfaces are subject to change
aoqi@0 87 * or deletion without notice.</b></p>
aoqi@0 88 *
aoqi@0 89 * @author Sucheta Dambalkar
aoqi@0 90 * @author Jonathan Gibbons
aoqi@0 91 */
aoqi@0 92 public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
aoqi@0 93 public class BadArgs extends Exception {
aoqi@0 94 private static final long serialVersionUID = 1479361270874789045L;
aoqi@0 95 BadArgs(String key, Object... args) {
aoqi@0 96 super(JavahTask.this.getMessage(key, args));
aoqi@0 97 this.key = key;
aoqi@0 98 this.args = args;
aoqi@0 99 }
aoqi@0 100
aoqi@0 101 BadArgs showUsage(boolean b) {
aoqi@0 102 showUsage = b;
aoqi@0 103 return this;
aoqi@0 104 }
aoqi@0 105
aoqi@0 106 final String key;
aoqi@0 107 final Object[] args;
aoqi@0 108 boolean showUsage;
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 static abstract class Option {
aoqi@0 112 Option(boolean hasArg, String... aliases) {
aoqi@0 113 this.hasArg = hasArg;
aoqi@0 114 this.aliases = aliases;
aoqi@0 115 }
aoqi@0 116
aoqi@0 117 boolean isHidden() {
aoqi@0 118 return false;
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 boolean matches(String opt) {
aoqi@0 122 for (String a: aliases) {
aoqi@0 123 if (a.equals(opt))
aoqi@0 124 return true;
aoqi@0 125 }
aoqi@0 126 return false;
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 boolean ignoreRest() {
aoqi@0 130 return false;
aoqi@0 131 }
aoqi@0 132
aoqi@0 133 abstract void process(JavahTask task, String opt, String arg) throws BadArgs;
aoqi@0 134
aoqi@0 135 final boolean hasArg;
aoqi@0 136 final String[] aliases;
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 static abstract class HiddenOption extends Option {
aoqi@0 140 HiddenOption(boolean hasArg, String... aliases) {
aoqi@0 141 super(hasArg, aliases);
aoqi@0 142 }
aoqi@0 143
aoqi@0 144 @Override
aoqi@0 145 boolean isHidden() {
aoqi@0 146 return true;
aoqi@0 147 }
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 static final Option[] recognizedOptions = {
aoqi@0 151 new Option(true, "-o") {
aoqi@0 152 void process(JavahTask task, String opt, String arg) {
aoqi@0 153 task.ofile = new File(arg);
aoqi@0 154 }
aoqi@0 155 },
aoqi@0 156
aoqi@0 157 new Option(true, "-d") {
aoqi@0 158 void process(JavahTask task, String opt, String arg) {
aoqi@0 159 task.odir = new File(arg);
aoqi@0 160 }
aoqi@0 161 },
aoqi@0 162
aoqi@0 163 new HiddenOption(true, "-td") {
aoqi@0 164 void process(JavahTask task, String opt, String arg) {
aoqi@0 165 // ignored; for backwards compatibility
aoqi@0 166 }
aoqi@0 167 },
aoqi@0 168
aoqi@0 169 new HiddenOption(false, "-stubs") {
aoqi@0 170 void process(JavahTask task, String opt, String arg) {
aoqi@0 171 // ignored; for backwards compatibility
aoqi@0 172 }
aoqi@0 173 },
aoqi@0 174
aoqi@0 175 new Option(false, "-v", "-verbose") {
aoqi@0 176 void process(JavahTask task, String opt, String arg) {
aoqi@0 177 task.verbose = true;
aoqi@0 178 }
aoqi@0 179 },
aoqi@0 180
aoqi@0 181 new Option(false, "-h", "-help", "--help", "-?") {
aoqi@0 182 void process(JavahTask task, String opt, String arg) {
aoqi@0 183 task.help = true;
aoqi@0 184 }
aoqi@0 185 },
aoqi@0 186
aoqi@0 187 new HiddenOption(false, "-trace") {
aoqi@0 188 void process(JavahTask task, String opt, String arg) {
aoqi@0 189 task.trace = true;
aoqi@0 190 }
aoqi@0 191 },
aoqi@0 192
aoqi@0 193 new Option(false, "-version") {
aoqi@0 194 void process(JavahTask task, String opt, String arg) {
aoqi@0 195 task.version = true;
aoqi@0 196 }
aoqi@0 197 },
aoqi@0 198
aoqi@0 199 new HiddenOption(false, "-fullversion") {
aoqi@0 200 void process(JavahTask task, String opt, String arg) {
aoqi@0 201 task.fullVersion = true;
aoqi@0 202 }
aoqi@0 203 },
aoqi@0 204
aoqi@0 205 new Option(false, "-jni") {
aoqi@0 206 void process(JavahTask task, String opt, String arg) {
aoqi@0 207 task.jni = true;
aoqi@0 208 }
aoqi@0 209 },
aoqi@0 210
aoqi@0 211 new Option(false, "-force") {
aoqi@0 212 void process(JavahTask task, String opt, String arg) {
aoqi@0 213 task.force = true;
aoqi@0 214 }
aoqi@0 215 },
aoqi@0 216
aoqi@0 217 new HiddenOption(false, "-Xnew") {
aoqi@0 218 void process(JavahTask task, String opt, String arg) {
aoqi@0 219 // we're already using the new javah
aoqi@0 220 }
aoqi@0 221 },
aoqi@0 222
aoqi@0 223 new HiddenOption(false, "-llni", "-Xllni") {
aoqi@0 224 void process(JavahTask task, String opt, String arg) {
aoqi@0 225 task.llni = true;
aoqi@0 226 }
aoqi@0 227 },
aoqi@0 228
aoqi@0 229 new HiddenOption(false, "-llnidouble") {
aoqi@0 230 void process(JavahTask task, String opt, String arg) {
aoqi@0 231 task.llni = true;
aoqi@0 232 task.doubleAlign = true;
aoqi@0 233 }
aoqi@0 234 },
aoqi@0 235
aoqi@0 236 new HiddenOption(false) {
aoqi@0 237 boolean matches(String opt) {
aoqi@0 238 return opt.startsWith("-XD");
aoqi@0 239 }
aoqi@0 240 void process(JavahTask task, String opt, String arg) {
aoqi@0 241 task.javac_extras.add(opt);
aoqi@0 242 }
aoqi@0 243 },
aoqi@0 244 };
aoqi@0 245
aoqi@0 246 JavahTask() {
aoqi@0 247 }
aoqi@0 248
aoqi@0 249 JavahTask(Writer out,
aoqi@0 250 JavaFileManager fileManager,
aoqi@0 251 DiagnosticListener<? super JavaFileObject> diagnosticListener,
aoqi@0 252 Iterable<String> options,
aoqi@0 253 Iterable<String> classes) {
aoqi@0 254 this();
aoqi@0 255 this.log = getPrintWriterForWriter(out);
aoqi@0 256 this.fileManager = fileManager;
aoqi@0 257 this.diagnosticListener = diagnosticListener;
aoqi@0 258
aoqi@0 259 try {
aoqi@0 260 handleOptions(options, false);
aoqi@0 261 } catch (BadArgs e) {
aoqi@0 262 throw new IllegalArgumentException(e.getMessage());
aoqi@0 263 }
aoqi@0 264
aoqi@0 265 this.classes = new ArrayList<String>();
aoqi@0 266 if (classes != null) {
aoqi@0 267 for (String classname: classes) {
aoqi@0 268 classname.getClass(); // null-check
aoqi@0 269 this.classes.add(classname);
aoqi@0 270 }
aoqi@0 271 }
aoqi@0 272 }
aoqi@0 273
aoqi@0 274 public void setLocale(Locale locale) {
aoqi@0 275 if (locale == null)
aoqi@0 276 locale = Locale.getDefault();
aoqi@0 277 task_locale = locale;
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 public void setLog(PrintWriter log) {
aoqi@0 281 this.log = log;
aoqi@0 282 }
aoqi@0 283
aoqi@0 284 public void setLog(OutputStream s) {
aoqi@0 285 setLog(getPrintWriterForStream(s));
aoqi@0 286 }
aoqi@0 287
aoqi@0 288 static PrintWriter getPrintWriterForStream(OutputStream s) {
aoqi@0 289 return new PrintWriter(s, true);
aoqi@0 290 }
aoqi@0 291
aoqi@0 292 static PrintWriter getPrintWriterForWriter(Writer w) {
aoqi@0 293 if (w == null)
aoqi@0 294 return getPrintWriterForStream(null);
aoqi@0 295 else if (w instanceof PrintWriter)
aoqi@0 296 return (PrintWriter) w;
aoqi@0 297 else
aoqi@0 298 return new PrintWriter(w, true);
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
aoqi@0 302 diagnosticListener = dl;
aoqi@0 303 }
aoqi@0 304
aoqi@0 305 public void setDiagnosticListener(OutputStream s) {
aoqi@0 306 setDiagnosticListener(getDiagnosticListenerForStream(s));
aoqi@0 307 }
aoqi@0 308
aoqi@0 309 private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
aoqi@0 310 return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
aoqi@0 314 final PrintWriter pw = getPrintWriterForWriter(w);
aoqi@0 315 return new DiagnosticListener<JavaFileObject> () {
aoqi@0 316 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
aoqi@0 317 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
aoqi@0 318 pw.print(getMessage("err.prefix"));
aoqi@0 319 pw.print(" ");
aoqi@0 320 }
aoqi@0 321 pw.println(diagnostic.getMessage(null));
aoqi@0 322 }
aoqi@0 323 };
aoqi@0 324 }
aoqi@0 325
aoqi@0 326 int run(String[] args) {
aoqi@0 327 try {
aoqi@0 328 handleOptions(args);
aoqi@0 329 boolean ok = run();
aoqi@0 330 return ok ? 0 : 1;
aoqi@0 331 } catch (BadArgs e) {
aoqi@0 332 diagnosticListener.report(createDiagnostic(e.key, e.args));
aoqi@0 333 return 1;
aoqi@0 334 } catch (InternalError e) {
aoqi@0 335 diagnosticListener.report(createDiagnostic("err.internal.error", e.getMessage()));
aoqi@0 336 return 1;
aoqi@0 337 } catch (Util.Exit e) {
aoqi@0 338 return e.exitValue;
aoqi@0 339 } finally {
aoqi@0 340 log.flush();
aoqi@0 341 }
aoqi@0 342 }
aoqi@0 343
aoqi@0 344 public void handleOptions(String[] args) throws BadArgs {
aoqi@0 345 handleOptions(Arrays.asList(args), true);
aoqi@0 346 }
aoqi@0 347
aoqi@0 348 private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
aoqi@0 349 if (log == null) {
aoqi@0 350 log = getPrintWriterForStream(System.out);
aoqi@0 351 if (diagnosticListener == null)
aoqi@0 352 diagnosticListener = getDiagnosticListenerForStream(System.err);
aoqi@0 353 } else {
aoqi@0 354 if (diagnosticListener == null)
aoqi@0 355 diagnosticListener = getDiagnosticListenerForWriter(log);
aoqi@0 356 }
aoqi@0 357
aoqi@0 358 if (fileManager == null)
aoqi@0 359 fileManager = getDefaultFileManager(diagnosticListener, log);
aoqi@0 360
aoqi@0 361 Iterator<String> iter = expandAtArgs(args).iterator();
aoqi@0 362 noArgs = !iter.hasNext();
aoqi@0 363
aoqi@0 364 while (iter.hasNext()) {
aoqi@0 365 String arg = iter.next();
aoqi@0 366 if (arg.startsWith("-"))
aoqi@0 367 handleOption(arg, iter);
aoqi@0 368 else if (allowClasses) {
aoqi@0 369 if (classes == null)
aoqi@0 370 classes = new ArrayList<String>();
aoqi@0 371 classes.add(arg);
aoqi@0 372 while (iter.hasNext())
aoqi@0 373 classes.add(iter.next());
aoqi@0 374 } else
aoqi@0 375 throw new BadArgs("err.unknown.option", arg).showUsage(true);
aoqi@0 376 }
aoqi@0 377
aoqi@0 378 if ((classes == null || classes.size() == 0) &&
aoqi@0 379 !(noArgs || help || version || fullVersion)) {
aoqi@0 380 throw new BadArgs("err.no.classes.specified");
aoqi@0 381 }
aoqi@0 382
aoqi@0 383 if (jni && llni)
aoqi@0 384 throw new BadArgs("jni.llni.mixed");
aoqi@0 385
aoqi@0 386 if (odir != null && ofile != null)
aoqi@0 387 throw new BadArgs("dir.file.mixed");
aoqi@0 388 }
aoqi@0 389
aoqi@0 390 private void handleOption(String name, Iterator<String> rest) throws BadArgs {
aoqi@0 391 for (Option o: recognizedOptions) {
aoqi@0 392 if (o.matches(name)) {
aoqi@0 393 if (o.hasArg) {
aoqi@0 394 if (rest.hasNext())
aoqi@0 395 o.process(this, name, rest.next());
aoqi@0 396 else
aoqi@0 397 throw new BadArgs("err.missing.arg", name).showUsage(true);
aoqi@0 398 } else
aoqi@0 399 o.process(this, name, null);
aoqi@0 400
aoqi@0 401 if (o.ignoreRest()) {
aoqi@0 402 while (rest.hasNext())
aoqi@0 403 rest.next();
aoqi@0 404 }
aoqi@0 405 return;
aoqi@0 406 }
aoqi@0 407 }
aoqi@0 408
aoqi@0 409 if (fileManager.handleOption(name, rest))
aoqi@0 410 return;
aoqi@0 411
aoqi@0 412 throw new BadArgs("err.unknown.option", name).showUsage(true);
aoqi@0 413 }
aoqi@0 414
aoqi@0 415 private Iterable<String> expandAtArgs(Iterable<String> args) throws BadArgs {
aoqi@0 416 try {
aoqi@0 417 List<String> l = new ArrayList<String>();
aoqi@0 418 for (String arg: args) l.add(arg);
aoqi@0 419 return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()])));
aoqi@0 420 } catch (FileNotFoundException e) {
aoqi@0 421 throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage());
aoqi@0 422 } catch (IOException e) {
aoqi@0 423 throw new BadArgs("at.args.io.exception", e.getLocalizedMessage());
aoqi@0 424 }
aoqi@0 425 }
aoqi@0 426
aoqi@0 427 public Boolean call() {
aoqi@0 428 return run();
aoqi@0 429 }
aoqi@0 430
aoqi@0 431 public boolean run() throws Util.Exit {
aoqi@0 432
aoqi@0 433 Util util = new Util(log, diagnosticListener);
aoqi@0 434
aoqi@0 435 if (noArgs || help) {
aoqi@0 436 showHelp();
aoqi@0 437 return help; // treat noArgs as an error for purposes of exit code
aoqi@0 438 }
aoqi@0 439
aoqi@0 440 if (version || fullVersion) {
aoqi@0 441 showVersion(fullVersion);
aoqi@0 442 return true;
aoqi@0 443 }
aoqi@0 444
aoqi@0 445 util.verbose = verbose;
aoqi@0 446
aoqi@0 447 Gen g;
aoqi@0 448
aoqi@0 449 if (llni)
aoqi@0 450 g = new LLNI(doubleAlign, util);
aoqi@0 451 else {
aoqi@0 452 // if (stubs)
aoqi@0 453 // throw new BadArgs("jni.no.stubs");
aoqi@0 454 g = new JNI(util);
aoqi@0 455 }
aoqi@0 456
aoqi@0 457 if (ofile != null) {
aoqi@0 458 if (!(fileManager instanceof StandardJavaFileManager)) {
aoqi@0 459 diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-o"));
aoqi@0 460 return false;
aoqi@0 461 }
aoqi@0 462 Iterable<? extends JavaFileObject> iter =
aoqi@0 463 ((StandardJavaFileManager) fileManager).getJavaFileObjectsFromFiles(Collections.singleton(ofile));
aoqi@0 464 JavaFileObject fo = iter.iterator().next();
aoqi@0 465 g.setOutFile(fo);
aoqi@0 466 } else {
aoqi@0 467 if (odir != null) {
aoqi@0 468 if (!(fileManager instanceof StandardJavaFileManager)) {
aoqi@0 469 diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-d"));
aoqi@0 470 return false;
aoqi@0 471 }
aoqi@0 472
aoqi@0 473 if (!odir.exists())
aoqi@0 474 if (!odir.mkdirs())
aoqi@0 475 util.error("cant.create.dir", odir.toString());
aoqi@0 476 try {
aoqi@0 477 ((StandardJavaFileManager) fileManager).setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(odir));
aoqi@0 478 } catch (IOException e) {
aoqi@0 479 Object msg = e.getLocalizedMessage();
aoqi@0 480 if (msg == null) {
aoqi@0 481 msg = e;
aoqi@0 482 }
aoqi@0 483 diagnosticListener.report(createDiagnostic("err.ioerror", odir, msg));
aoqi@0 484 return false;
aoqi@0 485 }
aoqi@0 486 }
aoqi@0 487 g.setFileManager(fileManager);
aoqi@0 488 }
aoqi@0 489
aoqi@0 490 /*
aoqi@0 491 * Force set to false will turn off smarts about checking file
aoqi@0 492 * content before writing.
aoqi@0 493 */
aoqi@0 494 g.setForce(force);
aoqi@0 495
aoqi@0 496 if (fileManager instanceof JavahFileManager)
aoqi@0 497 ((JavahFileManager) fileManager).setSymbolFileEnabled(false);
aoqi@0 498
aoqi@0 499 JavaCompiler c = ToolProvider.getSystemJavaCompiler();
aoqi@0 500 List<String> opts = new ArrayList<String>();
aoqi@0 501 opts.add("-proc:only");
aoqi@0 502 opts.addAll(javac_extras);
aoqi@0 503 CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null);
aoqi@0 504 JavahProcessor p = new JavahProcessor(g);
aoqi@0 505 t.setProcessors(Collections.singleton(p));
aoqi@0 506
aoqi@0 507 boolean ok = t.call();
aoqi@0 508 if (p.exit != null)
aoqi@0 509 throw new Util.Exit(p.exit);
aoqi@0 510 return ok;
aoqi@0 511 }
aoqi@0 512
aoqi@0 513 private List<File> pathToFiles(String path) {
aoqi@0 514 List<File> files = new ArrayList<File>();
aoqi@0 515 for (String f: path.split(File.pathSeparator)) {
aoqi@0 516 if (f.length() > 0)
aoqi@0 517 files.add(new File(f));
aoqi@0 518 }
aoqi@0 519 return files;
aoqi@0 520 }
aoqi@0 521
aoqi@0 522 static StandardJavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
aoqi@0 523 return JavahFileManager.create(dl, log);
aoqi@0 524 }
aoqi@0 525
aoqi@0 526 private void showHelp() {
aoqi@0 527 log.println(getMessage("main.usage", progname));
aoqi@0 528 for (Option o: recognizedOptions) {
aoqi@0 529 if (o.isHidden())
aoqi@0 530 continue;
aoqi@0 531 String name = o.aliases[0].substring(1); // there must always be at least one name
aoqi@0 532 log.println(getMessage("main.opt." + name));
aoqi@0 533 }
aoqi@0 534 String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
aoqi@0 535 for (String o: fmOptions) {
aoqi@0 536 if (fileManager.isSupportedOption(o) == -1)
aoqi@0 537 continue;
aoqi@0 538 String name = o.substring(1);
aoqi@0 539 log.println(getMessage("main.opt." + name));
aoqi@0 540 }
aoqi@0 541 log.println(getMessage("main.usage.foot"));
aoqi@0 542 }
aoqi@0 543
aoqi@0 544 private void showVersion(boolean full) {
aoqi@0 545 log.println(version(full));
aoqi@0 546 }
aoqi@0 547
aoqi@0 548 private static final String versionRBName = "com.sun.tools.javah.resources.version";
aoqi@0 549 private static ResourceBundle versionRB;
aoqi@0 550
aoqi@0 551 private String version(boolean full) {
aoqi@0 552 String msgKey = (full ? "javah.fullVersion" : "javah.version");
aoqi@0 553 String versionKey = (full ? "full" : "release");
aoqi@0 554 // versionKey=product: mm.nn.oo[-milestone]
aoqi@0 555 // versionKey=full: mm.mm.oo[-milestone]-build
aoqi@0 556 if (versionRB == null) {
aoqi@0 557 try {
aoqi@0 558 versionRB = ResourceBundle.getBundle(versionRBName);
aoqi@0 559 } catch (MissingResourceException e) {
aoqi@0 560 return getMessage("version.resource.missing", System.getProperty("java.version"));
aoqi@0 561 }
aoqi@0 562 }
aoqi@0 563 try {
aoqi@0 564 return getMessage(msgKey, "javah", versionRB.getString(versionKey));
aoqi@0 565 }
aoqi@0 566 catch (MissingResourceException e) {
aoqi@0 567 return getMessage("version.unknown", System.getProperty("java.version"));
aoqi@0 568 }
aoqi@0 569 }
aoqi@0 570
aoqi@0 571 private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
aoqi@0 572 return new Diagnostic<JavaFileObject>() {
aoqi@0 573 public Kind getKind() {
aoqi@0 574 return Diagnostic.Kind.ERROR;
aoqi@0 575 }
aoqi@0 576
aoqi@0 577 public JavaFileObject getSource() {
aoqi@0 578 return null;
aoqi@0 579 }
aoqi@0 580
aoqi@0 581 public long getPosition() {
aoqi@0 582 return Diagnostic.NOPOS;
aoqi@0 583 }
aoqi@0 584
aoqi@0 585 public long getStartPosition() {
aoqi@0 586 return Diagnostic.NOPOS;
aoqi@0 587 }
aoqi@0 588
aoqi@0 589 public long getEndPosition() {
aoqi@0 590 return Diagnostic.NOPOS;
aoqi@0 591 }
aoqi@0 592
aoqi@0 593 public long getLineNumber() {
aoqi@0 594 return Diagnostic.NOPOS;
aoqi@0 595 }
aoqi@0 596
aoqi@0 597 public long getColumnNumber() {
aoqi@0 598 return Diagnostic.NOPOS;
aoqi@0 599 }
aoqi@0 600
aoqi@0 601 public String getCode() {
aoqi@0 602 return key;
aoqi@0 603 }
aoqi@0 604
aoqi@0 605 public String getMessage(Locale locale) {
aoqi@0 606 return JavahTask.this.getMessage(locale, key, args);
aoqi@0 607 }
aoqi@0 608
aoqi@0 609 };
aoqi@0 610 }
aoqi@0 611
aoqi@0 612 private String getMessage(String key, Object... args) {
aoqi@0 613 return getMessage(task_locale, key, args);
aoqi@0 614 }
aoqi@0 615
aoqi@0 616 private String getMessage(Locale locale, String key, Object... args) {
aoqi@0 617 if (bundles == null) {
aoqi@0 618 // could make this a HashMap<Locale,SoftReference<ResourceBundle>>
aoqi@0 619 // and for efficiency, keep a hard reference to the bundle for the task
aoqi@0 620 // locale
aoqi@0 621 bundles = new HashMap<Locale, ResourceBundle>();
aoqi@0 622 }
aoqi@0 623
aoqi@0 624 if (locale == null)
aoqi@0 625 locale = Locale.getDefault();
aoqi@0 626
aoqi@0 627 ResourceBundle b = bundles.get(locale);
aoqi@0 628 if (b == null) {
aoqi@0 629 try {
aoqi@0 630 b = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n", locale);
aoqi@0 631 bundles.put(locale, b);
aoqi@0 632 } catch (MissingResourceException e) {
aoqi@0 633 throw new InternalError("Cannot find javah resource bundle for locale " + locale, e);
aoqi@0 634 }
aoqi@0 635 }
aoqi@0 636
aoqi@0 637 try {
aoqi@0 638 return MessageFormat.format(b.getString(key), args);
aoqi@0 639 } catch (MissingResourceException e) {
aoqi@0 640 return key;
aoqi@0 641 //throw new InternalError(e, key);
aoqi@0 642 }
aoqi@0 643 }
aoqi@0 644
aoqi@0 645 File ofile;
aoqi@0 646 File odir;
aoqi@0 647 String bootcp;
aoqi@0 648 String usercp;
aoqi@0 649 List<String> classes;
aoqi@0 650 boolean verbose;
aoqi@0 651 boolean noArgs;
aoqi@0 652 boolean help;
aoqi@0 653 boolean trace;
aoqi@0 654 boolean version;
aoqi@0 655 boolean fullVersion;
aoqi@0 656 boolean jni;
aoqi@0 657 boolean llni;
aoqi@0 658 boolean doubleAlign;
aoqi@0 659 boolean force;
aoqi@0 660 Set<String> javac_extras = new LinkedHashSet<String>();
aoqi@0 661
aoqi@0 662 PrintWriter log;
aoqi@0 663 JavaFileManager fileManager;
aoqi@0 664 DiagnosticListener<? super JavaFileObject> diagnosticListener;
aoqi@0 665 Locale task_locale;
aoqi@0 666 Map<Locale, ResourceBundle> bundles;
aoqi@0 667
aoqi@0 668 private static final String progname = "javah";
aoqi@0 669
aoqi@0 670 @SupportedAnnotationTypes("*")
aoqi@0 671 class JavahProcessor extends AbstractProcessor {
aoqi@0 672 private Messager messager;
aoqi@0 673
aoqi@0 674 JavahProcessor(Gen g) {
aoqi@0 675 this.g = g;
aoqi@0 676 }
aoqi@0 677
aoqi@0 678 @Override
aoqi@0 679 public SourceVersion getSupportedSourceVersion() {
aoqi@0 680 // since this is co-bundled with javac, we can assume it supports
aoqi@0 681 // the latest source version
aoqi@0 682 return SourceVersion.latest();
aoqi@0 683 }
aoqi@0 684
aoqi@0 685 @Override
aoqi@0 686 public void init(ProcessingEnvironment pEnv) {
aoqi@0 687 super.init(pEnv);
aoqi@0 688 messager = processingEnv.getMessager();
aoqi@0 689 }
aoqi@0 690
aoqi@0 691 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
aoqi@0 692 try {
aoqi@0 693 Set<TypeElement> classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements()));
aoqi@0 694 if (classes.size() > 0) {
aoqi@0 695 checkMethodParameters(classes);
aoqi@0 696 g.setProcessingEnvironment(processingEnv);
aoqi@0 697 g.setClasses(classes);
aoqi@0 698 g.run();
aoqi@0 699 }
aoqi@0 700 } catch (CompletionFailure cf) {
aoqi@0 701 messager.printMessage(ERROR, getMessage("class.not.found", cf.sym.getQualifiedName().toString()));
aoqi@0 702 } catch (ClassNotFoundException cnfe) {
aoqi@0 703 messager.printMessage(ERROR, getMessage("class.not.found", cnfe.getMessage()));
aoqi@0 704 } catch (IOException ioe) {
aoqi@0 705 messager.printMessage(ERROR, getMessage("io.exception", ioe.getMessage()));
aoqi@0 706 } catch (Util.Exit e) {
aoqi@0 707 exit = e;
aoqi@0 708 }
aoqi@0 709
aoqi@0 710 return true;
aoqi@0 711 }
aoqi@0 712
aoqi@0 713 private Set<TypeElement> getAllClasses(Set<? extends TypeElement> classes) {
aoqi@0 714 Set<TypeElement> allClasses = new LinkedHashSet<TypeElement>();
aoqi@0 715 getAllClasses0(classes, allClasses);
aoqi@0 716 return allClasses;
aoqi@0 717 }
aoqi@0 718
aoqi@0 719 private void getAllClasses0(Iterable<? extends TypeElement> classes, Set<TypeElement> allClasses) {
aoqi@0 720 for (TypeElement c: classes) {
aoqi@0 721 allClasses.add(c);
aoqi@0 722 getAllClasses0(ElementFilter.typesIn(c.getEnclosedElements()), allClasses);
aoqi@0 723 }
aoqi@0 724 }
aoqi@0 725
aoqi@0 726 // 4942232:
aoqi@0 727 // check that classes exist for all the parameters of native methods
aoqi@0 728 private void checkMethodParameters(Set<TypeElement> classes) {
aoqi@0 729 Types types = processingEnv.getTypeUtils();
aoqi@0 730 for (TypeElement te: classes) {
aoqi@0 731 for (ExecutableElement ee: ElementFilter.methodsIn(te.getEnclosedElements())) {
aoqi@0 732 for (VariableElement ve: ee.getParameters()) {
aoqi@0 733 TypeMirror tm = ve.asType();
aoqi@0 734 checkMethodParametersVisitor.visit(tm, types);
aoqi@0 735 }
aoqi@0 736 }
aoqi@0 737 }
aoqi@0 738 }
aoqi@0 739
aoqi@0 740 private TypeVisitor<Void,Types> checkMethodParametersVisitor =
aoqi@0 741 new SimpleTypeVisitor8<Void,Types>() {
aoqi@0 742 @Override
aoqi@0 743 public Void visitArray(ArrayType t, Types types) {
aoqi@0 744 visit(t.getComponentType(), types);
aoqi@0 745 return null;
aoqi@0 746 }
aoqi@0 747 @Override
aoqi@0 748 public Void visitDeclared(DeclaredType t, Types types) {
aoqi@0 749 t.asElement().getKind(); // ensure class exists
aoqi@0 750 for (TypeMirror st: types.directSupertypes(t))
aoqi@0 751 visit(st, types);
aoqi@0 752 return null;
aoqi@0 753 }
aoqi@0 754 };
aoqi@0 755
aoqi@0 756 private Gen g;
aoqi@0 757 private Util.Exit exit;
aoqi@0 758 }
aoqi@0 759 }

mercurial