feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,292 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Annotation;
import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.classfile.Annotation.Annotation_element_value;
import com.sun.tools.classfile.Annotation.Array_element_value;
import com.sun.tools.classfile.Annotation.Class_element_value;
import com.sun.tools.classfile.Annotation.Enum_element_value;
import com.sun.tools.classfile.Annotation.Primitive_element_value;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
/**
* A writer for writing annotations as text.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class AnnotationWriter extends BasicWriter {
static AnnotationWriter instance(Context context) {
AnnotationWriter instance = context.get(AnnotationWriter.class);
if (instance == null)
instance = new AnnotationWriter(context);
return instance;
}
protected AnnotationWriter(Context context) {
super(context);
classWriter = ClassWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
}
public void write(Annotation annot) {
write(annot, false);
}
public void write(Annotation annot, boolean resolveIndices) {
writeDescriptor(annot.type_index, resolveIndices);
boolean showParens = annot.num_element_value_pairs > 0 || !resolveIndices;
if (showParens)
print("(");
for (int i = 0; i < annot.num_element_value_pairs; i++) {
if (i > 0)
print(",");
write(annot.element_value_pairs[i], resolveIndices);
}
if (showParens)
print(")");
}
public void write(TypeAnnotation annot) {
write(annot, true, false);
}
public void write(TypeAnnotation annot, boolean showOffsets, boolean resolveIndices) {
write(annot.annotation, resolveIndices);
print(": ");
write(annot.position, showOffsets);
}
public void write(TypeAnnotation.Position pos, boolean showOffsets) {
print(pos.type);
switch (pos.type) {
// instanceof
case INSTANCEOF:
// new expression
case NEW:
// constructor/method reference receiver
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE:
if (showOffsets) {
print(", offset=");
print(pos.offset);
}
break;
// local variable
case LOCAL_VARIABLE:
// resource variable
case RESOURCE_VARIABLE:
if (pos.lvarOffset == null) {
print(", lvarOffset is Null!");
break;
}
print(", {");
for (int i = 0; i < pos.lvarOffset.length; ++i) {
if (i != 0) print("; ");
if (showOffsets) {
print("start_pc=");
print(pos.lvarOffset[i]);
}
print(", length=");
print(pos.lvarLength[i]);
print(", index=");
print(pos.lvarIndex[i]);
}
print("}");
break;
// exception parameter
case EXCEPTION_PARAMETER:
print(", exception_index=");
print(pos.exception_index);
break;
// method receiver
case METHOD_RECEIVER:
// Do nothing
break;
// type parameter
case CLASS_TYPE_PARAMETER:
case METHOD_TYPE_PARAMETER:
print(", param_index=");
print(pos.parameter_index);
break;
// type parameter bound
case CLASS_TYPE_PARAMETER_BOUND:
case METHOD_TYPE_PARAMETER_BOUND:
print(", param_index=");
print(pos.parameter_index);
print(", bound_index=");
print(pos.bound_index);
break;
// class extends or implements clause
case CLASS_EXTENDS:
print(", type_index=");
print(pos.type_index);
break;
// throws
case THROWS:
print(", type_index=");
print(pos.type_index);
break;
// method parameter
case METHOD_FORMAL_PARAMETER:
print(", param_index=");
print(pos.parameter_index);
break;
// type cast
case CAST:
// method/constructor/reference type argument
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT:
if (showOffsets) {
print(", offset=");
print(pos.offset);
}
print(", type_index=");
print(pos.type_index);
break;
// We don't need to worry about these
case METHOD_RETURN:
case FIELD:
break;
case UNKNOWN:
throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
default:
throw new AssertionError("AnnotationWriter: Unknown target type for position: " + pos);
}
// Append location data for generics/arrays.
if (!pos.location.isEmpty()) {
print(", location=");
print(pos.location);
}
}
public void write(Annotation.element_value_pair pair) {
write(pair, false);
}
public void write(Annotation.element_value_pair pair, boolean resolveIndices) {
writeIndex(pair.element_name_index, resolveIndices);
print("=");
write(pair.value, resolveIndices);
}
public void write(Annotation.element_value value) {
write(value, false);
}
public void write(Annotation.element_value value, boolean resolveIndices) {
ev_writer.write(value, resolveIndices);
}
private void writeDescriptor(int index, boolean resolveIndices) {
if (resolveIndices) {
try {
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
Descriptor d = new Descriptor(index);
print(d.getFieldType(constant_pool));
return;
} catch (ConstantPoolException ignore) {
} catch (InvalidDescriptor ignore) {
}
}
print("#" + index);
}
private void writeIndex(int index, boolean resolveIndices) {
if (resolveIndices) {
print(constantWriter.stringValue(index));
} else
print("#" + index);
}
element_value_Writer ev_writer = new element_value_Writer();
class element_value_Writer implements Annotation.element_value.Visitor<Void,Boolean> {
public void write(Annotation.element_value value, boolean resolveIndices) {
value.accept(this, resolveIndices);
}
public Void visitPrimitive(Primitive_element_value ev, Boolean resolveIndices) {
if (resolveIndices)
writeIndex(ev.const_value_index, resolveIndices);
else
print(((char) ev.tag) + "#" + ev.const_value_index);
return null;
}
public Void visitEnum(Enum_element_value ev, Boolean resolveIndices) {
if (resolveIndices) {
writeIndex(ev.type_name_index, resolveIndices);
print(".");
writeIndex(ev.const_name_index, resolveIndices);
} else
print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
return null;
}
public Void visitClass(Class_element_value ev, Boolean resolveIndices) {
if (resolveIndices) {
writeIndex(ev.class_info_index, resolveIndices);
print(".class");
} else
print(((char) ev.tag) + "#" + ev.class_info_index);
return null;
}
public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) {
print((char) ev.tag);
AnnotationWriter.this.write(ev.annotation_value, resolveIndices);
return null;
}
public Void visitArray(Array_element_value ev, Boolean resolveIndices) {
print("[");
for (int i = 0; i < ev.num_values; i++) {
if (i > 0)
print(",");
write(ev.values[i], resolveIndices);
}
print("]");
return null;
}
}
private ClassWriter classWriter;
private ConstantWriter constantWriter;
}

View File

@@ -0,0 +1,711 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.Formatter;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.AnnotationDefault_attribute;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.BootstrapMethods_attribute;
import com.sun.tools.classfile.CharacterRangeTable_attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.CompilationID_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantValue_attribute;
import com.sun.tools.classfile.DefaultAttribute;
import com.sun.tools.classfile.Deprecated_attribute;
import com.sun.tools.classfile.EnclosingMethod_attribute;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.InnerClasses_attribute;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
import com.sun.tools.classfile.MethodParameters_attribute;
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
import com.sun.tools.classfile.Signature_attribute;
import com.sun.tools.classfile.SourceDebugExtension_attribute;
import com.sun.tools.classfile.SourceFile_attribute;
import com.sun.tools.classfile.SourceID_attribute;
import com.sun.tools.classfile.StackMapTable_attribute;
import com.sun.tools.classfile.StackMap_attribute;
import com.sun.tools.classfile.Synthetic_attribute;
import static com.sun.tools.classfile.AccessFlags.*;
import com.sun.tools.javac.util.StringUtils;
/*
* A writer for writing Attributes as text.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class AttributeWriter extends BasicWriter
implements Attribute.Visitor<Void,Void>
{
public static AttributeWriter instance(Context context) {
AttributeWriter instance = context.get(AttributeWriter.class);
if (instance == null)
instance = new AttributeWriter(context);
return instance;
}
protected AttributeWriter(Context context) {
super(context);
context.put(AttributeWriter.class, this);
annotationWriter = AnnotationWriter.instance(context);
codeWriter = CodeWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
options = Options.instance(context);
}
public void write(Object owner, Attribute attr, ConstantPool constant_pool) {
if (attr != null) {
// null checks
owner.getClass();
constant_pool.getClass();
this.constant_pool = constant_pool;
this.owner = owner;
attr.accept(this, null);
}
}
public void write(Object owner, Attributes attrs, ConstantPool constant_pool) {
if (attrs != null) {
// null checks
owner.getClass();
constant_pool.getClass();
this.constant_pool = constant_pool;
this.owner = owner;
for (Attribute attr: attrs)
attr.accept(this, null);
}
}
public Void visitDefault(DefaultAttribute attr, Void ignore) {
if (attr.reason != null) {
report(attr.reason);
}
byte[] data = attr.info;
int i = 0;
int j = 0;
print(" ");
try {
print(attr.getName(constant_pool));
} catch (ConstantPoolException e) {
report(e);
print("attribute name = #" + attr.attribute_name_index);
}
print(": ");
println("length = 0x" + toHex(attr.info.length));
print(" ");
while (i < data.length) {
print(toHex(data[i], 2));
j++;
if (j == 16) {
println();
print(" ");
j = 0;
} else {
print(" ");
}
i++;
}
println();
return null;
}
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
println("AnnotationDefault:");
indent(+1);
print("default_value: ");
annotationWriter.write(attr.default_value);
indent(-1);
return null;
}
public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) {
println(Attribute.BootstrapMethods + ":");
for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) {
BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i];
indent(+1);
print(i + ": #" + bsm.bootstrap_method_ref + " ");
println(constantWriter.stringValue(bsm.bootstrap_method_ref));
indent(+1);
println("Method arguments:");
indent(+1);
for (int j = 0; j < bsm.bootstrap_arguments.length; j++) {
print("#" + bsm.bootstrap_arguments[j] + " ");
println(constantWriter.stringValue(bsm.bootstrap_arguments[j]));
}
indent(-3);
}
return null;
}
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
println("CharacterRangeTable:");
indent(+1);
for (int i = 0; i < attr.character_range_table.length; i++) {
CharacterRangeTable_attribute.Entry e = attr.character_range_table[i];
print(String.format(" %2d, %2d, %6x, %6x, %4x",
e.start_pc, e.end_pc,
e.character_range_start, e.character_range_end,
e.flags));
tab();
print(String.format("// %2d, %2d, %4d:%02d, %4d:%02d",
e.start_pc, e.end_pc,
(e.character_range_start >> 10), (e.character_range_start & 0x3ff),
(e.character_range_end >> 10), (e.character_range_end & 0x3ff)));
if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0)
print(", statement");
if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0)
print(", block");
if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0)
print(", assignment");
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0)
print(", flow-controller");
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0)
print(", flow-target");
if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0)
print(", invoke");
if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0)
print(", create");
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0)
print(", branch-true");
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
print(", branch-false");
println();
}
indent(-1);
return null;
}
public Void visitCode(Code_attribute attr, Void ignore) {
codeWriter.write(attr, constant_pool);
return null;
}
public Void visitCompilationID(CompilationID_attribute attr, Void ignore) {
constantWriter.write(attr.compilationID_index);
return null;
}
public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
print("ConstantValue: ");
constantWriter.write(attr.constantvalue_index);
println();
return null;
}
public Void visitDeprecated(Deprecated_attribute attr, Void ignore) {
println("Deprecated: true");
return null;
}
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) {
print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index);
tab();
print("// " + getJavaClassName(attr));
if (attr.method_index != 0)
print("." + getMethodName(attr));
println();
return null;
}
private String getJavaClassName(EnclosingMethod_attribute a) {
try {
return getJavaName(a.getClassName(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
}
}
private String getMethodName(EnclosingMethod_attribute a) {
try {
return a.getMethodName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
println("Exceptions:");
indent(+1);
print("throws ");
for (int i = 0; i < attr.number_of_exceptions; i++) {
if (i > 0)
print(", ");
print(getJavaException(attr, i));
}
println();
indent(-1);
return null;
}
private String getJavaException(Exceptions_attribute attr, int index) {
try {
return getJavaName(attr.getException(index, constant_pool));
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) {
boolean first = true;
for (int i = 0 ; i < attr.classes.length; i++) {
InnerClasses_attribute.Info info = attr.classes[i];
//access
AccessFlags access_flags = info.inner_class_access_flags;
if (options.checkAccess(access_flags)) {
if (first) {
writeInnerClassHeader();
first = false;
}
print(" ");
for (String name: access_flags.getInnerClassModifiers())
print(name + " ");
if (info.inner_name_index!=0) {
print("#" + info.inner_name_index + "= ");
}
print("#" + info.inner_class_info_index);
if (info.outer_class_info_index != 0) {
print(" of #" + info.outer_class_info_index);
}
print("; //");
if (info.inner_name_index != 0) {
print(getInnerName(constant_pool, info) + "=");
}
constantWriter.write(info.inner_class_info_index);
if (info.outer_class_info_index != 0) {
print(" of ");
constantWriter.write(info.outer_class_info_index);
}
println();
}
}
if (!first)
indent(-1);
return null;
}
String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) {
try {
return info.getInnerName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
private void writeInnerClassHeader() {
println("InnerClasses:");
indent(+1);
}
public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
println("LineNumberTable:");
indent(+1);
for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
println("line " + entry.line_number + ": " + entry.start_pc);
}
indent(-1);
return null;
}
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
println("LocalVariableTable:");
indent(+1);
println("Start Length Slot Name Signature");
for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) {
println(String.format("%5d %7d %5d %5s %s",
entry.start_pc, entry.length, entry.index,
constantWriter.stringValue(entry.name_index),
constantWriter.stringValue(entry.descriptor_index)));
}
indent(-1);
return null;
}
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
println("LocalVariableTypeTable:");
indent(+1);
println("Start Length Slot Name Signature");
for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) {
println(String.format("%5d %7d %5d %5s %s",
entry.start_pc, entry.length, entry.index,
constantWriter.stringValue(entry.name_index),
constantWriter.stringValue(entry.signature_index)));
}
indent(-1);
return null;
}
private static final String format = "%-31s%s";
public Void visitMethodParameters(MethodParameters_attribute attr,
Void ignore) {
final String header = String.format(format, "Name", "Flags");
println("MethodParameters:");
indent(+1);
println(header);
for (MethodParameters_attribute.Entry entry :
attr.method_parameter_table) {
String namestr =
entry.name_index != 0 ?
constantWriter.stringValue(entry.name_index) : "<no name>";
String flagstr =
(0 != (entry.flags & ACC_FINAL) ? "final " : "") +
(0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") +
(0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : "");
println(String.format(format, namestr, flagstr));
}
indent(-1);
return null;
}
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
println("RuntimeVisibleAnnotations:");
indent(+1);
for (int i = 0; i < attr.annotations.length; i++) {
print(i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
indent(-1);
return null;
}
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
println("RuntimeInvisibleAnnotations:");
indent(+1);
for (int i = 0; i < attr.annotations.length; i++) {
print(i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
indent(-1);
return null;
}
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
println("RuntimeVisibleTypeAnnotations:");
indent(+1);
for (int i = 0; i < attr.annotations.length; i++) {
print(i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
indent(-1);
return null;
}
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
println("RuntimeInvisibleTypeAnnotations:");
indent(+1);
for (int i = 0; i < attr.annotations.length; i++) {
print(i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
indent(-1);
return null;
}
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
println("RuntimeVisibleParameterAnnotations:");
indent(+1);
for (int param = 0; param < attr.parameter_annotations.length; param++) {
println("parameter " + param + ": ");
indent(+1);
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
print(i + ": ");
annotationWriter.write(attr.parameter_annotations[param][i]);
println();
}
indent(-1);
}
indent(-1);
return null;
}
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) {
println("RuntimeInvisibleParameterAnnotations:");
indent(+1);
for (int param = 0; param < attr.parameter_annotations.length; param++) {
println(param + ": ");
indent(+1);
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
print(i + ": ");
annotationWriter.write(attr.parameter_annotations[param][i]);
println();
}
indent(-1);
}
indent(-1);
return null;
}
public Void visitSignature(Signature_attribute attr, Void ignore) {
print("Signature: #" + attr.signature_index);
tab();
println("// " + getSignature(attr));
return null;
}
String getSignature(Signature_attribute info) {
try {
return info.getSignature(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
println("SourceDebugExtension:");
indent(+1);
for (String s: attr.getValue().split("[\r\n]+")) {
println(s);
}
indent(-1);
return null;
}
public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
println("SourceFile: \"" + getSourceFile(attr) + "\"");
return null;
}
private String getSourceFile(SourceFile_attribute attr) {
try {
return attr.getSourceFile(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitSourceID(SourceID_attribute attr, Void ignore) {
constantWriter.write(attr.sourceID_index);
return null;
}
public Void visitStackMap(StackMap_attribute attr, Void ignore) {
println("StackMap: number_of_entries = " + attr.number_of_entries);
indent(+1);
StackMapTableWriter w = new StackMapTableWriter();
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
w.write(entry);
}
indent(-1);
return null;
}
public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
println("StackMapTable: number_of_entries = " + attr.number_of_entries);
indent(+1);
StackMapTableWriter w = new StackMapTableWriter();
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
w.write(entry);
}
indent(-1);
return null;
}
class StackMapTableWriter // also handles CLDC StackMap attributes
implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> {
public void write(StackMapTable_attribute.stack_map_frame frame) {
frame.accept(this, null);
}
public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) {
printHeader(frame, "/* same */");
return null;
}
public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
printHeader(frame, "/* same_locals_1_stack_item */");
indent(+1);
printMap("stack", frame.stack);
indent(-1);
return null;
}
public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) {
printHeader(frame, "/* same_locals_1_stack_item_frame_extended */");
indent(+1);
println("offset_delta = " + frame.offset_delta);
printMap("stack", frame.stack);
indent(-1);
return null;
}
public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) {
printHeader(frame, "/* chop */");
indent(+1);
println("offset_delta = " + frame.offset_delta);
indent(-1);
return null;
}
public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) {
printHeader(frame, "/* same_frame_extended */");
indent(+1);
println("offset_delta = " + frame.offset_delta);
indent(-1);
return null;
}
public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) {
printHeader(frame, "/* append */");
indent(+1);
println("offset_delta = " + frame.offset_delta);
printMap("locals", frame.locals);
indent(-1);
return null;
}
public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) {
if (frame instanceof StackMap_attribute.stack_map_frame) {
printHeader(frame, "offset = " + frame.offset_delta);
indent(+1);
} else {
printHeader(frame, "/* full_frame */");
indent(+1);
println("offset_delta = " + frame.offset_delta);
}
printMap("locals", frame.locals);
printMap("stack", frame.stack);
indent(-1);
return null;
}
void printHeader(StackMapTable_attribute.stack_map_frame frame, String extra) {
print("frame_type = " + frame.frame_type + " ");
println(extra);
}
void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
print(name + " = [");
for (int i = 0; i < map.length; i++) {
StackMapTable_attribute.verification_type_info info = map[i];
int tag = info.tag;
switch (tag) {
case StackMapTable_attribute.verification_type_info.ITEM_Object:
print(" ");
constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index);
break;
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
print(" " + mapTypeName(tag));
print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset);
break;
default:
print(" " + mapTypeName(tag));
}
print(i == (map.length - 1) ? " " : ",");
}
println("]");
}
String mapTypeName(int tag) {
switch (tag) {
case StackMapTable_attribute.verification_type_info.ITEM_Top:
return "top";
case StackMapTable_attribute.verification_type_info.ITEM_Integer:
return "int";
case StackMapTable_attribute.verification_type_info.ITEM_Float:
return "float";
case StackMapTable_attribute.verification_type_info.ITEM_Long:
return "long";
case StackMapTable_attribute.verification_type_info.ITEM_Double:
return "double";
case StackMapTable_attribute.verification_type_info.ITEM_Null:
return "null";
case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis:
return "this";
case StackMapTable_attribute.verification_type_info.ITEM_Object:
return "CP";
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
return "uninitialized";
default:
report("unrecognized verification_type_info tag: " + tag);
return "[tag:" + tag + "]";
}
}
}
public Void visitSynthetic(Synthetic_attribute attr, Void ignore) {
println("Synthetic: true");
return null;
}
static String getJavaName(String name) {
return name.replace('/', '.');
}
String toHex(byte b, int w) {
return toHex(b & 0xff, w);
}
static String toHex(int i) {
return StringUtils.toUpperCase(Integer.toString(i, 16));
}
static String toHex(int i, int w) {
String s = StringUtils.toUpperCase(Integer.toHexString(i));
while (s.length() < w)
s = "0" + s;
return StringUtils.toUpperCase(s);
}
private AnnotationWriter annotationWriter;
private CodeWriter codeWriter;
private ConstantWriter constantWriter;
private Options options;
private ConstantPool constant_pool;
private Object owner;
}

