mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8294969: Convert jdk.jdeps javap to use the Classfile API
Reviewed-by: vromero
This commit is contained in:
parent
fbc766ee21
commit
1203e11a8d
29 changed files with 2012 additions and 2870 deletions
|
@ -67,7 +67,10 @@ import javax.tools.JavaFileObject;
|
|||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import jdk.internal.classfile.ClassModel;
|
||||
import jdk.internal.classfile.Classfile;
|
||||
import jdk.internal.classfile.constantpool.*;
|
||||
import static jdk.internal.classfile.Classfile.*;
|
||||
|
||||
/**
|
||||
* "Main" class for javap, normally accessed from the command line
|
||||
|
@ -166,7 +169,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
@Override
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.accessOptions.add(opt);
|
||||
task.options.showAccess = AccessFlags.ACC_PUBLIC;
|
||||
task.options.showAccess = ACC_PUBLIC;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -174,7 +177,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
@Override
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.accessOptions.add(opt);
|
||||
task.options.showAccess = AccessFlags.ACC_PROTECTED;
|
||||
task.options.showAccess = ACC_PROTECTED;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -193,7 +196,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
!task.options.accessOptions.contains("-private")) {
|
||||
task.options.accessOptions.add(opt);
|
||||
}
|
||||
task.options.showAccess = AccessFlags.ACC_PRIVATE;
|
||||
task.options.showAccess = ACC_PRIVATE;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -349,7 +352,6 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
context = new Context();
|
||||
context.put(Messages.class, this);
|
||||
options = Options.instance(context);
|
||||
attributeFactory = new Attribute.Factory();
|
||||
}
|
||||
|
||||
public JavapTask(Writer out,
|
||||
|
@ -633,7 +635,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
} catch (OutOfMemoryError e) {
|
||||
reportError("err.nomem");
|
||||
result = EXIT_ERROR;
|
||||
} catch (FatalError e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
Object msg = e.getLocalizedMessage();
|
||||
if (msg == null) {
|
||||
msg = e;
|
||||
|
@ -654,7 +656,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
}
|
||||
|
||||
protected int writeClass(ClassWriter classWriter, String className)
|
||||
throws IOException, ConstantPoolException {
|
||||
throws IOException {
|
||||
JavaFileObject fo = open(className);
|
||||
if (fo == null) {
|
||||
reportError("err.class.not.found", className);
|
||||
|
@ -663,34 +665,26 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
|
||||
ClassFileInfo cfInfo = read(fo);
|
||||
if (!className.endsWith(".class")) {
|
||||
if (cfInfo.cf.this_class == 0) {
|
||||
if (!className.equals("module-info")) {
|
||||
reportWarning("warn.unexpected.class", fo.getName(), className);
|
||||
}
|
||||
} else {
|
||||
String cfName = cfInfo.cf.getName();
|
||||
if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) {
|
||||
reportWarning("warn.unexpected.class", fo.getName(), className);
|
||||
}
|
||||
String cfName = cfInfo.cm.thisClass().asInternalName();
|
||||
if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) {
|
||||
reportWarning("warn.unexpected.class", fo.getName(), className);
|
||||
}
|
||||
}
|
||||
write(cfInfo);
|
||||
if (!write(cfInfo)) return EXIT_ERROR;
|
||||
|
||||
if (options.showInnerClasses) {
|
||||
ClassFile cf = cfInfo.cf;
|
||||
Attribute a = cf.getAttribute(Attribute.InnerClasses);
|
||||
if (a instanceof InnerClasses_attribute) {
|
||||
InnerClasses_attribute inners = (InnerClasses_attribute) a;
|
||||
ClassModel cm = cfInfo.cm;
|
||||
var a = cm.findAttribute(jdk.internal.classfile.Attributes.INNER_CLASSES);
|
||||
if (a.isPresent()) {
|
||||
var inners = a.get();
|
||||
try {
|
||||
int result = EXIT_OK;
|
||||
for (int i = 0; i < inners.classes.length; i++) {
|
||||
int outerIndex = inners.classes[i].outer_class_info_index;
|
||||
ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex);
|
||||
String outerClassName = outerClassInfo.getName();
|
||||
if (outerClassName.equals(cf.getName())) {
|
||||
int innerIndex = inners.classes[i].inner_class_info_index;
|
||||
ConstantPool.CONSTANT_Class_info innerClassInfo = cf.constant_pool.getClassInfo(innerIndex);
|
||||
String innerClassName = innerClassInfo.getName();
|
||||
for (var inner : inners.classes()) {
|
||||
var outerClassInfo = inner.outerClass();
|
||||
String outerClassName = outerClassInfo.map(ClassEntry::asInternalName).orElse(null);
|
||||
if (cm.thisClass().asInternalName().equals(outerClassName)) {
|
||||
var innerClassInfo = inner.innerClass();
|
||||
String innerClassName = innerClassInfo.asInternalName();
|
||||
classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", "."));
|
||||
classWriter.println();
|
||||
result = writeClass(classWriter, innerClassName);
|
||||
|
@ -698,13 +692,10 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
} catch (ConstantPoolException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
reportError("err.bad.innerclasses.attribute", className);
|
||||
return EXIT_ERROR;
|
||||
}
|
||||
} else if (a != null) {
|
||||
reportError("err.bad.innerclasses.attribute", className);
|
||||
return EXIT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -811,19 +802,19 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
}
|
||||
|
||||
public static class ClassFileInfo {
|
||||
ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
|
||||
ClassFileInfo(JavaFileObject fo, ClassModel cm, byte[] digest, int size) {
|
||||
this.fo = fo;
|
||||
this.cf = cf;
|
||||
this.cm = cm;
|
||||
this.digest = digest;
|
||||
this.size = size;
|
||||
}
|
||||
public final JavaFileObject fo;
|
||||
public final ClassFile cf;
|
||||
public final ClassModel cm;
|
||||
public final byte[] digest;
|
||||
public final int size;
|
||||
}
|
||||
|
||||
public ClassFileInfo read(JavaFileObject fo) throws IOException, ConstantPoolException {
|
||||
public ClassFileInfo read(JavaFileObject fo) throws IOException {
|
||||
InputStream in = fo.openInputStream();
|
||||
try {
|
||||
SizeInputStream sizeIn = null;
|
||||
|
@ -836,17 +827,16 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
in = new DigestInputStream(in, md);
|
||||
in = sizeIn = new SizeInputStream(in);
|
||||
}
|
||||
|
||||
ClassFile cf = ClassFile.read(in, attributeFactory);
|
||||
ClassModel cm = Classfile.of().parse(in.readAllBytes());
|
||||
byte[] digest = (md == null) ? null : md.digest();
|
||||
int size = (sizeIn == null) ? -1 : sizeIn.size();
|
||||
return new ClassFileInfo(fo, cf, digest, size);
|
||||
return new ClassFileInfo(fo, cm, digest, size);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void write(ClassFileInfo info) {
|
||||
public boolean write(ClassFileInfo info) {
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
if (options.sysInfo || options.verbose) {
|
||||
classWriter.setFile(info.fo.toUri());
|
||||
|
@ -855,56 +845,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
classWriter.setFileSize(info.size);
|
||||
}
|
||||
|
||||
classWriter.write(info.cf);
|
||||
}
|
||||
|
||||
protected void setClassFile(ClassFile classFile) {
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
classWriter.setClassFile(classFile);
|
||||
}
|
||||
|
||||
protected void setMethod(Method enclosingMethod) {
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
classWriter.setMethod(enclosingMethod);
|
||||
}
|
||||
|
||||
protected void write(Attribute value) {
|
||||
AttributeWriter attrWriter = AttributeWriter.instance(context);
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
ClassFile cf = classWriter.getClassFile();
|
||||
attrWriter.write(cf, value, cf.constant_pool);
|
||||
}
|
||||
|
||||
protected void write(Attributes attrs) {
|
||||
AttributeWriter attrWriter = AttributeWriter.instance(context);
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
ClassFile cf = classWriter.getClassFile();
|
||||
attrWriter.write(cf, attrs, cf.constant_pool);
|
||||
}
|
||||
|
||||
protected void write(ConstantPool constant_pool) {
|
||||
ConstantWriter constantWriter = ConstantWriter.instance(context);
|
||||
constantWriter.writeConstantPool(constant_pool);
|
||||
}
|
||||
|
||||
protected void write(ConstantPool constant_pool, int value) {
|
||||
ConstantWriter constantWriter = ConstantWriter.instance(context);
|
||||
constantWriter.write(value);
|
||||
}
|
||||
|
||||
protected void write(ConstantPool.CPInfo value) {
|
||||
ConstantWriter constantWriter = ConstantWriter.instance(context);
|
||||
constantWriter.println(value);
|
||||
}
|
||||
|
||||
protected void write(Field value) {
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
classWriter.writeField(value);
|
||||
}
|
||||
|
||||
protected void write(Method value) {
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
classWriter.writeMethod(value);
|
||||
return classWriter.write(info.cm);
|
||||
}
|
||||
|
||||
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
|
||||
|
@ -944,7 +885,8 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
if (result == null)
|
||||
result = l;
|
||||
else
|
||||
throw new IOException("multiple definitions found for " + moduleName);
|
||||
throw new IOException("multiple definitions found for "
|
||||
+ moduleName);
|
||||
}
|
||||
}
|
||||
if (result != null)
|
||||
|
@ -957,7 +899,8 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
private void showHelp() {
|
||||
printLines(getMessage("main.usage", progname));
|
||||
for (Option o: recognizedOptions) {
|
||||
String name = o.aliases[0].replaceAll("^-+", "").replaceAll("-+", "_"); // there must always be at least one name
|
||||
// there must always be at least one name
|
||||
String name = o.aliases[0].replaceAll("^-+", "").replaceAll("-+", "_");
|
||||
if (name.startsWith("X") || name.equals("fullversion"))
|
||||
continue;
|
||||
printLines(getMessage("main.opt." + name));
|
||||
|
@ -1000,7 +943,8 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
try {
|
||||
versionRB = ResourceBundle.getBundle(versionRBName);
|
||||
} catch (MissingResourceException e) {
|
||||
return getMessage("version.resource.missing", System.getProperty("java.version"));
|
||||
return getMessage("version.resource.missing",
|
||||
System.getProperty("java.version"));
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
@ -1064,7 +1008,8 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]";
|
||||
return getClass().getName() + "[key=" + key + ",args="
|
||||
+ Arrays.asList(args) + "]";
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -1089,10 +1034,12 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
ResourceBundle b = bundles.get(locale);
|
||||
if (b == null) {
|
||||
try {
|
||||
b = ResourceBundle.getBundle("com.sun.tools.javap.resources.javap", locale);
|
||||
b = ResourceBundle.getBundle("com.sun.tools.javap.resources.javap",
|
||||
locale);
|
||||
bundles.put(locale, b);
|
||||
} catch (MissingResourceException e) {
|
||||
throw new InternalError("Cannot find javap resource bundle for locale " + locale);
|
||||
throw new InternalError("Cannot find javap resource bundle for locale "
|
||||
+ locale);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1114,7 +1061,6 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||
//ResourceBundle bundle;
|
||||
Locale task_locale;
|
||||
Map<Locale, ResourceBundle> bundles;
|
||||
protected Attribute.Factory attributeFactory;
|
||||
|
||||
private static final String progname = "javap";
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue