/* * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package com.sun.tools.javap; import java.io.EOFException; import java.io.FileNotFoundException; import java.io.FilterInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.security.DigestInputStream; import java.security.MessageDigest; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import com.sun.tools.classfile.*; /** * "Main" class for javap, normally accessed from the command line * via Main, or from JSR199 via DisassemblerTool. * *
This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.
*/
public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
public class BadArgs extends Exception {
static final long serialVersionUID = 8765093759964640721L;
BadArgs(String key, Object... args) {
super(JavapTask.this.getMessage(key, args));
this.key = key;
this.args = args;
}
BadArgs showUsage(boolean b) {
showUsage = b;
return this;
}
final String key;
final Object[] args;
boolean showUsage;
}
static abstract class Option {
Option(boolean hasArg, String... aliases) {
this.hasArg = hasArg;
this.aliases = aliases;
}
boolean matches(String opt) {
for (String a: aliases) {
if (a.equals(opt))
return true;
}
return false;
}
boolean ignoreRest() {
return false;
}
abstract void process(JavapTask task, String opt, String arg) throws BadArgs;
final boolean hasArg;
final String[] aliases;
}
static Option[] recognizedOptions = {
new Option(false, "-help", "--help", "-?") {
void process(JavapTask task, String opt, String arg) {
task.options.help = true;
}
},
new Option(false, "-version") {
void process(JavapTask task, String opt, String arg) {
task.options.version = true;
}
},
new Option(false, "-fullversion") {
void process(JavapTask task, String opt, String arg) {
task.options.fullVersion = true;
}
},
new Option(false, "-v", "-verbose", "-all") {
void process(JavapTask task, String opt, String arg) {
task.options.verbose = true;
task.options.showFlags = true;
task.options.showAllAttrs = true;
}
},
new Option(false, "-l") {
void process(JavapTask task, String opt, String arg) {
task.options.showLineAndLocalVariableTables = true;
}
},
new Option(false, "-public") {
void process(JavapTask task, String opt, String arg) {
task.options.accessOptions.add(opt);
task.options.showAccess = AccessFlags.ACC_PUBLIC;
}
},
new Option(false, "-protected") {
void process(JavapTask task, String opt, String arg) {
task.options.accessOptions.add(opt);
task.options.showAccess = AccessFlags.ACC_PROTECTED;
}
},
new Option(false, "-package") {
void process(JavapTask task, String opt, String arg) {
task.options.accessOptions.add(opt);
task.options.showAccess = 0;
}
},
new Option(false, "-p", "-private") {
void process(JavapTask task, String opt, String arg) {
if (!task.options.accessOptions.contains("-p") &&
!task.options.accessOptions.contains("-private")) {
task.options.accessOptions.add(opt);
}
task.options.showAccess = AccessFlags.ACC_PRIVATE;
}
},
new Option(false, "-c") {
void process(JavapTask task, String opt, String arg) {
task.options.showDisassembled = true;
}
},
new Option(false, "-s") {
void process(JavapTask task, String opt, String arg) {
task.options.showInternalSignatures = true;
}
},
// new Option(false, "-all") {
// void process(JavapTask task, String opt, String arg) {
// task.options.showAllAttrs = true;
// }
// },
new Option(false, "-h") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
throw task.new BadArgs("err.h.not.supported");
}
},
new Option(false, "-verify", "-verify-verbose") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
throw task.new BadArgs("err.verify.not.supported");
}
},
new Option(false, "-sysinfo") {
void process(JavapTask task, String opt, String arg) {
task.options.sysInfo = true;
}
},
new Option(false, "-Xold") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
// -Xold is only supported as first arg when invoked from
// command line; this is handled in Main,main
throw task.new BadArgs("err.Xold.not.supported.here");
}
},
new Option(false, "-Xnew") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
// ignore: this _is_ the new version
}
},
new Option(false, "-XDcompat") {
void process(JavapTask task, String opt, String arg) {
task.options.compat = true;
}
},
new Option(false, "-XDjsr277") {
void process(JavapTask task, String opt, String arg) {
task.options.jsr277 = true;
}
},
new Option(false, "-XDignore.symbol.file") {
void process(JavapTask task, String opt, String arg) {
task.options.ignoreSymbolFile = true;
}
},
new Option(false, "-XDdetails") {
void process(JavapTask task, String opt, String arg) {
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
}
},
new Option(false, "-XDdetails:") {
@Override
boolean matches(String opt) {
int sep = opt.indexOf(":");
return sep != -1 && super.matches(opt.substring(0, sep + 1));
}
void process(JavapTask task, String opt, String arg) throws BadArgs {
int sep = opt.indexOf(":");
for (String v: opt.substring(sep + 1).split("[,: ]+")) {
if (!handleArg(task, v))
throw task.new BadArgs("err.invalid.arg.for.option", v);
}
}
boolean handleArg(JavapTask task, String arg) {
if (arg.length() == 0)
return true;
if (arg.equals("all")) {
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
return true;
}
boolean on = true;
if (arg.startsWith("-")) {
on = false;
arg = arg.substring(1);
}
for (InstructionDetailWriter.Kind k: InstructionDetailWriter.Kind.values()) {
if (arg.equalsIgnoreCase(k.option)) {
if (on)
task.options.details.add(k);
else
task.options.details.remove(k);
return true;
}
}
return false;
}
},
new Option(false, "-constants") {
void process(JavapTask task, String opt, String arg) {
task.options.showConstants = true;
}
}
};
JavapTask() {
context = new Context();
context.put(Messages.class, this);
options = Options.instance(context);
}
JavapTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener super JavaFileObject> diagnosticListener,
Iterable