View File

@@ -0,0 +1,205 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.io.PrintWriter;
import com.sun.tools.classfile.AttributeException;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.DescriptorException;
/*
* A writer similar to a PrintWriter but which does not hide exceptions.
* The standard print calls are line-buffered; report calls write messages directly.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class BasicWriter {
protected BasicWriter(Context context) {
lineWriter = LineWriter.instance(context);
out = context.get(PrintWriter.class);
messages = context.get(Messages.class);
if (messages == null)
throw new AssertionError();
}
protected void print(String s) {
lineWriter.print(s);
}
protected void print(Object o) {
lineWriter.print(o == null ? null : o.toString());
}
protected void println() {
lineWriter.println();
}
protected void println(String s) {
lineWriter.print(s);
lineWriter.println();
}
protected void println(Object o) {
lineWriter.print(o == null ? null : o.toString());
lineWriter.println();
}
protected void indent(int delta) {
lineWriter.indent(delta);
}
protected void tab() {
lineWriter.tab();
}
protected void setPendingNewline(boolean b) {
lineWriter.pendingNewline = b;
}
protected String report(AttributeException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(ConstantPoolException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(DescriptorException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(String msg) {
out.println("Error: " + msg); // i18n?
return "???";
}
protected String space(int w) {
if (w < spaces.length && spaces[w] != null)
return spaces[w];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < w; i++)
sb.append(" ");
String s = sb.toString();
if (w < spaces.length)
spaces[w] = s;
return s;
}
private String[] spaces = new String[80];
private LineWriter lineWriter;
private PrintWriter out;
protected Messages messages;
private static class LineWriter {
static LineWriter instance(Context context) {
LineWriter instance = context.get(LineWriter.class);
if (instance == null)
instance = new LineWriter(context);
return instance;
}
protected LineWriter(Context context) {
context.put(LineWriter.class, this);
Options options = Options.instance(context);
indentWidth = options.indentWidth;
tabColumn = options.tabColumn;
out = context.get(PrintWriter.class);
buffer = new StringBuilder();
}
protected void print(String s) {
if (pendingNewline) {
println();
pendingNewline = false;
}
if (s == null)
s = "null";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case ' ':
pendingSpaces++;
break;
case '\n':
println();
break;
default:
if (buffer.length() == 0)
indent();
if (pendingSpaces > 0) {
for (int sp = 0; sp < pendingSpaces; sp++)
buffer.append(' ');
pendingSpaces = 0;
}
buffer.append(c);
}
}
}
protected void println() {
// ignore/discard pending spaces
pendingSpaces = 0;
out.println(buffer);
buffer.setLength(0);
}
protected void indent(int delta) {
indentCount += delta;
}
protected void tab() {
int col = indentCount * indentWidth + tabColumn;
pendingSpaces += (col <= buffer.length() ? 1 : col - buffer.length());
}
private void indent() {
pendingSpaces += (indentCount * indentWidth);
}
private final PrintWriter out;
private final StringBuilder buffer;
private int indentCount;
private final int indentWidth;
private final int tabColumn;
private boolean pendingNewline;
private int pendingSpaces;
}
}

View File

@@ -0,0 +1,756 @@
/*
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.net.URI;
import java.text.DateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantValue_attribute;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.DescriptorException;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Signature;
import com.sun.tools.classfile.Signature_attribute;
import com.sun.tools.classfile.SourceFile_attribute;
import com.sun.tools.classfile.Type;
import com.sun.tools.classfile.Type.ArrayType;
import com.sun.tools.classfile.Type.ClassSigType;
import com.sun.tools.classfile.Type.ClassType;
import com.sun.tools.classfile.Type.MethodType;
import com.sun.tools.classfile.Type.SimpleType;
import com.sun.tools.classfile.Type.TypeParamType;
import com.sun.tools.classfile.Type.WildcardType;
import static com.sun.tools.classfile.AccessFlags.*;
/*
* The main javap class to write the contents of a class file as text.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class ClassWriter extends BasicWriter {
static ClassWriter instance(Context context) {
ClassWriter instance = context.get(ClassWriter.class);
if (instance == null)
instance = new ClassWriter(context);
return instance;
}
protected ClassWriter(Context context) {
super(context);
context.put(ClassWriter.class, this);
options = Options.instance(context);
attrWriter = AttributeWriter.instance(context);
codeWriter = CodeWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
}
void setDigest(String name, byte[] digest) {
this.digestName = name;
this.digest = digest;
}
void setFile(URI uri) {
this.uri = uri;
}
void setFileSize(int size) {
this.size = size;
}
void setLastModified(long lastModified) {
this.lastModified = lastModified;
}
protected ClassFile getClassFile() {
return classFile;
}
protected void setClassFile(ClassFile cf) {
classFile = cf;
constant_pool = classFile.constant_pool;
}
protected Method getMethod() {
return method;
}
protected void setMethod(Method m) {
method = m;
}
public void write(ClassFile cf) {
setClassFile(cf);
if (options.sysInfo || options.verbose) {
if (uri != null) {
if (uri.getScheme().equals("file"))
println("Classfile " + uri.getPath());
else
println("Classfile " + uri);
}
indent(+1);
if (lastModified != -1) {
Date lm = new Date(lastModified);
DateFormat df = DateFormat.getDateInstance();
if (size > 0) {
println("Last modified " + df.format(lm) + "; size " + size + " bytes");
} else {
println("Last modified " + df.format(lm));
}
} else if (size > 0) {
println("Size " + size + " bytes");
}
if (digestName != null && digest != null) {
StringBuilder sb = new StringBuilder();
for (byte b: digest)
sb.append(String.format("%02x", b));
println(digestName + " checksum " + sb);
}
}
Attribute sfa = cf.getAttribute(Attribute.SourceFile);
if (sfa instanceof SourceFile_attribute) {
println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
}
if (options.sysInfo || options.verbose) {
indent(-1);
}
String name = getJavaName(classFile);
AccessFlags flags = cf.access_flags;
writeModifiers(flags.getClassModifiers());
if (classFile.isClass())
print("class ");
else if (classFile.isInterface())
print("interface ");
print(name);
Signature_attribute sigAttr = getSignature(cf.attributes);
if (sigAttr == null) {
// use info from class file header
if (classFile.isClass() && classFile.super_class != 0 ) {
String sn = getJavaSuperclassName(cf);
if (!sn.equals("java.lang.Object")) {
print(" extends ");
print(sn);
}
}
for (int i = 0; i < classFile.interfaces.length; i++) {
print(i == 0 ? (classFile.isClass() ? " implements " : " extends ") : ",");
print(getJavaInterfaceName(classFile, i));
}
} else {
try {
Type t = sigAttr.getParsedSignature().getType(constant_pool);
JavaTypePrinter p = new JavaTypePrinter(classFile.isInterface());
// The signature parser cannot disambiguate between a
// FieldType and a ClassSignatureType that only contains a superclass type.
if (t instanceof Type.ClassSigType) {
print(p.print(t));
} else if (options.verbose || !t.isObject()) {
print(" extends ");
print(p.print(t));
}
} catch (ConstantPoolException e) {
print(report(e));
}
}
if (options.verbose) {
println();
indent(+1);
println("minor version: " + cf.minor_version);
println("major version: " + cf.major_version);
writeList("flags: ", flags.getClassFlags(), "\n");
indent(-1);
constantWriter.writeConstantPool();
} else {
print(" ");
}
println("{");
indent(+1);
writeFields();
writeMethods();
indent(-1);
println("}");
if (options.verbose) {
attrWriter.write(cf, cf.attributes, constant_pool);
}
}
// where
class JavaTypePrinter implements Type.Visitor<StringBuilder,StringBuilder> {
boolean isInterface;
JavaTypePrinter(boolean isInterface) {
this.isInterface = isInterface;
}
String print(Type t) {
return t.accept(this, new StringBuilder()).toString();
}
String printTypeArgs(List<? extends TypeParamType> typeParamTypes) {
StringBuilder builder = new StringBuilder();
appendIfNotEmpty(builder, "<", typeParamTypes, "> ");
return builder.toString();
}
public StringBuilder visitSimpleType(SimpleType type, StringBuilder sb) {
sb.append(getJavaName(type.name));
return sb;
}
public StringBuilder visitArrayType(ArrayType type, StringBuilder sb) {
append(sb, type.elemType);
sb.append("[]");
return sb;
}
public StringBuilder visitMethodType(MethodType type, StringBuilder sb) {
appendIfNotEmpty(sb, "<", type.typeParamTypes, "> ");
append(sb, type.returnType);
append(sb, " (", type.paramTypes, ")");
appendIfNotEmpty(sb, " throws ", type.throwsTypes, "");
return sb;
}
public StringBuilder visitClassSigType(ClassSigType type, StringBuilder sb) {
appendIfNotEmpty(sb, "<", type.typeParamTypes, ">");
if (isInterface) {
appendIfNotEmpty(sb, " extends ", type.superinterfaceTypes, "");
} else {
if (type.superclassType != null
&& (options.verbose || !type.superclassType.isObject())) {
sb.append(" extends ");
append(sb, type.superclassType);
}
appendIfNotEmpty(sb, " implements ", type.superinterfaceTypes, "");
}
return sb;
}
public StringBuilder visitClassType(ClassType type, StringBuilder sb) {
if (type.outerType != null) {
append(sb, type.outerType);
sb.append(".");
}
sb.append(getJavaName(type.name));
appendIfNotEmpty(sb, "<", type.typeArgs, ">");
return sb;
}
public StringBuilder visitTypeParamType(TypeParamType type, StringBuilder sb) {
sb.append(type.name);
String sep = " extends ";
if (type.classBound != null
&& (options.verbose || !type.classBound.isObject())) {
sb.append(sep);
append(sb, type.classBound);
sep = " & ";
}
if (type.interfaceBounds != null) {
for (Type bound: type.interfaceBounds) {
sb.append(sep);
append(sb, bound);
sep = " & ";
}
}
return sb;
}
public StringBuilder visitWildcardType(WildcardType type, StringBuilder sb) {
switch (type.kind) {
case UNBOUNDED:
sb.append("?");
break;
case EXTENDS:
sb.append("? extends ");
append(sb, type.boundType);
break;
case SUPER:
sb.append("? super ");
append(sb, type.boundType);
break;
default:
throw new AssertionError();
}
return sb;
}
private void append(StringBuilder sb, Type t) {
t.accept(this, sb);
}
private void append(StringBuilder sb, String prefix, List<? extends Type> list, String suffix) {
sb.append(prefix);
String sep = "";
for (Type t: list) {
sb.append(sep);
append(sb, t);
sep = ", ";
}
sb.append(suffix);
}
private void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> list, String suffix) {
if (!isEmpty(list))
append(sb, prefix, list, suffix);
}
private boolean isEmpty(List<? extends Type> list) {
return (list == null || list.isEmpty());
}
}
protected void writeFields() {
for (Field f: classFile.fields) {
writeField(f);
}
}
protected void writeField(Field f) {
if (!options.checkAccess(f.access_flags))
return;
AccessFlags flags = f.access_flags;
writeModifiers(flags.getFieldModifiers());
Signature_attribute sigAttr = getSignature(f.attributes);
if (sigAttr == null)
print(getJavaFieldType(f.descriptor));
else {
try {
Type t = sigAttr.getParsedSignature().getType(constant_pool);
print(getJavaName(t.toString()));
} catch (ConstantPoolException e) {
// report error?
// fall back on non-generic descriptor
print(getJavaFieldType(f.descriptor));
}
}
print(" ");
print(getFieldName(f));
if (options.showConstants) {
Attribute a = f.attributes.get(Attribute.ConstantValue);
if (a instanceof ConstantValue_attribute) {
print(" = ");
ConstantValue_attribute cv = (ConstantValue_attribute) a;
print(getConstantValue(f.descriptor, cv.constantvalue_index));
}
}
print(";");
println();
indent(+1);
boolean showBlank = false;
if (options.showDescriptors)
println("descriptor: " + getValue(f.descriptor));
if (options.verbose)
writeList("flags: ", flags.getFieldFlags(), "\n");
if (options.showAllAttrs) {
for (Attribute attr: f.attributes)
attrWriter.write(f, attr, constant_pool);
showBlank = true;
}
indent(-1);
if (showBlank || options.showDisassembled || options.showLineAndLocalVariableTables)
println();
}
protected void writeMethods() {
for (Method m: classFile.methods)
writeMethod(m);
setPendingNewline(false);
}
protected void writeMethod(Method m) {
if (!options.checkAccess(m.access_flags))
return;
method = m;
AccessFlags flags = m.access_flags;
Descriptor d;
Type.MethodType methodType;
List<? extends Type> methodExceptions;
Signature_attribute sigAttr = getSignature(m.attributes);
if (sigAttr == null) {
d = m.descriptor;
methodType = null;
methodExceptions = null;
} else {
Signature methodSig = sigAttr.getParsedSignature();
d = methodSig;
try {
methodType = (Type.MethodType) methodSig.getType(constant_pool);
methodExceptions = methodType.throwsTypes;
if (methodExceptions != null && methodExceptions.isEmpty())
methodExceptions = null;
} catch (ConstantPoolException e) {
// report error?
// fall back on standard descriptor
methodType = null;
methodExceptions = null;
}
}
writeModifiers(flags.getMethodModifiers());
if (methodType != null) {
print(new JavaTypePrinter(false).printTypeArgs(methodType.typeParamTypes));
}
if (getName(m).equals("<init>")) {
print(getJavaName(classFile));
print(getJavaParameterTypes(d, flags));
} else if (getName(m).equals("<clinit>")) {
print("{}");
} else {
print(getJavaReturnType(d));
print(" ");
print(getName(m));
print(getJavaParameterTypes(d, flags));
}
Attribute e_attr = m.attributes.get(Attribute.Exceptions);
if (e_attr != null) { // if there are generic exceptions, there must be erased exceptions
if (e_attr instanceof Exceptions_attribute) {
Exceptions_attribute exceptions = (Exceptions_attribute) e_attr;
print(" throws ");
if (methodExceptions != null) { // use generic list if available
writeList("", methodExceptions, "");
} else {
for (int i = 0; i < exceptions.number_of_exceptions; i++) {
if (i > 0)
print(", ");
print(getJavaException(exceptions, i));
}
}
} else {
report("Unexpected or invalid value for Exceptions attribute");
}
}
println(";");
indent(+1);
if (options.showDescriptors) {
println("descriptor: " + getValue(m.descriptor));
}
if (options.verbose) {
writeList("flags: ", flags.getMethodFlags(), "\n");
}
Code_attribute code = null;
Attribute c_attr = m.attributes.get(Attribute.Code);
if (c_attr != null) {
if (c_attr instanceof Code_attribute)
code = (Code_attribute) c_attr;
else
report("Unexpected or invalid value for Code attribute");
}
if (options.showAllAttrs) {
Attribute[] attrs = m.attributes.attrs;
for (Attribute attr: attrs)
attrWriter.write(m, attr, constant_pool);
} else if (code != null) {
if (options.showDisassembled) {
println("Code:");
codeWriter.writeInstrs(code);
codeWriter.writeExceptionTable(code);
}
if (options.showLineAndLocalVariableTables) {
attrWriter.write(code, code.attributes.get(Attribute.LineNumberTable), constant_pool);
attrWriter.write(code, code.attributes.get(Attribute.LocalVariableTable), constant_pool);
}
}
indent(-1);
// set pendingNewline to write a newline before the next method (if any)
// if a separator is desired
setPendingNewline(
options.showDisassembled ||
options.showAllAttrs ||
options.showDescriptors ||
options.showLineAndLocalVariableTables ||
options.verbose);
}
void writeModifiers(Collection<String> items) {
for (Object item: items) {
print(item);
print(" ");
}
}
void writeList(String prefix, Collection<?> items, String suffix) {
print(prefix);
String sep = "";
for (Object item: items) {
print(sep);
print(item);
sep = ", ";
}
print(suffix);
}
void writeListIfNotEmpty(String prefix, List<?> items, String suffix) {
if (items != null && items.size() > 0)
writeList(prefix, items, suffix);
}
Signature_attribute getSignature(Attributes attributes) {
return (Signature_attribute) attributes.get(Attribute.Signature);
}
String adjustVarargs(AccessFlags flags, String params) {
if (flags.is(ACC_VARARGS)) {
int i = params.lastIndexOf("[]");
if (i > 0)
return params.substring(0, i) + "..." + params.substring(i+2);
}
return params;
}
String getJavaName(ClassFile cf) {
try {
return getJavaName(cf.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getJavaSuperclassName(ClassFile cf) {
try {
return getJavaName(cf.getSuperclassName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getJavaInterfaceName(ClassFile cf, int index) {
try {
return getJavaName(cf.getInterfaceName(index));
} catch (ConstantPoolException e) {
return report(e);
}
}
String getJavaFieldType(Descriptor d) {
try {
return getJavaName(d.getFieldType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getJavaReturnType(Descriptor d) {
try {
return getJavaName(d.getReturnType(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getJavaParameterTypes(Descriptor d, AccessFlags flags) {
try {
return getJavaName(adjustVarargs(flags, d.getParameterTypes(constant_pool)));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getJavaException(Exceptions_attribute attr, int index) {
try {
return getJavaName(attr.getException(index, constant_pool));
} catch (ConstantPoolException e) {
return report(e);
}
}
String getValue(Descriptor d) {
try {
return d.getValue(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
String getFieldName(Field f) {
try {
return f.getName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
String getName(Method m) {
try {
return m.getName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
static String getJavaName(String name) {
return name.replace('/', '.');
}
String getSourceFile(SourceFile_attribute attr) {
try {
return attr.getSourceFile(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
/**
* Get the value of an entry in the constant pool as a Java constant.
* Characters and booleans are represented by CONSTANT_Intgere entries.
* Character and string values are processed to escape characters outside
* the basic printable ASCII set.
* @param d the descriptor, giving the expected type of the constant
* @param index the index of the value in the constant pool
* @return a printable string containing the value of the constant.
*/
String getConstantValue(Descriptor d, int index) {
try {
ConstantPool.CPInfo cpInfo = constant_pool.get(index);
switch (cpInfo.getTag()) {
case ConstantPool.CONSTANT_Integer: {
ConstantPool.CONSTANT_Integer_info info =
(ConstantPool.CONSTANT_Integer_info) cpInfo;
String t = d.getValue(constant_pool);
if (t.equals("C")) { // character
return getConstantCharValue((char) info.value);
} else if (t.equals("Z")) { // boolean
return String.valueOf(info.value == 1);
} else { // other: assume integer
return String.valueOf(info.value);
}
}
case ConstantPool.CONSTANT_String: {
ConstantPool.CONSTANT_String_info info =
(ConstantPool.CONSTANT_String_info) cpInfo;
return getConstantStringValue(info.getString());
}
default:
return constantWriter.stringValue(cpInfo);
}
} catch (ConstantPoolException e) {
return "#" + index;
}
}
private String getConstantCharValue(char c) {
StringBuilder sb = new StringBuilder();
sb.append('\'');
sb.append(esc(c, '\''));
sb.append('\'');
return sb.toString();
}
private String getConstantStringValue(String s) {
StringBuilder sb = new StringBuilder();
sb.append("\"");
for (int i = 0; i < s.length(); i++) {
sb.append(esc(s.charAt(i), '"'));
}
sb.append("\"");
return sb.toString();
}
private String esc(char c, char quote) {
if (32 <= c && c <= 126 && c != quote)
return String.valueOf(c);
else switch (c) {
case '\b': return "\\b";
case '\n': return "\\n";
case '\t': return "\\t";
case '\f': return "\\f";
case '\r': return "\\r";
case '\\': return "\\\\";
case '\'': return "\\'";
case '\"': return "\\\"";
default: return String.format("\\u%04x", (int) c);
}
}
private Options options;
private AttributeWriter attrWriter;
private CodeWriter codeWriter;
private ConstantWriter constantWriter;
private ClassFile classFile;
private URI uri;
private long lastModified;
private String digestName;
private byte[] digest;
private int size;
private ConstantPool constant_pool;
private Method method;
}

