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