1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javah/JavahTask.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,759 @@ 1.4 +/* 1.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javah; 1.30 + 1.31 +import java.io.File; 1.32 +import java.io.FileNotFoundException; 1.33 +import java.io.IOException; 1.34 +import java.io.OutputStream; 1.35 +import java.io.PrintWriter; 1.36 +import java.io.Writer; 1.37 +import java.text.MessageFormat; 1.38 +import java.util.ArrayList; 1.39 +import java.util.Arrays; 1.40 +import java.util.Collections; 1.41 +import java.util.HashMap; 1.42 +import java.util.Iterator; 1.43 +import java.util.LinkedHashSet; 1.44 +import java.util.List; 1.45 +import java.util.Locale; 1.46 +import java.util.Map; 1.47 +import java.util.MissingResourceException; 1.48 +import java.util.ResourceBundle; 1.49 +import java.util.Set; 1.50 + 1.51 +import javax.annotation.processing.AbstractProcessor; 1.52 +import javax.annotation.processing.Messager; 1.53 +import javax.annotation.processing.ProcessingEnvironment; 1.54 +import javax.annotation.processing.RoundEnvironment; 1.55 +import javax.annotation.processing.SupportedAnnotationTypes; 1.56 + 1.57 +import javax.lang.model.SourceVersion; 1.58 +import javax.lang.model.element.ExecutableElement; 1.59 +import javax.lang.model.element.TypeElement; 1.60 +import javax.lang.model.element.VariableElement; 1.61 +import javax.lang.model.type.ArrayType; 1.62 +import javax.lang.model.type.DeclaredType; 1.63 +import javax.lang.model.type.TypeMirror; 1.64 +import javax.lang.model.type.TypeVisitor; 1.65 +import javax.lang.model.util.ElementFilter; 1.66 +import javax.lang.model.util.SimpleTypeVisitor8; 1.67 +import javax.lang.model.util.Types; 1.68 + 1.69 +import javax.tools.Diagnostic; 1.70 +import javax.tools.DiagnosticListener; 1.71 +import javax.tools.JavaCompiler; 1.72 +import javax.tools.JavaCompiler.CompilationTask; 1.73 +import javax.tools.JavaFileManager; 1.74 +import javax.tools.JavaFileObject; 1.75 +import javax.tools.StandardJavaFileManager; 1.76 +import javax.tools.StandardLocation; 1.77 +import javax.tools.ToolProvider; 1.78 +import static javax.tools.Diagnostic.Kind.*; 1.79 + 1.80 +import com.sun.tools.javac.code.Symbol.CompletionFailure; 1.81 +import com.sun.tools.javac.main.CommandLine; 1.82 + 1.83 +/** 1.84 + * Javah generates support files for native methods. 1.85 + * Parse commandline options and invokes javadoc to execute those commands. 1.86 + * 1.87 + * <p><b>This is NOT part of any supported API. 1.88 + * If you write code that depends on this, you do so at your own 1.89 + * risk. This code and its internal interfaces are subject to change 1.90 + * or deletion without notice.</b></p> 1.91 + * 1.92 + * @author Sucheta Dambalkar 1.93 + * @author Jonathan Gibbons 1.94 + */ 1.95 +public class JavahTask implements NativeHeaderTool.NativeHeaderTask { 1.96 + public class BadArgs extends Exception { 1.97 + private static final long serialVersionUID = 1479361270874789045L; 1.98 + BadArgs(String key, Object... args) { 1.99 + super(JavahTask.this.getMessage(key, args)); 1.100 + this.key = key; 1.101 + this.args = args; 1.102 + } 1.103 + 1.104 + BadArgs showUsage(boolean b) { 1.105 + showUsage = b; 1.106 + return this; 1.107 + } 1.108 + 1.109 + final String key; 1.110 + final Object[] args; 1.111 + boolean showUsage; 1.112 + } 1.113 + 1.114 + static abstract class Option { 1.115 + Option(boolean hasArg, String... aliases) { 1.116 + this.hasArg = hasArg; 1.117 + this.aliases = aliases; 1.118 + } 1.119 + 1.120 + boolean isHidden() { 1.121 + return false; 1.122 + } 1.123 + 1.124 + boolean matches(String opt) { 1.125 + for (String a: aliases) { 1.126 + if (a.equals(opt)) 1.127 + return true; 1.128 + } 1.129 + return false; 1.130 + } 1.131 + 1.132 + boolean ignoreRest() { 1.133 + return false; 1.134 + } 1.135 + 1.136 + abstract void process(JavahTask task, String opt, String arg) throws BadArgs; 1.137 + 1.138 + final boolean hasArg; 1.139 + final String[] aliases; 1.140 + } 1.141 + 1.142 + static abstract class HiddenOption extends Option { 1.143 + HiddenOption(boolean hasArg, String... aliases) { 1.144 + super(hasArg, aliases); 1.145 + } 1.146 + 1.147 + @Override 1.148 + boolean isHidden() { 1.149 + return true; 1.150 + } 1.151 + } 1.152 + 1.153 + static final Option[] recognizedOptions = { 1.154 + new Option(true, "-o") { 1.155 + void process(JavahTask task, String opt, String arg) { 1.156 + task.ofile = new File(arg); 1.157 + } 1.158 + }, 1.159 + 1.160 + new Option(true, "-d") { 1.161 + void process(JavahTask task, String opt, String arg) { 1.162 + task.odir = new File(arg); 1.163 + } 1.164 + }, 1.165 + 1.166 + new HiddenOption(true, "-td") { 1.167 + void process(JavahTask task, String opt, String arg) { 1.168 + // ignored; for backwards compatibility 1.169 + } 1.170 + }, 1.171 + 1.172 + new HiddenOption(false, "-stubs") { 1.173 + void process(JavahTask task, String opt, String arg) { 1.174 + // ignored; for backwards compatibility 1.175 + } 1.176 + }, 1.177 + 1.178 + new Option(false, "-v", "-verbose") { 1.179 + void process(JavahTask task, String opt, String arg) { 1.180 + task.verbose = true; 1.181 + } 1.182 + }, 1.183 + 1.184 + new Option(false, "-h", "-help", "--help", "-?") { 1.185 + void process(JavahTask task, String opt, String arg) { 1.186 + task.help = true; 1.187 + } 1.188 + }, 1.189 + 1.190 + new HiddenOption(false, "-trace") { 1.191 + void process(JavahTask task, String opt, String arg) { 1.192 + task.trace = true; 1.193 + } 1.194 + }, 1.195 + 1.196 + new Option(false, "-version") { 1.197 + void process(JavahTask task, String opt, String arg) { 1.198 + task.version = true; 1.199 + } 1.200 + }, 1.201 + 1.202 + new HiddenOption(false, "-fullversion") { 1.203 + void process(JavahTask task, String opt, String arg) { 1.204 + task.fullVersion = true; 1.205 + } 1.206 + }, 1.207 + 1.208 + new Option(false, "-jni") { 1.209 + void process(JavahTask task, String opt, String arg) { 1.210 + task.jni = true; 1.211 + } 1.212 + }, 1.213 + 1.214 + new Option(false, "-force") { 1.215 + void process(JavahTask task, String opt, String arg) { 1.216 + task.force = true; 1.217 + } 1.218 + }, 1.219 + 1.220 + new HiddenOption(false, "-Xnew") { 1.221 + void process(JavahTask task, String opt, String arg) { 1.222 + // we're already using the new javah 1.223 + } 1.224 + }, 1.225 + 1.226 + new HiddenOption(false, "-llni", "-Xllni") { 1.227 + void process(JavahTask task, String opt, String arg) { 1.228 + task.llni = true; 1.229 + } 1.230 + }, 1.231 + 1.232 + new HiddenOption(false, "-llnidouble") { 1.233 + void process(JavahTask task, String opt, String arg) { 1.234 + task.llni = true; 1.235 + task.doubleAlign = true; 1.236 + } 1.237 + }, 1.238 + 1.239 + new HiddenOption(false) { 1.240 + boolean matches(String opt) { 1.241 + return opt.startsWith("-XD"); 1.242 + } 1.243 + void process(JavahTask task, String opt, String arg) { 1.244 + task.javac_extras.add(opt); 1.245 + } 1.246 + }, 1.247 + }; 1.248 + 1.249 + JavahTask() { 1.250 + } 1.251 + 1.252 + JavahTask(Writer out, 1.253 + JavaFileManager fileManager, 1.254 + DiagnosticListener<? super JavaFileObject> diagnosticListener, 1.255 + Iterable<String> options, 1.256 + Iterable<String> classes) { 1.257 + this(); 1.258 + this.log = getPrintWriterForWriter(out); 1.259 + this.fileManager = fileManager; 1.260 + this.diagnosticListener = diagnosticListener; 1.261 + 1.262 + try { 1.263 + handleOptions(options, false); 1.264 + } catch (BadArgs e) { 1.265 + throw new IllegalArgumentException(e.getMessage()); 1.266 + } 1.267 + 1.268 + this.classes = new ArrayList<String>(); 1.269 + if (classes != null) { 1.270 + for (String classname: classes) { 1.271 + classname.getClass(); // null-check 1.272 + this.classes.add(classname); 1.273 + } 1.274 + } 1.275 + } 1.276 + 1.277 + public void setLocale(Locale locale) { 1.278 + if (locale == null) 1.279 + locale = Locale.getDefault(); 1.280 + task_locale = locale; 1.281 + } 1.282 + 1.283 + public void setLog(PrintWriter log) { 1.284 + this.log = log; 1.285 + } 1.286 + 1.287 + public void setLog(OutputStream s) { 1.288 + setLog(getPrintWriterForStream(s)); 1.289 + } 1.290 + 1.291 + static PrintWriter getPrintWriterForStream(OutputStream s) { 1.292 + return new PrintWriter(s, true); 1.293 + } 1.294 + 1.295 + static PrintWriter getPrintWriterForWriter(Writer w) { 1.296 + if (w == null) 1.297 + return getPrintWriterForStream(null); 1.298 + else if (w instanceof PrintWriter) 1.299 + return (PrintWriter) w; 1.300 + else 1.301 + return new PrintWriter(w, true); 1.302 + } 1.303 + 1.304 + public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) { 1.305 + diagnosticListener = dl; 1.306 + } 1.307 + 1.308 + public void setDiagnosticListener(OutputStream s) { 1.309 + setDiagnosticListener(getDiagnosticListenerForStream(s)); 1.310 + } 1.311 + 1.312 + private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) { 1.313 + return getDiagnosticListenerForWriter(getPrintWriterForStream(s)); 1.314 + } 1.315 + 1.316 + private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) { 1.317 + final PrintWriter pw = getPrintWriterForWriter(w); 1.318 + return new DiagnosticListener<JavaFileObject> () { 1.319 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 1.320 + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 1.321 + pw.print(getMessage("err.prefix")); 1.322 + pw.print(" "); 1.323 + } 1.324 + pw.println(diagnostic.getMessage(null)); 1.325 + } 1.326 + }; 1.327 + } 1.328 + 1.329 + int run(String[] args) { 1.330 + try { 1.331 + handleOptions(args); 1.332 + boolean ok = run(); 1.333 + return ok ? 0 : 1; 1.334 + } catch (BadArgs e) { 1.335 + diagnosticListener.report(createDiagnostic(e.key, e.args)); 1.336 + return 1; 1.337 + } catch (InternalError e) { 1.338 + diagnosticListener.report(createDiagnostic("err.internal.error", e.getMessage())); 1.339 + return 1; 1.340 + } catch (Util.Exit e) { 1.341 + return e.exitValue; 1.342 + } finally { 1.343 + log.flush(); 1.344 + } 1.345 + } 1.346 + 1.347 + public void handleOptions(String[] args) throws BadArgs { 1.348 + handleOptions(Arrays.asList(args), true); 1.349 + } 1.350 + 1.351 + private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs { 1.352 + if (log == null) { 1.353 + log = getPrintWriterForStream(System.out); 1.354 + if (diagnosticListener == null) 1.355 + diagnosticListener = getDiagnosticListenerForStream(System.err); 1.356 + } else { 1.357 + if (diagnosticListener == null) 1.358 + diagnosticListener = getDiagnosticListenerForWriter(log); 1.359 + } 1.360 + 1.361 + if (fileManager == null) 1.362 + fileManager = getDefaultFileManager(diagnosticListener, log); 1.363 + 1.364 + Iterator<String> iter = expandAtArgs(args).iterator(); 1.365 + noArgs = !iter.hasNext(); 1.366 + 1.367 + while (iter.hasNext()) { 1.368 + String arg = iter.next(); 1.369 + if (arg.startsWith("-")) 1.370 + handleOption(arg, iter); 1.371 + else if (allowClasses) { 1.372 + if (classes == null) 1.373 + classes = new ArrayList<String>(); 1.374 + classes.add(arg); 1.375 + while (iter.hasNext()) 1.376 + classes.add(iter.next()); 1.377 + } else 1.378 + throw new BadArgs("err.unknown.option", arg).showUsage(true); 1.379 + } 1.380 + 1.381 + if ((classes == null || classes.size() == 0) && 1.382 + !(noArgs || help || version || fullVersion)) { 1.383 + throw new BadArgs("err.no.classes.specified"); 1.384 + } 1.385 + 1.386 + if (jni && llni) 1.387 + throw new BadArgs("jni.llni.mixed"); 1.388 + 1.389 + if (odir != null && ofile != null) 1.390 + throw new BadArgs("dir.file.mixed"); 1.391 + } 1.392 + 1.393 + private void handleOption(String name, Iterator<String> rest) throws BadArgs { 1.394 + for (Option o: recognizedOptions) { 1.395 + if (o.matches(name)) { 1.396 + if (o.hasArg) { 1.397 + if (rest.hasNext()) 1.398 + o.process(this, name, rest.next()); 1.399 + else 1.400 + throw new BadArgs("err.missing.arg", name).showUsage(true); 1.401 + } else 1.402 + o.process(this, name, null); 1.403 + 1.404 + if (o.ignoreRest()) { 1.405 + while (rest.hasNext()) 1.406 + rest.next(); 1.407 + } 1.408 + return; 1.409 + } 1.410 + } 1.411 + 1.412 + if (fileManager.handleOption(name, rest)) 1.413 + return; 1.414 + 1.415 + throw new BadArgs("err.unknown.option", name).showUsage(true); 1.416 + } 1.417 + 1.418 + private Iterable<String> expandAtArgs(Iterable<String> args) throws BadArgs { 1.419 + try { 1.420 + List<String> l = new ArrayList<String>(); 1.421 + for (String arg: args) l.add(arg); 1.422 + return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()]))); 1.423 + } catch (FileNotFoundException e) { 1.424 + throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage()); 1.425 + } catch (IOException e) { 1.426 + throw new BadArgs("at.args.io.exception", e.getLocalizedMessage()); 1.427 + } 1.428 + } 1.429 + 1.430 + public Boolean call() { 1.431 + return run(); 1.432 + } 1.433 + 1.434 + public boolean run() throws Util.Exit { 1.435 + 1.436 + Util util = new Util(log, diagnosticListener); 1.437 + 1.438 + if (noArgs || help) { 1.439 + showHelp(); 1.440 + return help; // treat noArgs as an error for purposes of exit code 1.441 + } 1.442 + 1.443 + if (version || fullVersion) { 1.444 + showVersion(fullVersion); 1.445 + return true; 1.446 + } 1.447 + 1.448 + util.verbose = verbose; 1.449 + 1.450 + Gen g; 1.451 + 1.452 + if (llni) 1.453 + g = new LLNI(doubleAlign, util); 1.454 + else { 1.455 +// if (stubs) 1.456 +// throw new BadArgs("jni.no.stubs"); 1.457 + g = new JNI(util); 1.458 + } 1.459 + 1.460 + if (ofile != null) { 1.461 + if (!(fileManager instanceof StandardJavaFileManager)) { 1.462 + diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-o")); 1.463 + return false; 1.464 + } 1.465 + Iterable<? extends JavaFileObject> iter = 1.466 + ((StandardJavaFileManager) fileManager).getJavaFileObjectsFromFiles(Collections.singleton(ofile)); 1.467 + JavaFileObject fo = iter.iterator().next(); 1.468 + g.setOutFile(fo); 1.469 + } else { 1.470 + if (odir != null) { 1.471 + if (!(fileManager instanceof StandardJavaFileManager)) { 1.472 + diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-d")); 1.473 + return false; 1.474 + } 1.475 + 1.476 + if (!odir.exists()) 1.477 + if (!odir.mkdirs()) 1.478 + util.error("cant.create.dir", odir.toString()); 1.479 + try { 1.480 + ((StandardJavaFileManager) fileManager).setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(odir)); 1.481 + } catch (IOException e) { 1.482 + Object msg = e.getLocalizedMessage(); 1.483 + if (msg == null) { 1.484 + msg = e; 1.485 + } 1.486 + diagnosticListener.report(createDiagnostic("err.ioerror", odir, msg)); 1.487 + return false; 1.488 + } 1.489 + } 1.490 + g.setFileManager(fileManager); 1.491 + } 1.492 + 1.493 + /* 1.494 + * Force set to false will turn off smarts about checking file 1.495 + * content before writing. 1.496 + */ 1.497 + g.setForce(force); 1.498 + 1.499 + if (fileManager instanceof JavahFileManager) 1.500 + ((JavahFileManager) fileManager).setSymbolFileEnabled(false); 1.501 + 1.502 + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); 1.503 + List<String> opts = new ArrayList<String>(); 1.504 + opts.add("-proc:only"); 1.505 + opts.addAll(javac_extras); 1.506 + CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null); 1.507 + JavahProcessor p = new JavahProcessor(g); 1.508 + t.setProcessors(Collections.singleton(p)); 1.509 + 1.510 + boolean ok = t.call(); 1.511 + if (p.exit != null) 1.512 + throw new Util.Exit(p.exit); 1.513 + return ok; 1.514 + } 1.515 + 1.516 + private List<File> pathToFiles(String path) { 1.517 + List<File> files = new ArrayList<File>(); 1.518 + for (String f: path.split(File.pathSeparator)) { 1.519 + if (f.length() > 0) 1.520 + files.add(new File(f)); 1.521 + } 1.522 + return files; 1.523 + } 1.524 + 1.525 + static StandardJavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) { 1.526 + return JavahFileManager.create(dl, log); 1.527 + } 1.528 + 1.529 + private void showHelp() { 1.530 + log.println(getMessage("main.usage", progname)); 1.531 + for (Option o: recognizedOptions) { 1.532 + if (o.isHidden()) 1.533 + continue; 1.534 + String name = o.aliases[0].substring(1); // there must always be at least one name 1.535 + log.println(getMessage("main.opt." + name)); 1.536 + } 1.537 + String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" }; 1.538 + for (String o: fmOptions) { 1.539 + if (fileManager.isSupportedOption(o) == -1) 1.540 + continue; 1.541 + String name = o.substring(1); 1.542 + log.println(getMessage("main.opt." + name)); 1.543 + } 1.544 + log.println(getMessage("main.usage.foot")); 1.545 + } 1.546 + 1.547 + private void showVersion(boolean full) { 1.548 + log.println(version(full)); 1.549 + } 1.550 + 1.551 + private static final String versionRBName = "com.sun.tools.javah.resources.version"; 1.552 + private static ResourceBundle versionRB; 1.553 + 1.554 + private String version(boolean full) { 1.555 + String msgKey = (full ? "javah.fullVersion" : "javah.version"); 1.556 + String versionKey = (full ? "full" : "release"); 1.557 + // versionKey=product: mm.nn.oo[-milestone] 1.558 + // versionKey=full: mm.mm.oo[-milestone]-build 1.559 + if (versionRB == null) { 1.560 + try { 1.561 + versionRB = ResourceBundle.getBundle(versionRBName); 1.562 + } catch (MissingResourceException e) { 1.563 + return getMessage("version.resource.missing", System.getProperty("java.version")); 1.564 + } 1.565 + } 1.566 + try { 1.567 + return getMessage(msgKey, "javah", versionRB.getString(versionKey)); 1.568 + } 1.569 + catch (MissingResourceException e) { 1.570 + return getMessage("version.unknown", System.getProperty("java.version")); 1.571 + } 1.572 + } 1.573 + 1.574 + private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) { 1.575 + return new Diagnostic<JavaFileObject>() { 1.576 + public Kind getKind() { 1.577 + return Diagnostic.Kind.ERROR; 1.578 + } 1.579 + 1.580 + public JavaFileObject getSource() { 1.581 + return null; 1.582 + } 1.583 + 1.584 + public long getPosition() { 1.585 + return Diagnostic.NOPOS; 1.586 + } 1.587 + 1.588 + public long getStartPosition() { 1.589 + return Diagnostic.NOPOS; 1.590 + } 1.591 + 1.592 + public long getEndPosition() { 1.593 + return Diagnostic.NOPOS; 1.594 + } 1.595 + 1.596 + public long getLineNumber() { 1.597 + return Diagnostic.NOPOS; 1.598 + } 1.599 + 1.600 + public long getColumnNumber() { 1.601 + return Diagnostic.NOPOS; 1.602 + } 1.603 + 1.604 + public String getCode() { 1.605 + return key; 1.606 + } 1.607 + 1.608 + public String getMessage(Locale locale) { 1.609 + return JavahTask.this.getMessage(locale, key, args); 1.610 + } 1.611 + 1.612 + }; 1.613 + } 1.614 + 1.615 + private String getMessage(String key, Object... args) { 1.616 + return getMessage(task_locale, key, args); 1.617 + } 1.618 + 1.619 + private String getMessage(Locale locale, String key, Object... args) { 1.620 + if (bundles == null) { 1.621 + // could make this a HashMap<Locale,SoftReference<ResourceBundle>> 1.622 + // and for efficiency, keep a hard reference to the bundle for the task 1.623 + // locale 1.624 + bundles = new HashMap<Locale, ResourceBundle>(); 1.625 + } 1.626 + 1.627 + if (locale == null) 1.628 + locale = Locale.getDefault(); 1.629 + 1.630 + ResourceBundle b = bundles.get(locale); 1.631 + if (b == null) { 1.632 + try { 1.633 + b = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n", locale); 1.634 + bundles.put(locale, b); 1.635 + } catch (MissingResourceException e) { 1.636 + throw new InternalError("Cannot find javah resource bundle for locale " + locale, e); 1.637 + } 1.638 + } 1.639 + 1.640 + try { 1.641 + return MessageFormat.format(b.getString(key), args); 1.642 + } catch (MissingResourceException e) { 1.643 + return key; 1.644 + //throw new InternalError(e, key); 1.645 + } 1.646 + } 1.647 + 1.648 + File ofile; 1.649 + File odir; 1.650 + String bootcp; 1.651 + String usercp; 1.652 + List<String> classes; 1.653 + boolean verbose; 1.654 + boolean noArgs; 1.655 + boolean help; 1.656 + boolean trace; 1.657 + boolean version; 1.658 + boolean fullVersion; 1.659 + boolean jni; 1.660 + boolean llni; 1.661 + boolean doubleAlign; 1.662 + boolean force; 1.663 + Set<String> javac_extras = new LinkedHashSet<String>(); 1.664 + 1.665 + PrintWriter log; 1.666 + JavaFileManager fileManager; 1.667 + DiagnosticListener<? super JavaFileObject> diagnosticListener; 1.668 + Locale task_locale; 1.669 + Map<Locale, ResourceBundle> bundles; 1.670 + 1.671 + private static final String progname = "javah"; 1.672 + 1.673 + @SupportedAnnotationTypes("*") 1.674 + class JavahProcessor extends AbstractProcessor { 1.675 + private Messager messager; 1.676 + 1.677 + JavahProcessor(Gen g) { 1.678 + this.g = g; 1.679 + } 1.680 + 1.681 + @Override 1.682 + public SourceVersion getSupportedSourceVersion() { 1.683 + // since this is co-bundled with javac, we can assume it supports 1.684 + // the latest source version 1.685 + return SourceVersion.latest(); 1.686 + } 1.687 + 1.688 + @Override 1.689 + public void init(ProcessingEnvironment pEnv) { 1.690 + super.init(pEnv); 1.691 + messager = processingEnv.getMessager(); 1.692 + } 1.693 + 1.694 + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 1.695 + try { 1.696 + Set<TypeElement> classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements())); 1.697 + if (classes.size() > 0) { 1.698 + checkMethodParameters(classes); 1.699 + g.setProcessingEnvironment(processingEnv); 1.700 + g.setClasses(classes); 1.701 + g.run(); 1.702 + } 1.703 + } catch (CompletionFailure cf) { 1.704 + messager.printMessage(ERROR, getMessage("class.not.found", cf.sym.getQualifiedName().toString())); 1.705 + } catch (ClassNotFoundException cnfe) { 1.706 + messager.printMessage(ERROR, getMessage("class.not.found", cnfe.getMessage())); 1.707 + } catch (IOException ioe) { 1.708 + messager.printMessage(ERROR, getMessage("io.exception", ioe.getMessage())); 1.709 + } catch (Util.Exit e) { 1.710 + exit = e; 1.711 + } 1.712 + 1.713 + return true; 1.714 + } 1.715 + 1.716 + private Set<TypeElement> getAllClasses(Set<? extends TypeElement> classes) { 1.717 + Set<TypeElement> allClasses = new LinkedHashSet<TypeElement>(); 1.718 + getAllClasses0(classes, allClasses); 1.719 + return allClasses; 1.720 + } 1.721 + 1.722 + private void getAllClasses0(Iterable<? extends TypeElement> classes, Set<TypeElement> allClasses) { 1.723 + for (TypeElement c: classes) { 1.724 + allClasses.add(c); 1.725 + getAllClasses0(ElementFilter.typesIn(c.getEnclosedElements()), allClasses); 1.726 + } 1.727 + } 1.728 + 1.729 + // 4942232: 1.730 + // check that classes exist for all the parameters of native methods 1.731 + private void checkMethodParameters(Set<TypeElement> classes) { 1.732 + Types types = processingEnv.getTypeUtils(); 1.733 + for (TypeElement te: classes) { 1.734 + for (ExecutableElement ee: ElementFilter.methodsIn(te.getEnclosedElements())) { 1.735 + for (VariableElement ve: ee.getParameters()) { 1.736 + TypeMirror tm = ve.asType(); 1.737 + checkMethodParametersVisitor.visit(tm, types); 1.738 + } 1.739 + } 1.740 + } 1.741 + } 1.742 + 1.743 + private TypeVisitor<Void,Types> checkMethodParametersVisitor = 1.744 + new SimpleTypeVisitor8<Void,Types>() { 1.745 + @Override 1.746 + public Void visitArray(ArrayType t, Types types) { 1.747 + visit(t.getComponentType(), types); 1.748 + return null; 1.749 + } 1.750 + @Override 1.751 + public Void visitDeclared(DeclaredType t, Types types) { 1.752 + t.asElement().getKind(); // ensure class exists 1.753 + for (TypeMirror st: types.directSupertypes(t)) 1.754 + visit(st, types); 1.755 + return null; 1.756 + } 1.757 + }; 1.758 + 1.759 + private Gen g; 1.760 + private Util.Exit exit; 1.761 + } 1.762 +}