View File

@@ -0,0 +1,287 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.ArrayList;
import java.util.List;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.DescriptorException;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Instruction.TypeKind;
import com.sun.tools.classfile.Method;
/*
* Write the contents of a Code attribute.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class CodeWriter extends BasicWriter {
public static CodeWriter instance(Context context) {
CodeWriter instance = context.get(CodeWriter.class);
if (instance == null)
instance = new CodeWriter(context);
return instance;
}
protected CodeWriter(Context context) {
super(context);
context.put(CodeWriter.class, this);
attrWriter = AttributeWriter.instance(context);
classWriter = ClassWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
sourceWriter = SourceWriter.instance(context);
tryBlockWriter = TryBlockWriter.instance(context);
stackMapWriter = StackMapWriter.instance(context);
localVariableTableWriter = LocalVariableTableWriter.instance(context);
localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
typeAnnotationWriter = TypeAnnotationWriter.instance(context);
options = Options.instance(context);
}
void write(Code_attribute attr, ConstantPool constant_pool) {
println("Code:");
indent(+1);
writeVerboseHeader(attr, constant_pool);
writeInstrs(attr);
writeExceptionTable(attr);
attrWriter.write(attr, attr.attributes, constant_pool);
indent(-1);
}
public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
Method method = classWriter.getMethod();
String argCount;
try {
int n = method.descriptor.getParameterCount(constant_pool);
if (!method.access_flags.is(AccessFlags.ACC_STATIC))
++n; // for 'this'
argCount = Integer.toString(n);
} catch (ConstantPoolException e) {
argCount = report(e);
} catch (DescriptorException e) {
argCount = report(e);
}
println("stack=" + attr.max_stack +
", locals=" + attr.max_locals +
", args_size=" + argCount);
}
public void writeInstrs(Code_attribute attr) {
List<InstructionDetailWriter> detailWriters = getDetailWriters(attr);
for (Instruction instr: attr.getInstructions()) {
try {
for (InstructionDetailWriter w: detailWriters)
w.writeDetails(instr);
writeInstr(instr);
} catch (ArrayIndexOutOfBoundsException e) {
println(report("error at or after byte " + instr.getPC()));
break;
}
}
for (InstructionDetailWriter w: detailWriters)
w.flush();
}
public void writeInstr(Instruction instr) {
print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic()));
// compute the number of indentations for the body of multi-line instructions
// This is 6 (the width of "%4d: "), divided by the width of each indentation level,
// and rounded up to the next integer.
int indentWidth = options.indentWidth;
int indent = (6 + indentWidth - 1) / indentWidth;
instr.accept(instructionPrinter, indent);
println();
}
// where
Instruction.KindVisitor<Void,Integer> instructionPrinter =
new Instruction.KindVisitor<Void,Integer>() {
public Void visitNoOperands(Instruction instr, Integer indent) {
return null;
}
public Void visitArrayType(Instruction instr, TypeKind kind, Integer indent) {
print(" " + kind.name);
return null;
}
public Void visitBranch(Instruction instr, int offset, Integer indent) {
print((instr.getPC() + offset));
return null;
}
public Void visitConstantPoolRef(Instruction instr, int index, Integer indent) {
print("#" + index);
tab();
print("// ");
printConstant(index);
return null;
}
public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Integer indent) {
print("#" + index + ", " + value);
tab();
print("// ");
printConstant(index);
return null;
}
public Void visitLocal(Instruction instr, int index, Integer indent) {
print(index);
return null;
}
public Void visitLocalAndValue(Instruction instr, int index, int value, Integer indent) {
print(index + ", " + value);
return null;
}
public Void visitLookupSwitch(Instruction instr,
int default_, int npairs, int[] matches, int[] offsets, Integer indent) {
int pc = instr.getPC();
print("{ // " + npairs);
indent(indent);
for (int i = 0; i < npairs; i++) {
print(String.format("%n%12d: %d", matches[i], (pc + offsets[i])));
}
print("\n default: " + (pc + default_) + "\n}");
indent(-indent);
return null;
}
public Void visitTableSwitch(Instruction instr,
int default_, int low, int high, int[] offsets, Integer indent) {
int pc = instr.getPC();
print("{ // " + low + " to " + high);
indent(indent);
for (int i = 0; i < offsets.length; i++) {
print(String.format("%n%12d: %d", (low + i), (pc + offsets[i])));
}
print("\n default: " + (pc + default_) + "\n}");
indent(-indent);
return null;
}
public Void visitValue(Instruction instr, int value, Integer indent) {
print(value);
return null;
}
public Void visitUnknown(Instruction instr, Integer indent) {
return null;
}
};
public void writeExceptionTable(Code_attribute attr) {
if (attr.exception_table_length > 0) {
println("Exception table:");
indent(+1);
println(" from to target type");
for (int i = 0; i < attr.exception_table.length; i++) {
Code_attribute.Exception_data handler = attr.exception_table[i];
print(String.format(" %5d %5d %5d",
handler.start_pc, handler.end_pc, handler.handler_pc));
print(" ");
int catch_type = handler.catch_type;
if (catch_type == 0) {
println("any");
} else {
print("Class ");
println(constantWriter.stringValue(catch_type));
}
}
indent(-1);
}
}
private void printConstant(int index) {
constantWriter.write(index);
}
private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
List<InstructionDetailWriter> detailWriters =
new ArrayList<InstructionDetailWriter>();
if (options.details.contains(InstructionDetailWriter.Kind.SOURCE)) {
sourceWriter.reset(classWriter.getClassFile(), attr);
if (sourceWriter.hasSource())
detailWriters.add(sourceWriter);
else
println("(Source code not available)");
}
if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VARS)) {
localVariableTableWriter.reset(attr);
detailWriters.add(localVariableTableWriter);
}
if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VAR_TYPES)) {
localVariableTypeTableWriter.reset(attr);
detailWriters.add(localVariableTypeTableWriter);
}
if (options.details.contains(InstructionDetailWriter.Kind.STACKMAPS)) {
stackMapWriter.reset(attr);
stackMapWriter.writeInitialDetails();
detailWriters.add(stackMapWriter);
}
if (options.details.contains(InstructionDetailWriter.Kind.TRY_BLOCKS)) {
tryBlockWriter.reset(attr);
detailWriters.add(tryBlockWriter);
}
if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
typeAnnotationWriter.reset(attr);
detailWriters.add(typeAnnotationWriter);
}
return detailWriters;
}
private AttributeWriter attrWriter;
private ClassWriter classWriter;
private ConstantWriter constantWriter;
private LocalVariableTableWriter localVariableTableWriter;
private LocalVariableTypeTableWriter localVariableTypeTableWriter;
private TypeAnnotationWriter typeAnnotationWriter;
private SourceWriter sourceWriter;
private StackMapWriter stackMapWriter;
private TryBlockWriter tryBlockWriter;
private Options options;
}

View File

@@ -0,0 +1,454 @@
/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import static com.sun.tools.classfile.ConstantPool.*;
/*
* Write a constant pool entry.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class ConstantWriter extends BasicWriter {
public static ConstantWriter instance(Context context) {
ConstantWriter instance = context.get(ConstantWriter.class);
if (instance == null)
instance = new ConstantWriter(context);
return instance;
}
protected ConstantWriter(Context context) {
super(context);
context.put(ConstantWriter.class, this);
classWriter = ClassWriter.instance(context);
options = Options.instance(context);
}
protected void writeConstantPool() {
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
writeConstantPool(constant_pool);
}
protected void writeConstantPool(ConstantPool constant_pool) {
ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
public Integer visitClass(CONSTANT_Class_info info, Void p) {
print("#" + info.name_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitDouble(CONSTANT_Double_info info, Void p) {
println(stringValue(info));
return 2;
}
public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
print("#" + info.class_index + ".#" + info.name_and_type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitFloat(CONSTANT_Float_info info, Void p) {
println(stringValue(info));
return 1;
}
public Integer visitInteger(CONSTANT_Integer_info info, Void p) {
println(stringValue(info));
return 1;
}
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
print("#" + info.class_index + ".#" + info.name_and_type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
print("#" + info.bootstrap_method_attr_index + ":#" + info.name_and_type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitLong(CONSTANT_Long_info info, Void p) {
println(stringValue(info));
return 2;
}
public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
print("#" + info.name_index + ":#" + info.type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
print("#" + info.class_index + ".#" + info.name_and_type_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
print("#" + info.reference_kind.tag + ":#" + info.reference_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitMethodType(CONSTANT_MethodType_info info, Void p) {
print("#" + info.descriptor_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitString(CONSTANT_String_info info, Void p) {
print("#" + info.string_index);
tab();
println("// " + stringValue(info));
return 1;
}
public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) {
println(stringValue(info));
return 1;
}
};
println("Constant pool:");
indent(+1);
int width = String.valueOf(constant_pool.size()).length() + 1;
int cpx = 1;
while (cpx < constant_pool.size()) {
print(String.format("%" + width + "s", ("#" + cpx)));
try {
CPInfo cpInfo = constant_pool.get(cpx);
print(String.format(" = %-18s ", cpTagName(cpInfo)));
cpx += cpInfo.accept(v, null);
} catch (ConstantPool.InvalidIndex ex) {
// should not happen
}
}
indent(-1);
}
protected void write(int cpx) {
ClassFile classFile = classWriter.getClassFile();
if (cpx == 0) {
print("#0");
return;
}
CPInfo cpInfo;
try {
cpInfo = classFile.constant_pool.get(cpx);
} catch (ConstantPoolException e) {
print("#" + cpx);
return;
}
int tag = cpInfo.getTag();
switch (tag) {
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_Fieldref:
// simplify references within this class
CPRefInfo ref = (CPRefInfo) cpInfo;
try {
if (ref.class_index == classFile.this_class)
cpInfo = classFile.constant_pool.get(ref.name_and_type_index);
} catch (ConstantPool.InvalidIndex e) {
// ignore, for now
}
}
print(tagName(tag) + " " + stringValue(cpInfo));
}
String cpTagName(CPInfo cpInfo) {
String n = cpInfo.getClass().getSimpleName();
return n.replace("CONSTANT_", "").replace("_info", "");
}
String tagName(int tag) {
switch (tag) {
case CONSTANT_Utf8:
return "Utf8";
case CONSTANT_Integer:
return "int";
case CONSTANT_Float:
return "float";
case CONSTANT_Long:
return "long";
case CONSTANT_Double:
return "double";
case CONSTANT_Class:
return "class";
case CONSTANT_String:
return "String";
case CONSTANT_Fieldref:
return "Field";
case CONSTANT_MethodHandle:
return "MethodHandle";
case CONSTANT_MethodType:
return "MethodType";
case CONSTANT_Methodref:
return "Method";
case CONSTANT_InterfaceMethodref:
return "InterfaceMethod";
case CONSTANT_InvokeDynamic:
return "InvokeDynamic";
case CONSTANT_NameAndType:
return "NameAndType";
default:
return "(unknown tag " + tag + ")";
}
}
String stringValue(int constant_pool_index) {
ClassFile classFile = classWriter.getClassFile();
try {
return stringValue(classFile.constant_pool.get(constant_pool_index));
} catch (ConstantPool.InvalidIndex e) {
return report(e);
}
}
String stringValue(CPInfo cpInfo) {
return stringValueVisitor.visit(cpInfo);
}
StringValueVisitor stringValueVisitor = new StringValueVisitor();
private class StringValueVisitor implements ConstantPool.Visitor<String, Void> {
public String visit(CPInfo info) {
return info.accept(this, null);
}
public String visitClass(CONSTANT_Class_info info, Void p) {
return getCheckedName(info);
}
String getCheckedName(CONSTANT_Class_info info) {
try {
return checkName(info.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitDouble(CONSTANT_Double_info info, Void p) {
return info.value + "d";
}
public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
return visitRef(info, p);
}
public String visitFloat(CONSTANT_Float_info info, Void p) {
return info.value + "f";
}
public String visitInteger(CONSTANT_Integer_info info, Void p) {
return String.valueOf(info.value);
}
public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
return visitRef(info, p);
}
public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
try {
String callee = stringValue(info.getNameAndTypeInfo());
return "#" + info.bootstrap_method_attr_index + ":" + callee;
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitLong(CONSTANT_Long_info info, Void p) {
return info.value + "l";
}
public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
return getCheckedName(info) + ":" + getType(info);
}
String getCheckedName(CONSTANT_NameAndType_info info) {
try {
return checkName(info.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getType(CONSTANT_NameAndType_info info) {
try {
return info.getType();
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
try {
return info.reference_kind.name + " " + stringValue(info.getCPRefInfo());
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodType(CONSTANT_MethodType_info info, Void p) {
try {
return info.getType();
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
return visitRef(info, p);
}
public String visitString(CONSTANT_String_info info, Void p) {
try {
ClassFile classFile = classWriter.getClassFile();
int string_index = info.string_index;
return stringValue(classFile.constant_pool.getUTF8Info(string_index));
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
String s = info.value;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\t':
sb.append('\\').append('t');
break;
case '\n':
sb.append('\\').append('n');
break;
case '\r':
sb.append('\\').append('r');
break;
case '\"':
sb.append('\\').append('\"');
break;
default:
sb.append(c);
}
}
return sb.toString();
}
String visitRef(CPRefInfo info, Void p) {
String cn = getCheckedClassName(info);
String nat;
try {
nat = stringValue(info.getNameAndTypeInfo());
} catch (ConstantPoolException e) {
nat = report(e);
}
return cn + "." + nat;
}
String getCheckedClassName(CPRefInfo info) {
try {
return checkName(info.getClassName());
} catch (ConstantPoolException e) {
return report(e);
}
}
}
/* If name is a valid binary name, return it; otherwise quote it. */
private static String checkName(String name) {
if (name == null)
return "null";
int len = name.length();
if (len == 0)
return "\"\"";
int cc = '/';
int cp;
for (int k = 0; k < len; k += Character.charCount(cp)) {
cp = name.codePointAt(k);
if ((cc == '/' && !Character.isJavaIdentifierStart(cp))
|| (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
return "\"" + addEscapes(name) + "\"";
}
cc = cp;
}
return name;
}
/* If name requires escapes, put them in, so it can be a string body. */
private static String addEscapes(String name) {
String esc = "\\\"\n\t";
String rep = "\\\"nt";
StringBuilder buf = null;
int nextk = 0;
int len = name.length();
for (int k = 0; k < len; k++) {
char cp = name.charAt(k);
int n = esc.indexOf(cp);
if (n >= 0) {
if (buf == null)
buf = new StringBuilder(len * 2);
if (nextk < k)
buf.append(name, nextk, k);
buf.append('\\');
buf.append(rep.charAt(n));
nextk = k+1;
}
}
if (buf == null)
return name;
if (nextk < len)
buf.append(name, nextk, len);
return buf.toString();
}
private ClassWriter classWriter;
private Options options;
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.HashMap;
import java.util.Map;
/*
* Class from which to put/get shared resources.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class Context {
public Context() {
map = new HashMap<Class<?>, Object>();
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> key) {
return (T) map.get(key);
}
@SuppressWarnings("unchecked")
public <T> T put(Class<T> key, T value) {
return (T) map.put(key, value);
}
Map<Class<?>, Object> map;
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap; //javax.tools;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.concurrent.Callable;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.OptionChecker;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.Tool;
/**
* This class is intended to be put in javax.tools.
*
* @see DiagnosticListener
* @see Diagnostic
* @see JavaFileManager
* @since 1.7
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public interface DisassemblerTool extends Tool, OptionChecker {
/**
* Creates a future for a disassembly task with the given
* components and arguments. The task might not have
* completed as described in the DissemblerTask interface.
*
* <p>If a file manager is provided, it must be able to handle all
* locations defined in {@link StandardLocation}.
*
* @param out a Writer for additional output from the compiler;
* use {@code System.err} if {@code null}
* @param fileManager a file manager; if {@code null} use the
* compiler's standard filemanager
* @param diagnosticListener a diagnostic listener; if {@code
* null} use the compiler's default method for reporting
* diagnostics
* @param options compiler options, {@code null} means no options
* @param classes class names (for annotation processing), {@code
* null} means no class names
* @return a task to perform the disassembly
* @throws RuntimeException if an unrecoverable error
* occurred in a user supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error in
* user code.
* @throws IllegalArgumentException if any of the given
* compilation units are of other kind than
* {@linkplain JavaFileObject.Kind#SOURCE source}
*/
DisassemblerTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes);
/**
* Gets a new instance of the standard file manager implementation
* for this tool. The file manager will use the given diagnostic
* listener for producing any non-fatal diagnostics. Fatal errors
* will be signalled with the appropriate exceptions.
*
* <p>The standard file manager will be automatically reopened if
* it is accessed after calls to {@code flush} or {@code close}.
* The standard file manager must be usable with other tools.
*
* @param diagnosticListener a diagnostic listener for non-fatal
* diagnostics; if {@code null} use the compiler's default method
* for reporting diagnostics
* @param locale the locale to apply when formatting diagnostics;
* {@code null} means the {@linkplain Locale#getDefault() default locale}.
* @param charset the character set used for decoding bytes; if
* {@code null} use the platform default
* @return the standard file manager
*/
StandardJavaFileManager getStandardFileManager(
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Locale locale,
Charset charset);
/**
* Interface representing a future for a disassembly task. The
* task has not yet started. To start the task, call
* the {@linkplain #call call} method.
*
* <p>Before calling the call method, additional aspects of the
* task can be configured, for example, by calling the
* {@linkplain #setLocale setLocale} method.
*/
interface DisassemblerTask extends Callable<Boolean> {
/**
* Set the locale to be applied when formatting diagnostics and
* other localized data.
*
* @param locale the locale to apply; {@code null} means apply no
* locale
* @throws IllegalStateException if the task has started
*/
void setLocale(Locale locale);
/**
* Performs this compilation task. The compilation may only
* be performed once. Subsequent calls to this method throw
* IllegalStateException.
*
* @return true if and only all the files compiled without errors;
* false otherwise
*
* @throws RuntimeException if an unrecoverable error occurred
* in a user-supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error
* in user code.
* @throws IllegalStateException if called more than once
*/
Boolean call();
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Instruction;
/*
* Write additional details for an instruction.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public abstract class InstructionDetailWriter extends BasicWriter {
public enum Kind {
LOCAL_VARS("localVariables"),
LOCAL_VAR_TYPES("localVariableTypes"),
SOURCE("source"),
STACKMAPS("stackMaps"),
TRY_BLOCKS("tryBlocks"),
TYPE_ANNOS("typeAnnotations");
Kind(String option) {
this.option = option;
}
final String option;
}
InstructionDetailWriter(Context context) {
super(context);
}
abstract void writeDetails(Instruction instr);
void flush() { }
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2007, 2009, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
/**
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class InternalError extends Error {
private static final long serialVersionUID = 8114054446416187030L;
InternalError(Throwable t, Object... args) {
super("Internal error", t);
this.args = args;
}
InternalError(Object... args) {
super("Internal error");
this.args = args;
}
public final Object[] args;
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
/**
* javap's implementation of JavaFileManager.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class JavapFileManager extends JavacFileManager {
private JavapFileManager(Context context, Charset charset) {
super(context, true, charset);
setSymbolFileEnabled(false);
}
public static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
Context javac_context = new Context();
if (dl != null)
javac_context.put(DiagnosticListener.class, dl);
javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
return new JavapFileManager(javac_context, null);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
/**
* Annotate instructions with details about local variables.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class LocalVariableTableWriter extends InstructionDetailWriter {
public enum NoteKind {
START("start") {
public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
return (pc == entry.start_pc);
}
},
END("end") {
public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
return (pc == entry.start_pc + entry.length);
}
};
NoteKind(String text) {
this.text = text;
}
public abstract boolean match(LocalVariableTable_attribute.Entry entry, int pc);
public final String text;
};
static LocalVariableTableWriter instance(Context context) {
LocalVariableTableWriter instance = context.get(LocalVariableTableWriter.class);
if (instance == null)
instance = new LocalVariableTableWriter(context);
return instance;
}
protected LocalVariableTableWriter(Context context) {
super(context);
context.put(LocalVariableTableWriter.class, this);
classWriter = ClassWriter.instance(context);
}
public void reset(Code_attribute attr) {
codeAttr = attr;
pcMap = new HashMap<Integer, List<LocalVariableTable_attribute.Entry>>();
LocalVariableTable_attribute lvt =
(LocalVariableTable_attribute) (attr.attributes.get(Attribute.LocalVariableTable));
if (lvt == null)
return;
for (int i = 0; i < lvt.local_variable_table.length; i++) {
LocalVariableTable_attribute.Entry entry = lvt.local_variable_table[i];
put(entry.start_pc, entry);
put(entry.start_pc + entry.length, entry);
}
}
public void writeDetails(Instruction instr) {
int pc = instr.getPC();
writeLocalVariables(pc, NoteKind.END);
writeLocalVariables(pc, NoteKind.START);
}
@Override
public void flush() {
int pc = codeAttr.code_length;
writeLocalVariables(pc, NoteKind.END);
}
public void writeLocalVariables(int pc, NoteKind kind) {
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
String indent = space(2); // get from Options?
List<LocalVariableTable_attribute.Entry> entries = pcMap.get(pc);
if (entries != null) {
for (ListIterator<LocalVariableTable_attribute.Entry> iter =
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
LocalVariableTable_attribute.Entry entry =
kind == NoteKind.END ? iter.previous() : iter.next();
if (kind.match(entry, pc)) {
print(indent);
print(kind.text);
print(" local ");
print(entry.index);
print(" // ");
Descriptor d = new Descriptor(entry.descriptor_index);
try {
print(d.getFieldType(constant_pool));
} catch (InvalidDescriptor e) {
print(report(e));
} catch (ConstantPoolException e) {
print(report(e));
}
print(" ");
try {
print(constant_pool.getUTF8Value(entry.name_index));
} catch (ConstantPoolException e) {
print(report(e));
}
println();
}
}
}
}
private void put(int pc, LocalVariableTable_attribute.Entry entry) {
List<LocalVariableTable_attribute.Entry> list = pcMap.get(pc);
if (list == null) {
list = new ArrayList<LocalVariableTable_attribute.Entry>();
pcMap.put(pc, list);
}
if (!list.contains(entry))
list.add(entry);
}
private ClassWriter classWriter;
private Code_attribute codeAttr;
private Map<Integer, List<LocalVariableTable_attribute.Entry>> pcMap;
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
import com.sun.tools.classfile.Signature;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
/**
* Annotate instructions with details about local variables.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class LocalVariableTypeTableWriter extends InstructionDetailWriter {
public enum NoteKind {
START("start") {
public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
return (pc == entry.start_pc);
}
},
END("end") {
public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
return (pc == entry.start_pc + entry.length);
}
};
NoteKind(String text) {
this.text = text;
}
public abstract boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc);
public final String text;
};
static LocalVariableTypeTableWriter instance(Context context) {
LocalVariableTypeTableWriter instance = context.get(LocalVariableTypeTableWriter.class);
if (instance == null)
instance = new LocalVariableTypeTableWriter(context);
return instance;
}
protected LocalVariableTypeTableWriter(Context context) {
super(context);
context.put(LocalVariableTypeTableWriter.class, this);
classWriter = ClassWriter.instance(context);
}
public void reset(Code_attribute attr) {
codeAttr = attr;
pcMap = new HashMap<Integer, List<LocalVariableTypeTable_attribute.Entry>>();
LocalVariableTypeTable_attribute lvt =
(LocalVariableTypeTable_attribute) (attr.attributes.get(Attribute.LocalVariableTypeTable));
if (lvt == null)
return;
for (int i = 0; i < lvt.local_variable_table.length; i++) {
LocalVariableTypeTable_attribute.Entry entry = lvt.local_variable_table[i];
put(entry.start_pc, entry);
put(entry.start_pc + entry.length, entry);
}
}
public void writeDetails(Instruction instr) {
int pc = instr.getPC();
writeLocalVariables(pc, NoteKind.END);
writeLocalVariables(pc, NoteKind.START);
}
@Override
public void flush() {
int pc = codeAttr.code_length;
writeLocalVariables(pc, NoteKind.END);
}
public void writeLocalVariables(int pc, NoteKind kind) {
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
String indent = space(2); // get from Options?
List<LocalVariableTypeTable_attribute.Entry> entries = pcMap.get(pc);
if (entries != null) {
for (ListIterator<LocalVariableTypeTable_attribute.Entry> iter =
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
LocalVariableTypeTable_attribute.Entry entry =
kind == NoteKind.END ? iter.previous() : iter.next();
if (kind.match(entry, pc)) {
print(indent);
print(kind.text);
print(" generic local ");
print(entry.index);
print(" // ");
Descriptor d = new Signature(entry.signature_index);
try {
print(d.getFieldType(constant_pool).toString().replace("/", "."));
} catch (InvalidDescriptor e) {
print(report(e));
} catch (ConstantPoolException e) {
print(report(e));
}
print(" ");
try {
print(constant_pool.getUTF8Value(entry.name_index));
} catch (ConstantPoolException e) {
print(report(e));
}
println();
}
}
}
}
private void put(int pc, LocalVariableTypeTable_attribute.Entry entry) {
List<LocalVariableTypeTable_attribute.Entry> list = pcMap.get(pc);
if (list == null) {
list = new ArrayList<LocalVariableTypeTable_attribute.Entry>();
pcMap.put(pc, list);
}
if (!list.contains(entry))
list.add(entry);
}
private ClassWriter classWriter;
private Code_attribute codeAttr;
private Map<Integer, List<LocalVariableTypeTable_attribute.Entry>> pcMap;
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2007, 2008, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.io.PrintWriter;
/**
* Main entry point.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class Main {
/**
* Main entry point for the launcher.
* Note: This method calls System.exit.
* @param args command line arguments
*/
public static void main(String[] args) {
JavapTask t = new JavapTask();
int rc = t.run(args);
System.exit(rc);
}
/**
* Entry point that does <i>not</i> call System.exit.
* @param args command line arguments
* @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(String[] args, PrintWriter out) {
JavapTask t = new JavapTask();
t.setLog(out);
return t.run(args);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2007, 2009, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.Locale;
/**
* Access to javap messages.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public interface Messages {
String getMessage(String key, Object... args);
String getMessage(Locale locale, String key, Object... args);
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import com.sun.tools.classfile.AccessFlags;
/*
* Provides access to javap's options, set via the command line
* or JSR 199 API.
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class Options {
public static Options instance(Context context) {
Options instance = context.get(Options.class);
if (instance == null)
instance = new Options(context);
return instance;
}
protected Options(Context context) {
context.put(Options.class, this);
}
/**
* Checks access of class, field or method.
*/
public boolean checkAccess(AccessFlags flags){
boolean isPublic = flags.is(AccessFlags.ACC_PUBLIC);
boolean isProtected = flags.is(AccessFlags.ACC_PROTECTED);
boolean isPrivate = flags.is(AccessFlags.ACC_PRIVATE);
boolean isPackage = !(isPublic || isProtected || isPrivate);
if ((showAccess == AccessFlags.ACC_PUBLIC) && (isProtected || isPrivate || isPackage))
return false;
else if ((showAccess == AccessFlags.ACC_PROTECTED) && (isPrivate || isPackage))
return false;
else if ((showAccess == 0) && (isPrivate))
return false;
else
return true;
}
public boolean help;
public boolean verbose;
public boolean version;
public boolean fullVersion;
public boolean showFlags;
public boolean showLineAndLocalVariableTables;
public int showAccess;
public Set<String> accessOptions = new HashSet<String>();
public Set<InstructionDetailWriter.Kind> details = EnumSet.noneOf(InstructionDetailWriter.Kind.class);
public boolean showDisassembled;
public boolean showDescriptors;
public boolean showAllAttrs;
public boolean showConstants;
public boolean sysInfo;
public boolean showInnerClasses;
public int indentWidth = 2; // #spaces per indentWidth level; must be > 0
public int tabColumn = 40; // column number for comments; must be > 0
}

View File

@@ -0,0 +1,213 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.SourceFile_attribute;
/**
* Annotate instructions with source code.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class SourceWriter extends InstructionDetailWriter {
static SourceWriter instance(Context context) {
SourceWriter instance = context.get(SourceWriter.class);
if (instance == null)
instance = new SourceWriter(context);
return instance;
}
protected SourceWriter(Context context) {
super(context);
context.put(SourceWriter.class, this);
}
void setFileManager(JavaFileManager fileManager) {
this.fileManager = fileManager;
}
public void reset(ClassFile cf, Code_attribute attr) {
setSource(cf);
setLineMap(attr);
}
public void writeDetails(Instruction instr) {
String indent = space(40); // could get from Options?
Set<Integer> lines = lineMap.get(instr.getPC());
if (lines != null) {
for (int line: lines) {
print(indent);
print(String.format(" %4d ", line));
if (line < sourceLines.length)
print(sourceLines[line]);
println();
int nextLine = nextLine(line);
for (int i = line + 1; i < nextLine; i++) {
print(indent);
print(String.format("(%4d)", i));
if (i < sourceLines.length)
print(sourceLines[i]);
println();
}
}
}
}
public boolean hasSource() {
return (sourceLines.length > 0);
}
private void setLineMap(Code_attribute attr) {
SortedMap<Integer, SortedSet<Integer>> map =
new TreeMap<Integer, SortedSet<Integer>>();
SortedSet<Integer> allLines = new TreeSet<Integer>();
for (Attribute a: attr.attributes) {
if (a instanceof LineNumberTable_attribute) {
LineNumberTable_attribute t = (LineNumberTable_attribute) a;
for (LineNumberTable_attribute.Entry e: t.line_number_table) {
int start_pc = e.start_pc;
int line = e.line_number;
SortedSet<Integer> pcLines = map.get(start_pc);
if (pcLines == null) {
pcLines = new TreeSet<Integer>();
map.put(start_pc, pcLines);
}
pcLines.add(line);
allLines.add(line);
}
}
}
lineMap = map;
lineList = new ArrayList<Integer>(allLines);
}
private void setSource(ClassFile cf) {
if (cf != classFile) {
classFile = cf;
sourceLines = splitLines(readSource(cf));
}
}
private String readSource(ClassFile cf) {
if (fileManager == null)
return null;
Location location;
if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
location = StandardLocation.SOURCE_PATH;
else
location = StandardLocation.CLASS_PATH;
// Guess the source file for a class from the package name for this
// class and the base of the source file. This avoids having to read
// additional classes to determine the outmost class from any
// InnerClasses and EnclosingMethod attributes.
try {
String className = cf.getName();
SourceFile_attribute sf =
(SourceFile_attribute) cf.attributes.get(Attribute.SourceFile);
if (sf == null) {
report(messages.getMessage("err.no.SourceFile.attribute"));
return null;
}
String sourceFile = sf.getSourceFile(cf.constant_pool);
String fileBase = sourceFile.endsWith(".java")
? sourceFile.substring(0, sourceFile.length() - 5) : sourceFile;
int sep = className.lastIndexOf("/");
String pkgName = (sep == -1 ? "" : className.substring(0, sep+1));
String topClassName = (pkgName + fileBase).replace('/', '.');
JavaFileObject fo =
fileManager.getJavaFileForInput(location,
topClassName,
JavaFileObject.Kind.SOURCE);
if (fo == null) {
report(messages.getMessage("err.source.file.not.found"));
return null;
}
return fo.getCharContent(true).toString();
} catch (ConstantPoolException e) {
report(e);
return null;
} catch (IOException e) {
report(e.getLocalizedMessage());
return null;
}
}
private static String[] splitLines(String text) {
if (text == null)
return new String[0];
List<String> lines = new ArrayList<String>();
lines.add(""); // dummy line 0
try {
BufferedReader r = new BufferedReader(new StringReader(text));
String line;
while ((line = r.readLine()) != null)
lines.add(line);
} catch (IOException ignore) {
}
return lines.toArray(new String[lines.size()]);
}
private int nextLine(int line) {
int i = lineList.indexOf(line);
if (i == -1 || i == lineList.size() - 1)
return - 1;
return lineList.get(i + 1);
}
private JavaFileManager fileManager;
private ClassFile classFile;
private SortedMap<Integer, SortedSet<Integer>> lineMap;
private List<Integer> lineList;
private String[] sourceLines;
}

View File

@@ -0,0 +1,291 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.StackMapTable_attribute;
import com.sun.tools.classfile.StackMapTable_attribute.*;
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
/**
* Annotate instructions with stack map.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class StackMapWriter extends InstructionDetailWriter {
static StackMapWriter instance(Context context) {
StackMapWriter instance = context.get(StackMapWriter.class);
if (instance == null)
instance = new StackMapWriter(context);
return instance;
}
protected StackMapWriter(Context context) {
super(context);
context.put(StackMapWriter.class, this);
classWriter = ClassWriter.instance(context);
}
public void reset(Code_attribute attr) {
setStackMap((StackMapTable_attribute) attr.attributes.get(Attribute.StackMapTable));
}
void setStackMap(StackMapTable_attribute attr) {
if (attr == null) {
map = null;
return;
}
Method m = classWriter.getMethod();
Descriptor d = m.descriptor;
String[] args;
try {
ConstantPool cp = classWriter.getClassFile().constant_pool;
String argString = d.getParameterTypes(cp);
args = argString.substring(1, argString.length() - 1).split("[, ]+");
} catch (ConstantPoolException e) {
return;
} catch (InvalidDescriptor e) {
return;
}
boolean isStatic = m.access_flags.is(AccessFlags.ACC_STATIC);
verification_type_info[] initialLocals = new verification_type_info[(isStatic ? 0 : 1) + args.length];
if (!isStatic)
initialLocals[0] = new CustomVerificationTypeInfo("this");
for (int i = 0; i < args.length; i++) {
initialLocals[(isStatic ? 0 : 1) + i] =
new CustomVerificationTypeInfo(args[i].replace(".", "/"));
}
map = new HashMap<Integer, StackMap>();
StackMapBuilder builder = new StackMapBuilder();
// using -1 as the pc for the initial frame effectively compensates for
// the difference in behavior for the first stack map frame (where the
// pc offset is just offset_delta) compared to subsequent frames (where
// the pc offset is always offset_delta+1).
int pc = -1;
map.put(pc, new StackMap(initialLocals, empty));
for (int i = 0; i < attr.entries.length; i++)
pc = attr.entries[i].accept(builder, pc);
}
public void writeInitialDetails() {
writeDetails(-1);
}
public void writeDetails(Instruction instr) {
writeDetails(instr.getPC());
}
private void writeDetails(int pc) {
if (map == null)
return;
StackMap m = map.get(pc);
if (m != null) {
print("StackMap locals: ", m.locals);
print("StackMap stack: ", m.stack);
}
}
void print(String label, verification_type_info[] entries) {
print(label);
for (int i = 0; i < entries.length; i++) {
print(" ");
print(entries[i]);
}
println();
}
void print(verification_type_info entry) {
if (entry == null) {
print("ERROR");
return;
}
switch (entry.tag) {
case -1:
print(((CustomVerificationTypeInfo) entry).text);
break;
case ITEM_Top:
print("top");
break;
case ITEM_Integer:
print("int");
break;
case ITEM_Float:
print("float");
break;
case ITEM_Long:
print("long");
break;
case ITEM_Double:
print("double");
break;
case ITEM_Null:
print("null");
break;
case ITEM_UninitializedThis:
print("uninit_this");
break;
case ITEM_Object:
try {
ConstantPool cp = classWriter.getClassFile().constant_pool;
ConstantPool.CONSTANT_Class_info class_info = cp.getClassInfo(((Object_variable_info) entry).cpool_index);
print(cp.getUTF8Value(class_info.name_index));
} catch (ConstantPoolException e) {
print("??");
}
break;
case ITEM_Uninitialized:
print(((Uninitialized_variable_info) entry).offset);
break;
}
}
private Map<Integer, StackMap> map;
private ClassWriter classWriter;
class StackMapBuilder
implements StackMapTable_attribute.stack_map_frame.Visitor<Integer, Integer> {
public Integer visit_same_frame(same_frame frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap m = map.get(pc);
assert (m != null);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap prev = map.get(pc);
assert (prev != null);
StackMap m = new StackMap(prev.locals, frame.stack);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap prev = map.get(pc);
assert (prev != null);
StackMap m = new StackMap(prev.locals, frame.stack);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_chop_frame(chop_frame frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap prev = map.get(pc);
assert (prev != null);
int k = 251 - frame.frame_type;
verification_type_info[] new_locals = Arrays.copyOf(prev.locals, prev.locals.length - k);
StackMap m = new StackMap(new_locals, empty);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_same_frame_extended(same_frame_extended frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta();
StackMap m = map.get(pc);
assert (m != null);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_append_frame(append_frame frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap prev = map.get(pc);
assert (prev != null);
verification_type_info[] new_locals = new verification_type_info[prev.locals.length + frame.locals.length];
System.arraycopy(prev.locals, 0, new_locals, 0, prev.locals.length);
System.arraycopy(frame.locals, 0, new_locals, prev.locals.length, frame.locals.length);
StackMap m = new StackMap(new_locals, empty);
map.put(new_pc, m);
return new_pc;
}
public Integer visit_full_frame(full_frame frame, Integer pc) {
int new_pc = pc + frame.getOffsetDelta() + 1;
StackMap m = new StackMap(frame.locals, frame.stack);
map.put(new_pc, m);
return new_pc;
}
}
static class StackMap {
StackMap(verification_type_info[] locals, verification_type_info[] stack) {
this.locals = locals;
this.stack = stack;
}
private final verification_type_info[] locals;
private final verification_type_info[] stack;
}
static class CustomVerificationTypeInfo extends verification_type_info {
public CustomVerificationTypeInfo(String text) {
super(-1);
this.text = text;
}
private String text;
}
private final verification_type_info[] empty = { };
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.Code_attribute.Exception_data;
import com.sun.tools.classfile.Instruction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
/**
* Annotate instructions with details about try blocks.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class TryBlockWriter extends InstructionDetailWriter {
public enum NoteKind {
START("try") {
public boolean match(Exception_data entry, int pc) {
return (pc == entry.start_pc);
}
},
END("end try") {
public boolean match(Exception_data entry, int pc) {
return (pc == entry.end_pc);
}
},
HANDLER("catch") {
public boolean match(Exception_data entry, int pc) {
return (pc == entry.handler_pc);
}
};
NoteKind(String text) {
this.text = text;
}
public abstract boolean match(Exception_data entry, int pc);
public final String text;
};
static TryBlockWriter instance(Context context) {
TryBlockWriter instance = context.get(TryBlockWriter.class);
if (instance == null)
instance = new TryBlockWriter(context);
return instance;
}
protected TryBlockWriter(Context context) {
super(context);
context.put(TryBlockWriter.class, this);
constantWriter = ConstantWriter.instance(context);
}
public void reset(Code_attribute attr) {
indexMap = new HashMap<Exception_data, Integer>();
pcMap = new HashMap<Integer, List<Exception_data>>();
for (int i = 0; i < attr.exception_table.length; i++) {
Exception_data entry = attr.exception_table[i];
indexMap.put(entry, i);
put(entry.start_pc, entry);
put(entry.end_pc, entry);
put(entry.handler_pc, entry);
}
}
public void writeDetails(Instruction instr) {
writeTrys(instr, NoteKind.END);
writeTrys(instr, NoteKind.START);
writeTrys(instr, NoteKind.HANDLER);
}
public void writeTrys(Instruction instr, NoteKind kind) {
String indent = space(2); // get from Options?
int pc = instr.getPC();
List<Exception_data> entries = pcMap.get(pc);
if (entries != null) {
for (ListIterator<Exception_data> iter =
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
Exception_data entry =
kind == NoteKind.END ? iter.previous() : iter.next();
if (kind.match(entry, pc)) {
print(indent);
print(kind.text);
print("[");
print(indexMap.get(entry));
print("] ");
if (entry.catch_type == 0)
print("finally");
else {
print("#" + entry.catch_type);
print(" // ");
constantWriter.write(entry.catch_type);
}
println();
}
}
}
}
private void put(int pc, Exception_data entry) {
List<Exception_data> list = pcMap.get(pc);
if (list == null) {
list = new ArrayList<Exception_data>();
pcMap.put(pc, list);
}
if (!list.contains(entry))
list.add(entry);
}
private Map<Integer, List<Exception_data>> pcMap;
private Map<Exception_data, Integer> indexMap;
private ConstantWriter constantWriter;
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javap;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.classfile.TypeAnnotation.Position;
import com.sun.tools.classfile.Instruction;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sun.tools.javac.util.StringUtils;
/**
* Annotate instructions with details about type annotations.
*
* <p><b>This is NOT part of any supported API.
* 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.</b>
*/
public class TypeAnnotationWriter extends InstructionDetailWriter {
public enum NoteKind { VISIBLE, INVISIBLE };
public static class Note {
Note(NoteKind kind, TypeAnnotation anno) {
this.kind = kind;
this.anno = anno;
}
public final NoteKind kind;
public final TypeAnnotation anno;
}
static TypeAnnotationWriter instance(Context context) {
TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class);
if (instance == null)
instance = new TypeAnnotationWriter(context);
return instance;
}
protected TypeAnnotationWriter(Context context) {
super(context);
context.put(TypeAnnotationWriter.class, this);
annotationWriter = AnnotationWriter.instance(context);
classWriter = ClassWriter.instance(context);
}
public void reset(Code_attribute attr) {
Method m = classWriter.getMethod();
pcMap = new HashMap<Integer, List<Note>>();
check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations));
check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations));
}
private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) {
if (attr == null)
return;
for (TypeAnnotation anno: attr.annotations) {
Position p = anno.position;
Note note = null;
if (p.offset != -1)
addNote(p.offset, note = new Note(kind, anno));
if (p.lvarOffset != null) {
for (int i = 0; i < p.lvarOffset.length; i++) {
if (note == null)
note = new Note(kind, anno);
addNote(p.lvarOffset[i], note);
}
}
}
}
private void addNote(int pc, Note note) {
List<Note> list = pcMap.get(pc);
if (list == null)
pcMap.put(pc, list = new ArrayList<Note>());
list.add(note);
}
@Override
void writeDetails(Instruction instr) {
String indent = space(2); // get from Options?
int pc = instr.getPC();
List<Note> notes = pcMap.get(pc);
if (notes != null) {
for (Note n: notes) {
print(indent);
print("@");
annotationWriter.write(n.anno, false, true);
print(", ");
println(StringUtils.toLowerCase(n.kind.toString()));
}
}
}
private AnnotationWriter annotationWriter;
private ClassWriter classWriter;
private Map<Integer, List<Note>> pcMap;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
Classes to dump class files in text format.
<p><b>This is NOT part of any supported API.
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.</b>
*/
@jdk.Exported(false)
package com.sun.tools.javap;

View File

@@ -0,0 +1,46 @@
package com.sun.tools.javap.resources;
public final class javap extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "err.bad.constant.pool", "error while reading constant pool for {0}: {1}" },
{ "err.bad.innerclasses.attribute", "bad InnerClasses attribute for {0}" },
{ "err.class.not.found", "class not found: {0}" },
{ "err.crash", "A serious internal error has occurred: {0}\nPlease file a bug report, and include the following information:\n{1}" },
{ "err.end.of.file", "unexpected end of file while reading {0}" },
{ "err.file.not.found", "file not found: {0}" },
{ "err.incompatible.options", "bad combination of options: {0}" },
{ "err.internal.error", "internal error: {0} {1} {2}" },
{ "err.invalid.arg.for.option", "invalid argument for option: {0}" },
{ "err.invalid.use.of.option", "invalid use of option: {0}" },
{ "err.ioerror", "IO error reading {0}: {1}" },
{ "err.missing.arg", "no value given for {0}" },
{ "err.no.SourceFile.attribute", "no SourceFile attribute" },
{ "err.no.classes.specified", "no classes specified" },
{ "err.not.standard.file.manager", "can only specify class files when using a standard file manager" },
{ "err.prefix", "Error:" },
{ "err.source.file.not.found", "source file not found" },
{ "err.unknown.option", "unknown option: {0}" },
{ "main.opt.bootclasspath", " -bootclasspath <path> Override location of bootstrap class files" },
{ "main.opt.c", " -c Disassemble the code" },
{ "main.opt.classpath", " -classpath <path> Specify where to find user class files" },
{ "main.opt.constants", " -constants Show final constants" },
{ "main.opt.cp", " -cp <path> Specify where to find user class files" },
{ "main.opt.help", " -help --help -? Print this usage message" },
{ "main.opt.l", " -l Print line number and local variable tables" },
{ "main.opt.p", " -p -private Show all classes and members" },
{ "main.opt.package", " -package Show package/protected/public classes\n and members (default)" },
{ "main.opt.protected", " -protected Show protected/public classes and members" },
{ "main.opt.public", " -public Show only public classes and members" },
{ "main.opt.s", " -s Print internal type signatures" },
{ "main.opt.sysinfo", " -sysinfo Show system info (path, size, date, MD5 hash)\n of class being processed" },
{ "main.opt.v", " -v -verbose Print additional information" },
{ "main.opt.version", " -version Version information" },
{ "main.usage", "Usage: {0} <options> <classes>\nwhere possible options include:" },
{ "main.usage.summary", "Usage: {0} <options> <classes>\nuse -help for a list of possible options" },
{ "note.prefix", "Note:" },
{ "warn.prefix", "Warning:" },
{ "warn.unexpected.class", "Binary file {0} contains {1}" },
};
}
}

View File

@@ -0,0 +1,46 @@
package com.sun.tools.javap.resources;
public final class javap_ja extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "err.bad.constant.pool", "{0}\u306E\u5B9A\u6570\u30D7\u30FC\u30EB\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {1}" },
{ "err.bad.innerclasses.attribute", "{0}\u306EInnerClasses\u5C5E\u6027\u304C\u4E0D\u6B63\u3067\u3059" },
{ "err.class.not.found", "\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}" },
{ "err.crash", "\u91CD\u5927\u306A\u5185\u90E8\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {0}\n\u6B21\u306E\u60C5\u5831\u3092\u542B\u3080bug\u30EC\u30DD\u30FC\u30C8\u3092\u30D5\u30A1\u30A4\u30EB\u3057\u3066\u304F\u3060\u3055\u3044:\n{1}" },
{ "err.end.of.file", "{0}\u306E\u8AAD\u53D6\u308A\u4E2D\u306B\u4E88\u671F\u3057\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u306E\u7D42\u308F\u308A\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F" },
{ "err.file.not.found", "\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: {0}" },
{ "err.incompatible.options", "\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u7D44\u5408\u305B\u304C\u4E0D\u6B63\u3067\u3059: {0}" },
{ "err.internal.error", "\u5185\u90E8\u30A8\u30E9\u30FC: {0} {1} {2}" },
{ "err.invalid.arg.for.option", "\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}" },
{ "err.invalid.use.of.option", "\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u4F7F\u7528\u304C\u7121\u52B9\u3067\u3059: {0}" },
{ "err.ioerror", "{0}\u306E\u8AAD\u53D6\u308A\u4E2D\u306BIO\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F: {1}" },
{ "err.missing.arg", "{0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093" },
{ "err.no.SourceFile.attribute", "SourceFile\u5C5E\u6027\u304C\u3042\u308A\u307E\u305B\u3093" },
{ "err.no.classes.specified", "\u30AF\u30E9\u30B9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093" },
{ "err.not.standard.file.manager", "\u6A19\u6E96\u30D5\u30A1\u30A4\u30EB\u30FB\u30DE\u30CD\u30FC\u30B8\u30E3\u3092\u4F7F\u7528\u3057\u3066\u3044\u308B\u5834\u5408\u306F\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u307F\u6307\u5B9A\u3067\u304D\u307E\u3059" },
{ "err.prefix", "\u30A8\u30E9\u30FC:" },
{ "err.source.file.not.found", "\u30BD\u30FC\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093" },
{ "err.unknown.option", "\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}" },
{ "main.opt.bootclasspath", " -bootclasspath <path> \u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B" },
{ "main.opt.c", " -c \u30B3\u30FC\u30C9\u3092\u9006\u30A2\u30BB\u30F3\u30D6\u30EB\u3059\u308B" },
{ "main.opt.classpath", " -classpath <path> \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B" },
{ "main.opt.constants", " -constants final\u5B9A\u6570\u3092\u8868\u793A\u3059\u308B" },
{ "main.opt.cp", " -cp <path> \u30E6\u30FC\u30B6\u30FC\u30FB\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3059\u308B" },
{ "main.opt.help", " -help --help -? \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u51FA\u529B\u3059\u308B" },
{ "main.opt.l", " -l \u884C\u756A\u53F7\u3068\u30ED\u30FC\u30AB\u30EB\u5909\u6570\u8868\u3092\u51FA\u529B\u3059\u308B" },
{ "main.opt.p", " -p -private \u3059\u3079\u3066\u306E\u30AF\u30E9\u30B9\u3068\u30E1\u30F3\u30D0\u30FC\u3092\u8868\u793A\u3059\u308B" },
{ "main.opt.package", " -package package/protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\n \u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B(\u30C7\u30D5\u30A9\u30EB\u30C8)" },
{ "main.opt.protected", " -protected protected/public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B" },
{ "main.opt.public", " -public public\u30AF\u30E9\u30B9\u304A\u3088\u3073\u30E1\u30F3\u30D0\u30FC\u306E\u307F\u3092\u8868\u793A\u3059\u308B" },
{ "main.opt.s", " -s \u5185\u90E8\u30BF\u30A4\u30D7\u7F72\u540D\u3092\u51FA\u529B\u3059\u308B" },
{ "main.opt.sysinfo", " -sysinfo \u51E6\u7406\u3057\u3066\u3044\u308B\u30AF\u30E9\u30B9\u306E\u30B7\u30B9\u30C6\u30E0\u60C5\u5831(\u30D1\u30B9\u3001\u30B5\u30A4\u30BA\u3001\u65E5\u4ED8\u3001MD5\u30CF\u30C3\u30B7\u30E5)\n \u3092\u8868\u793A\u3059\u308B" },
{ "main.opt.v", " -v -verbose \u8FFD\u52A0\u60C5\u5831\u3092\u51FA\u529B\u3059\u308B" },
{ "main.opt.version", " -version \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831" },
{ "main.usage", "\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306B\u306F\u6B21\u306E\u3082\u306E\u304C\u3042\u308A\u307E\u3059:" },
{ "main.usage.summary", "\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-help\u3092\u4F7F\u7528\u3057\u307E\u3059" },
{ "note.prefix", "\u6CE8:" },
{ "warn.prefix", "\u8B66\u544A:" },
{ "warn.unexpected.class", "\u30D0\u30A4\u30CA\u30EA\u30FB\u30D5\u30A1\u30A4\u30EB{0}\u306B{1}\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059" },
};
}
}

View File

@@ -0,0 +1,46 @@
package com.sun.tools.javap.resources;
public final class javap_zh_CN extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "err.bad.constant.pool", "\u8BFB\u53D6{0}\u7684\u5E38\u91CF\u6C60\u65F6\u51FA\u9519: {1}" },
{ "err.bad.innerclasses.attribute", "{0}\u7684 InnerClasses \u5C5E\u6027\u9519\u8BEF" },
{ "err.class.not.found", "\u627E\u4E0D\u5230\u7C7B: {0}" },
{ "err.crash", "\u51FA\u73B0\u4E25\u91CD\u7684\u5185\u90E8\u9519\u8BEF: {0}\n\u8BF7\u5EFA\u7ACB Bug \u62A5\u544A, \u5E76\u5305\u62EC\u4EE5\u4E0B\u4FE1\u606F:\n{1}" },
{ "err.end.of.file", "\u8BFB\u53D6{0}\u65F6\u51FA\u73B0\u610F\u5916\u7684\u6587\u4EF6\u7ED3\u5C3E" },
{ "err.file.not.found", "\u627E\u4E0D\u5230\u6587\u4EF6: {0}" },
{ "err.incompatible.options", "\u9009\u9879\u7EC4\u5408\u9519\u8BEF: {0}" },
{ "err.internal.error", "\u5185\u90E8\u9519\u8BEF: {0} {1} {2}" },
{ "err.invalid.arg.for.option", "\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}" },
{ "err.invalid.use.of.option", "\u9009\u9879\u7684\u4F7F\u7528\u65E0\u6548: {0}" },
{ "err.ioerror", "\u8BFB\u53D6{0}\u65F6\u51FA\u73B0 IO \u9519\u8BEF: {1}" },
{ "err.missing.arg", "\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C" },
{ "err.no.SourceFile.attribute", "\u6CA1\u6709 SourceFile \u5C5E\u6027" },
{ "err.no.classes.specified", "\u672A\u6307\u5B9A\u7C7B" },
{ "err.not.standard.file.manager", "\u4F7F\u7528\u6807\u51C6\u6587\u4EF6\u7BA1\u7406\u5668\u65F6\u53EA\u80FD\u6307\u5B9A\u7C7B\u6587\u4EF6" },
{ "err.prefix", "\u9519\u8BEF:" },
{ "err.source.file.not.found", "\u627E\u4E0D\u5230\u6E90\u6587\u4EF6" },
{ "err.unknown.option", "\u672A\u77E5\u9009\u9879: {0}" },
{ "main.opt.bootclasspath", " -bootclasspath <path> \u8986\u76D6\u5F15\u5BFC\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E" },
{ "main.opt.c", " -c \u5BF9\u4EE3\u7801\u8FDB\u884C\u53CD\u6C47\u7F16" },
{ "main.opt.classpath", " -classpath <path> \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E" },
{ "main.opt.constants", " -constants \u663E\u793A\u6700\u7EC8\u5E38\u91CF" },
{ "main.opt.cp", " -cp <path> \u6307\u5B9A\u67E5\u627E\u7528\u6237\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E" },
{ "main.opt.help", " -help --help -? \u8F93\u51FA\u6B64\u7528\u6CD5\u6D88\u606F" },
{ "main.opt.l", " -l \u8F93\u51FA\u884C\u53F7\u548C\u672C\u5730\u53D8\u91CF\u8868" },
{ "main.opt.p", " -p -private \u663E\u793A\u6240\u6709\u7C7B\u548C\u6210\u5458" },
{ "main.opt.package", " -package \u663E\u793A\u7A0B\u5E8F\u5305/\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\n \u548C\u6210\u5458 (\u9ED8\u8BA4)" },
{ "main.opt.protected", " -protected \u663E\u793A\u53D7\u4FDD\u62A4\u7684/\u516C\u5171\u7C7B\u548C\u6210\u5458" },
{ "main.opt.public", " -public \u4EC5\u663E\u793A\u516C\u5171\u7C7B\u548C\u6210\u5458" },
{ "main.opt.s", " -s \u8F93\u51FA\u5185\u90E8\u7C7B\u578B\u7B7E\u540D" },
{ "main.opt.sysinfo", " -sysinfo \u663E\u793A\u6B63\u5728\u5904\u7406\u7684\u7C7B\u7684\n \u7CFB\u7EDF\u4FE1\u606F (\u8DEF\u5F84, \u5927\u5C0F, \u65E5\u671F, MD5 \u6563\u5217)" },
{ "main.opt.v", " -v -verbose \u8F93\u51FA\u9644\u52A0\u4FE1\u606F" },
{ "main.opt.version", " -version \u7248\u672C\u4FE1\u606F" },
{ "main.usage", "\u7528\u6CD5: {0} <options> <classes>\n\u5176\u4E2D, \u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:" },
{ "main.usage.summary", "\u7528\u6CD5: {0} <options> <classes>\n\u4F7F\u7528 -help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879" },
{ "note.prefix", "\u6CE8:" },
{ "warn.prefix", "\u8B66\u544A:" },
{ "warn.unexpected.class", "\u4E8C\u8FDB\u5236\u6587\u4EF6{0}\u5305\u542B{1}" },
};
}
}

View File

@@ -0,0 +1,11 @@
package com.sun.tools.javap.resources;
public final class version extends java.util.ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "full", "1.8.0_462-b08" },
{ "jdk", "1.8.0_462" },
{ "release", "1.8.0_462" },
};
}
}