Merge
This commit is contained in:
commit
d550e02d46
@ -76,6 +76,10 @@ public class AccessFlags {
|
||||
return (flags & mask) != 0;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
private static final int[] classModifiers = {
|
||||
ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
|
||||
};
|
||||
|
@ -166,6 +166,10 @@ public abstract class Attribute {
|
||||
|
||||
public abstract <R,D> R accept(Attribute.Visitor<R,D> visitor, D data);
|
||||
|
||||
public int byteLength() {
|
||||
return 6 + attribute_length;
|
||||
}
|
||||
|
||||
public final int attribute_name_index;
|
||||
public final int attribute_length;
|
||||
|
||||
|
@ -95,6 +95,13 @@ public class Attributes implements Iterable<Attribute> {
|
||||
return attrs.length;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
int length = 2;
|
||||
for (Attribute a: attrs)
|
||||
length += a.byteLength();
|
||||
return length;
|
||||
}
|
||||
|
||||
public final Attribute[] attrs;
|
||||
public final Map<String, Attribute> map;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class CharacterRangeTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public CharacterRangeTable_attribute(int name_index, Entry[] character_range_table) {
|
||||
super(name_index, character_range_table.length * Entry.length());
|
||||
super(name_index, 2 + character_range_table.length * Entry.length());
|
||||
this.character_range_table = character_range_table;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,38 @@ public class ClassFile {
|
||||
return access_flags.is(ACC_INTERFACE);
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 4 + // magic
|
||||
2 + // minor
|
||||
2 + // major
|
||||
constant_pool.byteLength() +
|
||||
2 + // access flags
|
||||
2 + // this_class
|
||||
2 + // super_class
|
||||
byteLength(interfaces) +
|
||||
byteLength(fields) +
|
||||
byteLength(methods) +
|
||||
attributes.byteLength();
|
||||
}
|
||||
|
||||
private int byteLength(int[] indices) {
|
||||
return 2 + 2 * indices.length;
|
||||
}
|
||||
|
||||
private int byteLength(Field[] fields) {
|
||||
int length = 2;
|
||||
for (Field f: fields)
|
||||
length += f.byteLength();
|
||||
return length;
|
||||
}
|
||||
|
||||
private int byteLength(Method[] methods) {
|
||||
int length = 2;
|
||||
for (Method m: methods)
|
||||
length += m.byteLength();
|
||||
return length;
|
||||
}
|
||||
|
||||
public final int magic;
|
||||
public final int minor_version;
|
||||
public final int major_version;
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
@ -179,6 +181,16 @@ public class ConstantPool {
|
||||
return pool.length;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
int length = 2;
|
||||
for (int i = 1; i < size(); ) {
|
||||
CPInfo cpInfo = pool[i];
|
||||
length += cpInfo.byteLength();
|
||||
i += cpInfo.size();
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public CPInfo get(int index) throws InvalidIndex {
|
||||
if (index <= 0 || index >= pool.length)
|
||||
throw new InvalidIndex(index);
|
||||
@ -291,6 +303,8 @@ public class ConstantPool {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public abstract int byteLength();
|
||||
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
protected final ConstantPool cp;
|
||||
@ -315,6 +329,10 @@ public class ConstantPool {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
|
||||
return cp.getClassInfo(class_index);
|
||||
}
|
||||
@ -347,6 +365,10 @@ public class ConstantPool {
|
||||
return CONSTANT_Class;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public String getName() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
@ -390,6 +412,10 @@ public class ConstantPool {
|
||||
return CONSTANT_Double;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 2;
|
||||
@ -439,6 +465,10 @@ public class ConstantPool {
|
||||
return CONSTANT_Float;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Float_info[value: " + value + "]";
|
||||
@ -464,6 +494,10 @@ public class ConstantPool {
|
||||
return CONSTANT_Integer;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Integer_info[value: " + value + "]";
|
||||
@ -513,6 +547,10 @@ public class ConstantPool {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Long_info[value: " + value + "]";
|
||||
@ -561,6 +599,10 @@ public class ConstantPool {
|
||||
return CONSTANT_NameAndType;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public String getName() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
@ -597,6 +639,10 @@ public class ConstantPool {
|
||||
return CONSTANT_String;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public String getString() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(string_index);
|
||||
}
|
||||
@ -626,6 +672,20 @@ public class ConstantPool {
|
||||
return CONSTANT_Utf8;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
class SizeOutputStream extends OutputStream {
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
size++;
|
||||
}
|
||||
int size;
|
||||
}
|
||||
SizeOutputStream sizeOut = new SizeOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(sizeOut);
|
||||
try { out.writeUTF(value); } catch (IOException ignore) { }
|
||||
return 1 + sizeOut.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (value.length() < 32 && isPrintableAscii(value))
|
||||
|
@ -260,9 +260,6 @@ public class ExtendedAnnotation {
|
||||
// For generic/array types.
|
||||
public List<Integer> location = new ArrayList<Integer>();
|
||||
|
||||
// Tree position.
|
||||
public int pos = -1;
|
||||
|
||||
// For typecasts, type tests, new (and locals, as start_pc).
|
||||
public int offset = -1;
|
||||
|
||||
@ -391,9 +388,6 @@ public class ExtendedAnnotation {
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
sb.append(", pos = ");
|
||||
sb.append(pos);
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ public class Field {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 6 + attributes.byteLength();
|
||||
}
|
||||
|
||||
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(name_index);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class LineNumberTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public LineNumberTable_attribute(int name_index, Entry[] line_number_table) {
|
||||
super(name_index, line_number_table.length * Entry.length());
|
||||
super(name_index, 2 + line_number_table.length * Entry.length());
|
||||
this.line_number_table_length = line_number_table.length;
|
||||
this.line_number_table = line_number_table;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class LocalVariableTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public LocalVariableTable_attribute(int name_index, Entry[] local_variable_table) {
|
||||
super(name_index, local_variable_table.length * Entry.length());
|
||||
super(name_index, 2 + local_variable_table.length * Entry.length());
|
||||
this.local_variable_table_length = local_variable_table.length;
|
||||
this.local_variable_table = local_variable_table;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class LocalVariableTypeTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public LocalVariableTypeTable_attribute(int name_index, Entry[] local_variable_table) {
|
||||
super(name_index, local_variable_table.length * Entry.length());
|
||||
super(name_index, 2 + local_variable_table.length * Entry.length());
|
||||
this.local_variable_table_length = local_variable_table.length;
|
||||
this.local_variable_table = local_variable_table;
|
||||
}
|
||||
|
@ -50,6 +50,10 @@ public class Method {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public int byteLength() {
|
||||
return 6 + attributes.byteLength();
|
||||
}
|
||||
|
||||
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(name_index);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class ModuleExportTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public ModuleExportTable_attribute(int name_index, int[] export_type_table) {
|
||||
super(name_index, 2 * export_type_table.length);
|
||||
super(name_index, 2 + 2 * export_type_table.length);
|
||||
this.export_type_table = export_type_table;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class ModuleMemberTable_attribute extends Attribute {
|
||||
}
|
||||
|
||||
public ModuleMemberTable_attribute(int name_index, int[] package_member_table) {
|
||||
super(name_index, 2 * package_member_table.length);
|
||||
super(name_index, 2 + 2 * package_member_table.length);
|
||||
this.package_member_table = package_member_table;
|
||||
}
|
||||
|
||||
|
@ -1197,21 +1197,9 @@ public abstract class Symbol implements Element {
|
||||
* as possible implementations.
|
||||
*/
|
||||
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
|
||||
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
|
||||
while (t.tag == TYPEVAR)
|
||||
t = t.getUpperBound();
|
||||
TypeSymbol c = t.tsym;
|
||||
for (Scope.Entry e = c.members().lookup(name);
|
||||
e.scope != null;
|
||||
e = e.next()) {
|
||||
if (e.sym.kind == MTH) {
|
||||
MethodSymbol m = (MethodSymbol) e.sym;
|
||||
if (m.overrides(this, origin, types, checkResult) &&
|
||||
(m.flags() & SYNTHETIC) == 0)
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodSymbol res = types.implementation(this, origin, types, checkResult);
|
||||
if (res != null)
|
||||
return res;
|
||||
// if origin is derived from a raw type, we might have missed
|
||||
// an implementation because we do not know enough about instantiations.
|
||||
// in this case continue with the supertype as origin.
|
||||
|
@ -25,10 +25,9 @@
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.*;
|
||||
|
||||
import com.sun.tools.javac.api.Messages;
|
||||
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
@ -1442,7 +1441,7 @@ public class Types {
|
||||
return (sym.flags() & STATIC) != 0
|
||||
? sym.type
|
||||
: memberType.visit(t, sym);
|
||||
}
|
||||
}
|
||||
// where
|
||||
private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
|
||||
|
||||
@ -1552,7 +1551,7 @@ public class Types {
|
||||
return t; /* fast special case */
|
||||
else
|
||||
return erasure.visit(t, recurse);
|
||||
}
|
||||
}
|
||||
// where
|
||||
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
|
||||
public Type visitType(Type t, Boolean recurse) {
|
||||
@ -1946,6 +1945,45 @@ public class Types {
|
||||
hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
|
||||
}
|
||||
|
||||
private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_check =
|
||||
new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
|
||||
|
||||
private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_nocheck =
|
||||
new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
|
||||
|
||||
public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) {
|
||||
Map<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache = checkResult ?
|
||||
implCache_check : implCache_nocheck;
|
||||
SoftReference<Map<TypeSymbol, MethodSymbol>> ref_cache = implCache.get(ms);
|
||||
Map<TypeSymbol, MethodSymbol> cache = ref_cache != null ? ref_cache.get() : null;
|
||||
if (cache == null) {
|
||||
cache = new HashMap<TypeSymbol, MethodSymbol>();
|
||||
implCache.put(ms, new SoftReference<Map<TypeSymbol, MethodSymbol>>(cache));
|
||||
}
|
||||
MethodSymbol impl = cache.get(origin);
|
||||
if (impl == null) {
|
||||
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
|
||||
while (t.tag == TYPEVAR)
|
||||
t = t.getUpperBound();
|
||||
TypeSymbol c = t.tsym;
|
||||
for (Scope.Entry e = c.members().lookup(ms.name);
|
||||
e.scope != null;
|
||||
e = e.next()) {
|
||||
if (e.sym.kind == Kinds.MTH) {
|
||||
MethodSymbol m = (MethodSymbol) e.sym;
|
||||
if (m.overrides(ms, origin, types, checkResult) &&
|
||||
(m.flags() & SYNTHETIC) == 0) {
|
||||
impl = m;
|
||||
cache.put(origin, m);
|
||||
return impl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does t have the same arguments as s? It is assumed that both
|
||||
* types are (possibly polymorphic) method types. Monomorphic
|
||||
|
@ -1040,15 +1040,6 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||
try {
|
||||
enterTypeAnnotations(annotations);
|
||||
|
||||
// enrich type parameter symbols... easier for annotation processors
|
||||
if (tree instanceof JCTypeParameter) {
|
||||
JCTypeParameter typeparam = (JCTypeParameter)tree;
|
||||
ListBuffer<Attribute.Compound> buf = ListBuffer.lb();
|
||||
for (JCTypeAnnotation anno : annotations)
|
||||
buf.add(anno.attribute_field);
|
||||
typeparam.type.tsym.attributes_field = buf.toList();
|
||||
}
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
|
@ -817,6 +817,23 @@ public class TransTypes extends TreeTranslator {
|
||||
pop();
|
||||
}
|
||||
|
||||
private boolean inClass = false;
|
||||
|
||||
@Override
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
if (!inClass) {
|
||||
// Do not recurse into nested and inner classes since
|
||||
// TransTypes.visitClassDef makes an invocation for each class
|
||||
// separately.
|
||||
inClass = true;
|
||||
try {
|
||||
super.visitClassDef(tree);
|
||||
} finally {
|
||||
inClass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame,
|
||||
List<JCTree> path, TypeAnnotationPosition p) {
|
||||
switch (frame.getKind()) {
|
||||
|
@ -1003,7 +1003,7 @@ compiler.misc.inferred.do.not.conform.to.bounds=\
|
||||
inferred: {0}\n\
|
||||
bound(s): {1}
|
||||
compiler.misc.inferred.do.not.conform.to.params=\
|
||||
actual arguments do not conforms to inferred formal arguments\n\
|
||||
actual arguments do not conform to inferred formal arguments\n\
|
||||
required: {0}\n\
|
||||
found: {1}
|
||||
|
||||
|
@ -208,6 +208,32 @@ public class RichDiagnosticFormatter extends
|
||||
}
|
||||
return clauses.reverse();
|
||||
}
|
||||
|
||||
private int indexOf(Type type, WhereClauseKind kind) {
|
||||
int index = 1;
|
||||
for (Type t : whereClauses.get(kind).keySet()) {
|
||||
if (t.tsym == type.tsym) {
|
||||
return index;
|
||||
}
|
||||
if (kind != WhereClauseKind.TYPEVAR ||
|
||||
t.toString().equals(type.toString())) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean unique(TypeVar typevar) {
|
||||
int found = 0;
|
||||
for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
|
||||
if (t.toString().equals(typevar.toString())) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < 1)
|
||||
throw new AssertionError("Missing type variable in where clause " + typevar);
|
||||
return found == 1;
|
||||
}
|
||||
//where
|
||||
/**
|
||||
* This enum defines all posssible kinds of where clauses that can be
|
||||
@ -366,33 +392,6 @@ public class RichDiagnosticFormatter extends
|
||||
}
|
||||
}
|
||||
|
||||
private int indexOf(Type type, WhereClauseKind kind) {
|
||||
int index = 0;
|
||||
boolean found = false;
|
||||
for (Type t : whereClauses.get(kind).keySet()) {
|
||||
if (t == type) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (!found)
|
||||
throw new AssertionError("Missing symbol in where clause " + type);
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
private boolean unique(TypeVar typevar) {
|
||||
int found = 0;
|
||||
for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
|
||||
if (t.toString().equals(typevar.toString())) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < 1)
|
||||
throw new AssertionError("Missing type variable in where clause " + typevar);
|
||||
return found == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
|
||||
return super.printMethodArgs(args, varArgs, locale);
|
||||
@ -492,7 +491,7 @@ public class RichDiagnosticFormatter extends
|
||||
|
||||
@Override
|
||||
public Void visitCapturedType(CapturedType t, Void ignored) {
|
||||
if (!whereClauses.get(WhereClauseKind.CAPTURED).containsKey(t)) {
|
||||
if (indexOf(t, WhereClauseKind.CAPTURED) == -1) {
|
||||
String suffix = t.lower == syms.botType ? ".1" : "";
|
||||
JCDiagnostic d = diags.fragment("where.captured"+ suffix, t, t.bound, t.lower, t.wildcard);
|
||||
whereClauses.get(WhereClauseKind.CAPTURED).put(t, d);
|
||||
@ -506,7 +505,7 @@ public class RichDiagnosticFormatter extends
|
||||
@Override
|
||||
public Void visitClassType(ClassType t, Void ignored) {
|
||||
if (t.isCompound()) {
|
||||
if (!whereClauses.get(WhereClauseKind.INTERSECTION).containsKey(t)) {
|
||||
if (indexOf(t, WhereClauseKind.INTERSECTION) == -1) {
|
||||
Type supertype = types.supertype(t);
|
||||
List<Type> interfaces = types.interfaces(t);
|
||||
JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype));
|
||||
@ -524,11 +523,17 @@ public class RichDiagnosticFormatter extends
|
||||
|
||||
@Override
|
||||
public Void visitTypeVar(TypeVar t, Void ignored) {
|
||||
if (!whereClauses.get(WhereClauseKind.TYPEVAR).containsKey(t)) {
|
||||
if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
|
||||
//access the bound type and skip error types
|
||||
Type bound = t.bound;
|
||||
while ((bound instanceof ErrorType))
|
||||
bound = ((ErrorType)bound).getOriginalType();
|
||||
List<Type> bounds = types.getBounds(t);
|
||||
//retrieve the bound list - if the type variable
|
||||
//has not been attributed the bound is not set
|
||||
List<Type> bounds = bound != null ?
|
||||
types.getBounds(t) :
|
||||
List.<Type>nil();
|
||||
|
||||
nameSimplifier.addUsage(t.tsym);
|
||||
|
||||
boolean boundErroneous = bounds.head == null ||
|
||||
|
@ -32,6 +32,10 @@ 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.
|
||||
@ -51,71 +55,243 @@ public class AnnotationWriter extends BasicWriter {
|
||||
|
||||
protected AnnotationWriter(Context context) {
|
||||
super(context);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
}
|
||||
|
||||
public void write(Annotation annot) {
|
||||
print("#" + annot.type_index + "(");
|
||||
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]);
|
||||
write(annot.element_value_pairs[i], resolveIndices);
|
||||
}
|
||||
print(")");
|
||||
if (showParens)
|
||||
print(")");
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation annot) {
|
||||
write(annot.annotation);
|
||||
print('@');
|
||||
print(annot.position.toString());
|
||||
write(annot, true, false);
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation annot, boolean showOffsets, boolean resolveIndices) {
|
||||
write(annot.annotation, resolveIndices);
|
||||
print(": ");
|
||||
write(annot.position, showOffsets);
|
||||
}
|
||||
|
||||
public void write(ExtendedAnnotation.Position pos, boolean showOffsets) {
|
||||
print(pos.type);
|
||||
|
||||
switch (pos.type) {
|
||||
// type case
|
||||
case TYPECAST:
|
||||
case TYPECAST_GENERIC_OR_ARRAY:
|
||||
// object creation
|
||||
case INSTANCEOF:
|
||||
case INSTANCEOF_GENERIC_OR_ARRAY:
|
||||
// new expression
|
||||
case NEW:
|
||||
case NEW_GENERIC_OR_ARRAY:
|
||||
case NEW_TYPE_ARGUMENT:
|
||||
case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
if (showOffsets) {
|
||||
print(", offset=");
|
||||
print(pos.offset);
|
||||
}
|
||||
break;
|
||||
// local variable
|
||||
case LOCAL_VARIABLE:
|
||||
case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
|
||||
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;
|
||||
// method receiver
|
||||
case METHOD_RECEIVER:
|
||||
// Do nothing
|
||||
break;
|
||||
// type parameters
|
||||
case CLASS_TYPE_PARAMETER:
|
||||
case METHOD_TYPE_PARAMETER:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
break;
|
||||
// type parameters bound
|
||||
case CLASS_TYPE_PARAMETER_BOUND:
|
||||
case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
case METHOD_TYPE_PARAMETER_BOUND:
|
||||
case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
print(", bound_index=");
|
||||
print(pos.bound_index);
|
||||
break;
|
||||
// wildcard
|
||||
case WILDCARD_BOUND:
|
||||
case WILDCARD_BOUND_GENERIC_OR_ARRAY:
|
||||
print(", wild_card=");
|
||||
print(pos.wildcard_position);
|
||||
break;
|
||||
// Class extends and implements clauses
|
||||
case CLASS_EXTENDS:
|
||||
case CLASS_EXTENDS_GENERIC_OR_ARRAY:
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
// throws
|
||||
case THROWS:
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
case CLASS_LITERAL:
|
||||
if (showOffsets) {
|
||||
print(", offset=");
|
||||
print(pos.offset);
|
||||
}
|
||||
break;
|
||||
// method parameter: not specified
|
||||
case METHOD_PARAMETER_GENERIC_OR_ARRAY:
|
||||
print(", param_index=");
|
||||
print(pos.parameter_index);
|
||||
break;
|
||||
// method type argument: wasn't specified
|
||||
case METHOD_TYPE_ARGUMENT:
|
||||
case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
|
||||
if (showOffsets) {
|
||||
print(", offset=");
|
||||
print(pos.offset);
|
||||
}
|
||||
print(", type_index=");
|
||||
print(pos.type_index);
|
||||
break;
|
||||
// We don't need to worry abut these
|
||||
case METHOD_RETURN_GENERIC_OR_ARRAY:
|
||||
case FIELD_GENERIC_OR_ARRAY:
|
||||
break;
|
||||
case UNKNOWN:
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("unknown type: " + pos.type);
|
||||
}
|
||||
|
||||
// Append location data for generics/arrays.
|
||||
if (pos.type.hasLocation()) {
|
||||
print(", location=");
|
||||
print(pos.location);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Annotation.element_value_pair pair) {
|
||||
print("#" + pair.element_name_index + ":");
|
||||
write(pair.value);
|
||||
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) {
|
||||
ev_writer.write(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,Void> {
|
||||
public void write(Annotation.element_value value) {
|
||||
value.accept(this, null);
|
||||
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, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.const_value_index);
|
||||
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, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
|
||||
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, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.class_info_index);
|
||||
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, Void p) {
|
||||
public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) {
|
||||
print((char) ev.tag);
|
||||
AnnotationWriter.this.write(ev.annotation_value);
|
||||
AnnotationWriter.this.write(ev.annotation_value, resolveIndices);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitArray(Array_element_value ev, Void p) {
|
||||
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]);
|
||||
write(ev.values[i], resolveIndices);
|
||||
}
|
||||
print("]");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ClassWriter classWriter;
|
||||
private ConstantWriter constantWriter;
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ 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.Field;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||
import com.sun.tools.classfile.LineNumberTable_attribute;
|
||||
import com.sun.tools.classfile.LocalVariableTable_attribute;
|
||||
@ -149,22 +148,26 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
|
||||
println(" AnnotationDefault: ");
|
||||
print(" default_value: ");
|
||||
println("AnnotationDefault:");
|
||||
indent(+1);
|
||||
print("default_value: ");
|
||||
annotationWriter.write(attr.default_value);
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
|
||||
print(" CharacterRangeTable: ");
|
||||
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(" " + e.start_pc + ", " +
|
||||
e.end_pc + ", " +
|
||||
Integer.toHexString(e.character_range_start) + ", " +
|
||||
Integer.toHexString(e.character_range_end) + ", " +
|
||||
Integer.toHexString(e.flags) +
|
||||
"\t// ");
|
||||
Integer.toHexString(e.flags));
|
||||
tab();
|
||||
print("// ");
|
||||
print(e.start_pc + ", " +
|
||||
e.end_pc + ", " +
|
||||
(e.character_range_start >> 10) + ":" + (e.character_range_start & 0x3ff) + ", " +
|
||||
@ -187,16 +190,13 @@ public class AttributeWriter extends BasicWriter
|
||||
print(", branch-true");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
|
||||
print(", branch-false");
|
||||
|
||||
|
||||
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCode(Code_attribute attr, Void ignore) {
|
||||
codeWriter.write(attr, constant_pool);
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -207,25 +207,23 @@ public class AttributeWriter extends BasicWriter
|
||||
|
||||
public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
|
||||
if (options.compat) // BUG 6622216 javap names some attributes incorrectly
|
||||
print(" Constant value: ");
|
||||
print("Constant value: ");
|
||||
else
|
||||
print(" ConstantValue: ");
|
||||
print("ConstantValue: ");
|
||||
constantWriter.write(attr.constantvalue_index);
|
||||
if (!options.compat) // BUG 6622232 javap gets whitespace confused
|
||||
println();
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitDeprecated(Deprecated_attribute attr, Void ignore) {
|
||||
if (!(options.compat && owner instanceof Field)) // BUG 6622232 javap gets whitespace confused
|
||||
print(" ");
|
||||
println("Deprecated: true");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) {
|
||||
print(" EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index
|
||||
+ "\t// " + getJavaClassName(attr));
|
||||
print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index);
|
||||
tab();
|
||||
print("// " + getJavaClassName(attr));
|
||||
if (attr.method_index != 0)
|
||||
print("." + getMethodName(attr));
|
||||
println();
|
||||
@ -249,15 +247,16 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
|
||||
println(" Exceptions: ");
|
||||
print(" throws ");
|
||||
println("Exceptions:");
|
||||
indent(+1);
|
||||
print("throws ");
|
||||
for (int i = 0; i < attr.number_of_exceptions; i++) {
|
||||
if (i > 0)
|
||||
print(", ");
|
||||
print(getJavaException(attr, i));
|
||||
}
|
||||
if (!options.compat) // BUG 6622232 javap gets whitespace confused
|
||||
println();
|
||||
println();
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -290,8 +289,7 @@ public class AttributeWriter extends BasicWriter
|
||||
writeInnerClassHeader();
|
||||
first = false;
|
||||
}
|
||||
if (!options.compat) // BUG 6622232: javap gets whitespace confused
|
||||
print(" ");
|
||||
print(" ");
|
||||
for (String name: access_flags.getInnerClassModifiers())
|
||||
print(name + " ");
|
||||
if (info.inner_name_index!=0) {
|
||||
@ -313,6 +311,8 @@ public class AttributeWriter extends BasicWriter
|
||||
println();
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -325,26 +325,28 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
private void writeInnerClassHeader() {
|
||||
print(" ");
|
||||
if (options.compat) // BUG 6622216: javap names some attributes incorrectly
|
||||
print("InnerClass");
|
||||
else
|
||||
print("InnerClasses");
|
||||
println(": ");
|
||||
println(":");
|
||||
indent(+1);
|
||||
}
|
||||
|
||||
public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
|
||||
println(" LineNumberTable: ");
|
||||
println("LineNumberTable:");
|
||||
indent(+1);
|
||||
for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
|
||||
println(" line " + entry.line_number + ": " + entry.start_pc);
|
||||
println("line " + entry.line_number + ": " + entry.start_pc);
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
|
||||
println(" LocalVariableTable: ");
|
||||
println(" Start Length Slot Name Signature");
|
||||
|
||||
println("LocalVariableTable:");
|
||||
indent(+1);
|
||||
println("Start Length Slot Name Signature");
|
||||
for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) {
|
||||
Formatter formatter = new Formatter();
|
||||
println(formatter.format("%8d %7d %5d %5s %s",
|
||||
@ -352,25 +354,28 @@ public class AttributeWriter extends BasicWriter
|
||||
constantWriter.stringValue(entry.name_index),
|
||||
constantWriter.stringValue(entry.descriptor_index)));
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
|
||||
println(" LocalVariableTypeTable: ");
|
||||
println(" Start Length Slot Name Signature");
|
||||
|
||||
println("LocalVariableTypeTable:");
|
||||
indent(+1);
|
||||
println("Start Length Slot Name Signature");
|
||||
for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) {
|
||||
Formatter formatter = new Formatter();
|
||||
println(formatter.format("%8d %7d %5d %5s %s",
|
||||
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;
|
||||
}
|
||||
|
||||
public Void visitModule(Module_attribute attr, Void ignore) {
|
||||
println(" Module: #" + attr.module_name + "\t// " + getModuleName(attr));
|
||||
print("Module: #" + attr.module_name);
|
||||
tab();
|
||||
println("// " + getModuleName(attr));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -383,11 +388,15 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitModuleExportTable(ModuleExportTable_attribute attr, Void ignore) {
|
||||
println(" ModuleExportTable:");
|
||||
println(" Types: (" + attr.export_type_table.length + ")");
|
||||
println("ModuleExportTable:");
|
||||
indent(+1);
|
||||
println("Types: (" + attr.export_type_table.length + ")");
|
||||
for (int i = 0; i < attr.export_type_table.length; i++) {
|
||||
println(" #" + attr.export_type_table[i] + "\t// " + getExportTypeName(attr, i));
|
||||
print("#" + attr.export_type_table[i]);
|
||||
tab();
|
||||
println("// " + getExportTypeName(attr, i));
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -400,11 +409,15 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, Void ignore) {
|
||||
println(" ModuleMemberTable:");
|
||||
println(" Packages: (" + attr.package_member_table.length + ")");
|
||||
println("ModuleMemberTable:");
|
||||
indent(+1);
|
||||
println("Packages: (" + attr.package_member_table.length + ")");
|
||||
for (int i = 0; i < attr.package_member_table.length; i++) {
|
||||
println(" #" + attr.package_member_table[i] + "\t// " + getPackageMemberName(attr, i));
|
||||
print("#" + attr.package_member_table[i]);
|
||||
tab();
|
||||
println("// " + getPackageMemberName(attr, i));
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -417,73 +430,91 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleAnnotations: ");
|
||||
println("RuntimeVisibleAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeInvisibleAnnotations: ");
|
||||
println("RuntimeInvisibleAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleTypeAnnotations: ");
|
||||
println("RuntimeVisibleTypeAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeInvisibleTypeAnnotations: ");
|
||||
println("RuntimeInvisibleTypeAnnotations:");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
print(i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleParameterAnnotations: ");
|
||||
println("RuntimeVisibleParameterAnnotations:");
|
||||
indent(+1);
|
||||
for (int param = 0; param < attr.parameter_annotations.length; param++) {
|
||||
println(" parameter " + param + ": ");
|
||||
println("parameter " + param + ": ");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
|
||||
print(" " + 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: ");
|
||||
println("RuntimeInvisibleParameterAnnotations:");
|
||||
indent(+1);
|
||||
for (int param = 0; param < attr.parameter_annotations.length; param++) {
|
||||
println(" " + param + ": ");
|
||||
println(param + ": ");
|
||||
indent(+1);
|
||||
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
|
||||
print(" " + 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) {
|
||||
println(" Signature: #" + attr.signature_index + "\t// " + getSignature(attr));
|
||||
print("Signature: #" + attr.signature_index);
|
||||
tab();
|
||||
println("// " + getSignature(attr));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -496,12 +527,12 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
|
||||
println(" SourceDebugExtension: " + attr.getValue());
|
||||
println("SourceDebugExtension: " + attr.getValue());
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
|
||||
println(" SourceFile: \"" + getSourceFile(attr) + "\"");
|
||||
println("SourceFile: \"" + getSourceFile(attr) + "\"");
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -519,24 +550,26 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
public Void visitStackMap(StackMap_attribute attr, Void ignore) {
|
||||
println(" StackMap: number_of_entries = " + attr.number_of_entries);
|
||||
|
||||
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);
|
||||
}
|
||||
println();
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
|
||||
println(" StackMapTable: number_of_entries = " + attr.number_of_entries);
|
||||
|
||||
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);
|
||||
}
|
||||
println();
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -555,29 +588,37 @@ public class AttributeWriter extends BasicWriter
|
||||
public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* 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);
|
||||
println(" /* same_locals_1_stack_item_frame_extended */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
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);
|
||||
println(" /* chop */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
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);
|
||||
println(" /* same_frame_extended */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
indent(+1);
|
||||
println("offset_delta = " + frame.offset_delta);
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -592,13 +633,16 @@ public class AttributeWriter extends BasicWriter
|
||||
public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
if (frame instanceof StackMap_attribute.stack_map_frame) {
|
||||
println(" offset = " + frame.offset_delta);
|
||||
indent(+1);
|
||||
println(" offset = " + frame.offset_delta);
|
||||
} else {
|
||||
println(" /* full_frame */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
indent(+1);
|
||||
println("offset_delta = " + frame.offset_delta);
|
||||
}
|
||||
printMap("locals", frame.locals);
|
||||
printMap("stack", frame.stack);
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -607,7 +651,7 @@ public class AttributeWriter extends BasicWriter
|
||||
}
|
||||
|
||||
void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
|
||||
print(" " + name + " = [");
|
||||
print(name + " = [");
|
||||
for (int i = 0; i < map.length; i++) {
|
||||
StackMapTable_attribute.verification_type_info info = map[i];
|
||||
int tag = info.tag;
|
||||
|
@ -71,6 +71,18 @@ public class BasicWriter {
|
||||
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 "???";
|
||||
@ -122,19 +134,30 @@ public class BasicWriter {
|
||||
|
||||
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);
|
||||
if (c == '\n') {
|
||||
println();
|
||||
} else {
|
||||
buffer.append(c);
|
||||
switch (c) {
|
||||
case '\n':
|
||||
println();
|
||||
break;
|
||||
default:
|
||||
if (buffer.length() == 0)
|
||||
indent();
|
||||
buffer.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,8 +168,31 @@ public class BasicWriter {
|
||||
buffer.setLength(0);
|
||||
}
|
||||
|
||||
protected void indent(int delta) {
|
||||
indentCount += delta;
|
||||
}
|
||||
|
||||
protected void tab() {
|
||||
if (buffer.length() == 0)
|
||||
indent();
|
||||
space(indentCount * indentWidth + tabColumn - buffer.length());
|
||||
}
|
||||
|
||||
private void indent() {
|
||||
space(indentCount * indentWidth);
|
||||
}
|
||||
|
||||
private void space(int n) {
|
||||
for (int i = 0; i < n; i++)
|
||||
buffer.append(' ');
|
||||
}
|
||||
|
||||
private PrintWriter out;
|
||||
private StringBuilder buffer;
|
||||
private int indentCount;
|
||||
private int indentWidth;
|
||||
private int tabColumn;
|
||||
private boolean pendingNewline;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,7 @@ public class ClassWriter extends BasicWriter {
|
||||
else
|
||||
println("Classfile " + uri);
|
||||
}
|
||||
indent(+1);
|
||||
if (lastModified != -1) {
|
||||
Date lm = new Date(lastModified);
|
||||
DateFormat df = DateFormat.getDateInstance();
|
||||
@ -144,6 +145,10 @@ public class ClassWriter extends BasicWriter {
|
||||
println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
|
||||
}
|
||||
|
||||
if ((options.sysInfo || options.verbose) && !options.compat) {
|
||||
indent(-1);
|
||||
}
|
||||
|
||||
String name = getJavaName(classFile);
|
||||
AccessFlags flags = cf.access_flags;
|
||||
|
||||
@ -186,23 +191,24 @@ public class ClassWriter extends BasicWriter {
|
||||
|
||||
if (options.verbose) {
|
||||
println();
|
||||
indent(+1);
|
||||
attrWriter.write(cf, cf.attributes, constant_pool);
|
||||
println(" minor version: " + cf.minor_version);
|
||||
println(" major version: " + cf.major_version);
|
||||
println("minor version: " + cf.minor_version);
|
||||
println("major version: " + cf.major_version);
|
||||
if (!options.compat)
|
||||
writeList(" flags: ", flags.getClassFlags(), NEWLINE);
|
||||
writeList("flags: ", flags.getClassFlags(), NEWLINE);
|
||||
indent(-1);
|
||||
constantWriter.writeConstantPool();
|
||||
println();
|
||||
} else {
|
||||
if (!options.compat)
|
||||
print(" ");
|
||||
print(" ");
|
||||
}
|
||||
|
||||
println("{");
|
||||
indent(+1);
|
||||
writeFields();
|
||||
writeMethods();
|
||||
indent(-1);
|
||||
println("}");
|
||||
println();
|
||||
}
|
||||
|
||||
protected void writeFields() {
|
||||
@ -215,14 +221,6 @@ public class ClassWriter extends BasicWriter {
|
||||
if (!options.checkAccess(f.access_flags))
|
||||
return;
|
||||
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
|
||||
AccessFlags flags = f.access_flags;
|
||||
writeModifiers(flags.getFieldModifiers());
|
||||
Signature_attribute sigAttr = getSignature(f.attributes);
|
||||
@ -251,11 +249,13 @@ public class ClassWriter extends BasicWriter {
|
||||
print(";");
|
||||
println();
|
||||
|
||||
indent(+1);
|
||||
|
||||
if (options.showInternalSignatures)
|
||||
println(" Signature: " + getValue(f.descriptor));
|
||||
println("Signature: " + getValue(f.descriptor));
|
||||
|
||||
if (options.verbose && !options.compat)
|
||||
writeList(" flags: ", flags.getFieldFlags(), NEWLINE);
|
||||
writeList("flags: ", flags.getFieldFlags(), NEWLINE);
|
||||
|
||||
if (options.showAllAttrs) {
|
||||
for (Attribute attr: f.attributes)
|
||||
@ -263,6 +263,8 @@ public class ClassWriter extends BasicWriter {
|
||||
println();
|
||||
}
|
||||
|
||||
indent(-1);
|
||||
|
||||
if (options.showDisassembled || options.showLineAndLocalVariableTables)
|
||||
println();
|
||||
}
|
||||
@ -270,6 +272,7 @@ public class ClassWriter extends BasicWriter {
|
||||
protected void writeMethods() {
|
||||
for (Method m: classFile.methods)
|
||||
writeMethod(m);
|
||||
setPendingNewline(false);
|
||||
}
|
||||
|
||||
protected void writeMethod(Method m) {
|
||||
@ -278,14 +281,6 @@ public class ClassWriter extends BasicWriter {
|
||||
|
||||
method = m;
|
||||
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
|
||||
AccessFlags flags = m.access_flags;
|
||||
|
||||
Descriptor d;
|
||||
@ -333,16 +328,6 @@ public class ClassWriter extends BasicWriter {
|
||||
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;
|
||||
if (options.compat) { // Bug XXXXXXX whitespace
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
print(" ");
|
||||
}
|
||||
print(" throws ");
|
||||
if (methodExceptions != null) { // use generic list if available
|
||||
writeList("", methodExceptions, "");
|
||||
@ -358,14 +343,17 @@ public class ClassWriter extends BasicWriter {
|
||||
}
|
||||
}
|
||||
|
||||
print(";");
|
||||
println();
|
||||
println(";");
|
||||
|
||||
if (options.showInternalSignatures)
|
||||
println(" Signature: " + getValue(m.descriptor));
|
||||
indent(+1);
|
||||
|
||||
if (options.verbose && !options.compat)
|
||||
writeList(" flags: ", flags.getMethodFlags(), NEWLINE);
|
||||
if (options.showInternalSignatures) {
|
||||
println("Signature: " + getValue(m.descriptor));
|
||||
}
|
||||
|
||||
if (options.verbose && !options.compat) {
|
||||
writeList("flags: ", flags.getMethodFlags(), NEWLINE);
|
||||
}
|
||||
|
||||
Code_attribute code = null;
|
||||
Attribute c_attr = m.attributes.get(Attribute.Code);
|
||||
@ -378,33 +366,35 @@ public class ClassWriter extends BasicWriter {
|
||||
|
||||
if (options.showDisassembled && !options.showAllAttrs) {
|
||||
if (code != null) {
|
||||
println(" Code:");
|
||||
println("Code:");
|
||||
codeWriter.writeInstrs(code);
|
||||
codeWriter.writeExceptionTable(code);
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
if (options.showLineAndLocalVariableTables) {
|
||||
if (code != null)
|
||||
if (code != null) {
|
||||
attrWriter.write(code, code.attributes.get(Attribute.LineNumberTable), constant_pool);
|
||||
println();
|
||||
if (code != null)
|
||||
attrWriter.write(code, code.attributes.get(Attribute.LocalVariableTable), constant_pool);
|
||||
println();
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
if (options.showAllAttrs) {
|
||||
Attribute[] attrs = m.attributes.attrs;
|
||||
for (Attribute attr: attrs)
|
||||
attrWriter.write(m, attr, constant_pool);
|
||||
|
||||
// // the following condition is to mimic old javap
|
||||
// if (!(attrs.length > 0 &&
|
||||
// attrs[attrs.length - 1] instanceof Exceptions_attribute))
|
||||
println();
|
||||
}
|
||||
|
||||
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.showInternalSignatures ||
|
||||
options.showLineAndLocalVariableTables ||
|
||||
options.verbose);
|
||||
}
|
||||
|
||||
void writeModifiers(Collection<String> items) {
|
||||
|
@ -64,15 +64,18 @@ class CodeWriter extends BasicWriter {
|
||||
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:");
|
||||
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) {
|
||||
@ -89,9 +92,9 @@ class CodeWriter extends BasicWriter {
|
||||
argCount = report(e);
|
||||
}
|
||||
|
||||
println(" Stack=" + attr.max_stack +
|
||||
", Locals=" + attr.max_locals +
|
||||
", Args_size=" + argCount);
|
||||
println("stack=" + attr.max_stack +
|
||||
", locals=" + attr.max_locals +
|
||||
", args_size=" + argCount);
|
||||
|
||||
}
|
||||
|
||||
@ -114,8 +117,7 @@ class CodeWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public void writeInstr(Instruction instr) {
|
||||
print(" " + instr.getPC() + ":\t");
|
||||
print(instr.getMnemonic());
|
||||
print(String.format("%4d: %-12s ", instr.getPC(), instr.getMnemonic()));
|
||||
instr.accept(instructionPrinter, null);
|
||||
println();
|
||||
}
|
||||
@ -133,54 +135,62 @@ class CodeWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public Void visitBranch(Instruction instr, int offset, Void p) {
|
||||
print("\t" + (instr.getPC() + offset));
|
||||
print((instr.getPC() + offset));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitConstantPoolRef(Instruction instr, int index, Void p) {
|
||||
print("\t#" + index + "; //");
|
||||
print("#" + index + ";");
|
||||
tab();
|
||||
print("// ");
|
||||
printConstant(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) {
|
||||
print("\t#" + index + ", " + value + "; //");
|
||||
print("#" + index + ", " + value + ";");
|
||||
tab();
|
||||
print("// ");
|
||||
printConstant(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocal(Instruction instr, int index, Void p) {
|
||||
print("\t" + index);
|
||||
print(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) {
|
||||
print("\t" + index + ", " + value);
|
||||
print(index + ", " + value);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) {
|
||||
int pc = instr.getPC();
|
||||
print("{ //" + npairs);
|
||||
print("{ // " + npairs);
|
||||
indent(+1);
|
||||
for (int i = 0; i < npairs; i++) {
|
||||
print("\n\t\t" + matches[i] + ": " + (pc + offsets[i]) + ";");
|
||||
print("\n" + matches[i] + ": " + (pc + offsets[i]) + ";");
|
||||
}
|
||||
print("\n\t\tdefault: " + (pc + default_) + " }");
|
||||
print("\ndefault: " + (pc + default_) + " }");
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) {
|
||||
int pc = instr.getPC();
|
||||
print("{ //" + low + " to " + high);
|
||||
indent(+1);
|
||||
for (int i = 0; i < offsets.length; i++) {
|
||||
print("\n\t\t" + (low + i) + ": " + (pc + offsets[i]) + ";");
|
||||
print("\n" + (low + i) + ": " + (pc + offsets[i]) + ";");
|
||||
}
|
||||
print("\n\t\tdefault: " + (pc + default_) + " }");
|
||||
print("\ndefault: " + (pc + default_) + " }");
|
||||
indent(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitValue(Instruction instr, int value, Void p) {
|
||||
print("\t" + value);
|
||||
print(value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -192,13 +202,13 @@ class CodeWriter extends BasicWriter {
|
||||
|
||||
public void writeExceptionTable(Code_attribute attr) {
|
||||
if (attr.exception_table_langth > 0) {
|
||||
println(" Exception table:");
|
||||
println(" from to target type");
|
||||
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];
|
||||
printFixedWidthInt(handler.start_pc, 6);
|
||||
printFixedWidthInt(handler.end_pc, 6);
|
||||
printFixedWidthInt(handler.handler_pc, 6);
|
||||
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) {
|
||||
@ -206,9 +216,9 @@ class CodeWriter extends BasicWriter {
|
||||
} else {
|
||||
print("Class ");
|
||||
println(constantWriter.stringValue(catch_type));
|
||||
println("");
|
||||
}
|
||||
}
|
||||
indent(-1);
|
||||
}
|
||||
|
||||
}
|
||||
@ -217,13 +227,6 @@ class CodeWriter extends BasicWriter {
|
||||
constantWriter.write(index);
|
||||
}
|
||||
|
||||
private void printFixedWidthInt(int n, int width) {
|
||||
String s = String.valueOf(n);
|
||||
for (int i = s.length(); i < width; i++)
|
||||
print(" ");
|
||||
print(s);
|
||||
}
|
||||
|
||||
private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
|
||||
List<InstructionDetailWriter> detailWriters =
|
||||
new ArrayList<InstructionDetailWriter>();
|
||||
@ -253,6 +256,11 @@ class CodeWriter extends BasicWriter {
|
||||
detailWriters.add(tryBlockWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
|
||||
typeAnnotationWriter.reset(attr);
|
||||
detailWriters.add(typeAnnotationWriter);
|
||||
}
|
||||
|
||||
return detailWriters;
|
||||
}
|
||||
|
||||
@ -261,6 +269,7 @@ class CodeWriter extends BasicWriter {
|
||||
private ConstantWriter constantWriter;
|
||||
private LocalVariableTableWriter localVariableTableWriter;
|
||||
private LocalVariableTypeTableWriter localVariableTypeTableWriter;
|
||||
private TypeAnnotationWriter typeAnnotationWriter;
|
||||
private SourceWriter sourceWriter;
|
||||
private StackMapWriter stackMapWriter;
|
||||
private TryBlockWriter tryBlockWriter;
|
||||
|
@ -62,7 +62,9 @@ public class ConstantWriter extends BasicWriter {
|
||||
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) {
|
||||
println("#" + info.name_index + ";\t// " + stringValue(info));
|
||||
print("#" + info.name_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -72,7 +74,9 @@ public class ConstantWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -87,7 +91,9 @@ public class ConstantWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -97,18 +103,23 @@ public class ConstantWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
|
||||
String tab = (options.compat ? "" : "\t"); // BUG 6622232 javap gets whitespace confused
|
||||
println("#" + info.name_index + ":#" + info.type_index + ";" + tab + "// " + stringValue(info));
|
||||
print("#" + info.name_index + ":#" + info.type_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitString(CONSTANT_String_info info, Void p) {
|
||||
println("#" + info.string_index + ";\t// " + stringValue(info));
|
||||
print("#" + info.string_index + ";");
|
||||
tab();
|
||||
println("// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -118,17 +129,21 @@ public class ConstantWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
};
|
||||
println(" Constant pool:");
|
||||
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("const %" + width + "s", ("#" + cpx)));
|
||||
try {
|
||||
CPInfo cpInfo = constant_pool.get(cpx);
|
||||
print("const #" + cpx + " = " + tagName(cpInfo.getTag()) + "\t");
|
||||
print(String.format(" = %-15s ", tagName(cpInfo.getTag())));
|
||||
cpx += cpInfo.accept(v, null);
|
||||
} catch (ConstantPool.InvalidIndex ex) {
|
||||
print("const #" + cpx); // should not happen
|
||||
// should not happen
|
||||
}
|
||||
}
|
||||
indent(-1);
|
||||
}
|
||||
|
||||
protected void write(int cpx) {
|
||||
|
@ -42,7 +42,8 @@ public abstract class InstructionDetailWriter extends BasicWriter {
|
||||
LOCAL_VAR_TYPES("localVariableTypes"),
|
||||
SOURCE("source"),
|
||||
STACKMAPS("stackMaps"),
|
||||
TRY_BLOCKS("tryBlocks");
|
||||
TRY_BLOCKS("tryBlocks"),
|
||||
TYPE_ANNOS("typeAnnotations");
|
||||
Kind(String option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
@ -41,13 +41,13 @@ import com.sun.tools.javac.util.Context;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
class JavapFileManager extends JavacFileManager {
|
||||
public class JavapFileManager extends JavacFileManager {
|
||||
private JavapFileManager(Context context, Charset charset) {
|
||||
super(context, true, charset);
|
||||
setIgnoreSymbolFile(true);
|
||||
}
|
||||
|
||||
static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) {
|
||||
public static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
|
||||
Context javac_context = new Context();
|
||||
|
||||
if (dl != null)
|
||||
|
@ -32,8 +32,10 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.URI;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -49,6 +51,8 @@ import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.NestingKind;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileManager;
|
||||
@ -57,6 +61,9 @@ import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* "Main" class for javap, normally accessed from the command line
|
||||
@ -289,6 +296,44 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showConstants = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDinner") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showInnerClasses = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDindent:") {
|
||||
@Override
|
||||
boolean matches(String opt) {
|
||||
int sep = opt.indexOf(":");
|
||||
return sep != -1 && super.matches(opt.substring(0, sep + 1));
|
||||
}
|
||||
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
int sep = opt.indexOf(":");
|
||||
try {
|
||||
task.options.indentWidth = Integer.valueOf(opt.substring(sep + 1));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDtab:") {
|
||||
@Override
|
||||
boolean matches(String opt) {
|
||||
int sep = opt.indexOf(":");
|
||||
return sep != -1 && super.matches(opt.substring(0, sep + 1));
|
||||
}
|
||||
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
int sep = opt.indexOf(":");
|
||||
try {
|
||||
task.options.tabColumn = Integer.valueOf(opt.substring(sep + 1));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@ -316,17 +361,17 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
Iterable<String> classes) {
|
||||
this(out, fileManager, diagnosticListener);
|
||||
|
||||
try {
|
||||
handleOptions(options, false);
|
||||
} catch (BadArgs e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
|
||||
this.classes = new ArrayList<String>();
|
||||
for (String classname: classes) {
|
||||
classname.getClass(); // null-check
|
||||
this.classes.add(classname);
|
||||
}
|
||||
|
||||
try {
|
||||
handleOptions(options, false);
|
||||
} catch (BadArgs e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale) {
|
||||
@ -372,10 +417,18 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
final PrintWriter pw = getPrintWriterForWriter(w);
|
||||
return new DiagnosticListener<JavaFileObject> () {
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||
switch (diagnostic.getKind()) {
|
||||
case ERROR:
|
||||
pw.print(getMessage("err.prefix"));
|
||||
pw.print(" ");
|
||||
break;
|
||||
case WARNING:
|
||||
pw.print(getMessage("warn.prefix"));
|
||||
break;
|
||||
case NOTE:
|
||||
pw.print(getMessage("note.prefix"));
|
||||
break;
|
||||
}
|
||||
pw.print(" ");
|
||||
pw.println(diagnostic.getMessage(null));
|
||||
}
|
||||
};
|
||||
@ -405,7 +458,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
boolean ok = run();
|
||||
return ok ? EXIT_OK : EXIT_ERROR;
|
||||
} catch (BadArgs e) {
|
||||
diagnosticListener.report(createDiagnostic(e.key, e.args));
|
||||
reportError(e.key, e.args);
|
||||
if (e.showUsage) {
|
||||
log.println(getMessage("main.usage.summary", progname));
|
||||
}
|
||||
@ -419,7 +472,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
e_args[0] = e.getCause();
|
||||
System.arraycopy(e.args, 0, e_args, 1, e.args.length);
|
||||
}
|
||||
diagnosticListener.report(createDiagnostic("err.internal.error", e_args));
|
||||
reportError("err.internal.error", e_args);
|
||||
return EXIT_ABNORMAL;
|
||||
} finally {
|
||||
log.flush();
|
||||
@ -521,64 +574,37 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
SourceWriter sourceWriter = SourceWriter.instance(context);
|
||||
sourceWriter.setFileManager(fileManager);
|
||||
|
||||
attributeFactory.setCompat(options.compat);
|
||||
attributeFactory.setJSR277(options.jsr277);
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
for (String className: classes) {
|
||||
JavaFileObject fo;
|
||||
try {
|
||||
if (className.endsWith(".class")) {
|
||||
if (fileManager instanceof StandardJavaFileManager) {
|
||||
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
|
||||
fo = sfm.getJavaFileObjects(className).iterator().next();
|
||||
} else {
|
||||
diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className));
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
fo = getClassFileObject(className);
|
||||
if (fo == null) {
|
||||
// see if it is an inner class, by replacing dots to $, starting from the right
|
||||
String cn = className;
|
||||
int lastDot;
|
||||
while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) {
|
||||
cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
|
||||
fo = getClassFileObject(cn);
|
||||
}
|
||||
}
|
||||
if (fo == null) {
|
||||
diagnosticListener.report(createDiagnostic("err.class.not.found", className));
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
attributeFactory.setCompat(options.compat);
|
||||
attributeFactory.setJSR277(options.jsr277);
|
||||
|
||||
write(read(fo));
|
||||
|
||||
writeClass(classWriter, className);
|
||||
} catch (ConstantPoolException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
|
||||
reportError("err.bad.constant.pool", className, e.getLocalizedMessage());
|
||||
ok = false;
|
||||
} catch (EOFException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.end.of.file", className));
|
||||
reportError("err.end.of.file", className);
|
||||
ok = false;
|
||||
} catch (FileNotFoundException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage()));
|
||||
reportError("err.file.not.found", e.getLocalizedMessage());
|
||||
ok = false;
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
Object msg = e.getLocalizedMessage();
|
||||
if (msg == null)
|
||||
msg = e;
|
||||
diagnosticListener.report(createDiagnostic("err.ioerror", className, msg));
|
||||
reportError("err.ioerror", className, msg);
|
||||
ok = false;
|
||||
} catch (Throwable t) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString()));
|
||||
reportError("err.crash", t.toString(), sw.toString());
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
@ -586,6 +612,152 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
return ok;
|
||||
}
|
||||
|
||||
protected boolean writeClass(ClassWriter classWriter, String className)
|
||||
throws IOException, ConstantPoolException {
|
||||
JavaFileObject fo = open(className);
|
||||
if (fo == null) {
|
||||
reportError("err.class.not.found", className);
|
||||
return false;
|
||||
}
|
||||
|
||||
ClassFileInfo cfInfo = read(fo);
|
||||
if (!className.endsWith(".class")) {
|
||||
String cfName = cfInfo.cf.getName();
|
||||
if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", ".")))
|
||||
reportWarning("warn.unexpected.class", className, cfName.replace('/', '.'));
|
||||
}
|
||||
write(cfInfo);
|
||||
|
||||
if (options.showInnerClasses) {
|
||||
ClassFile cf = cfInfo.cf;
|
||||
Attribute a = cf.getAttribute(Attribute.InnerClasses);
|
||||
if (a instanceof InnerClasses_attribute) {
|
||||
InnerClasses_attribute inners = (InnerClasses_attribute) a;
|
||||
try {
|
||||
boolean ok = true;
|
||||
for (int i = 0; i < inners.classes.length; i++) {
|
||||
int outerIndex = inners.classes[i].outer_class_info_index;
|
||||
ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex);
|
||||
String outerClassName = outerClassInfo.getName();
|
||||
if (outerClassName.equals(cf.getName())) {
|
||||
int innerIndex = inners.classes[i].inner_class_info_index;
|
||||
ConstantPool.CONSTANT_Class_info innerClassInfo = cf.constant_pool.getClassInfo(innerIndex);
|
||||
String innerClassName = innerClassInfo.getName();
|
||||
classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", "."));
|
||||
classWriter.println();
|
||||
ok = ok & writeClass(classWriter, innerClassName);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
} catch (ConstantPoolException e) {
|
||||
reportError("err.bad.innerclasses.attribute", className);
|
||||
return false;
|
||||
}
|
||||
} else if (a != null) {
|
||||
reportError("err.bad.innerclasses.attribute", className);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected JavaFileObject open(String className) throws IOException {
|
||||
// for compatibility, first see if it is a class name
|
||||
JavaFileObject fo = getClassFileObject(className);
|
||||
if (fo != null)
|
||||
return fo;
|
||||
|
||||
// see if it is an inner class, by replacing dots to $, starting from the right
|
||||
String cn = className;
|
||||
int lastDot;
|
||||
while ((lastDot = cn.lastIndexOf(".")) != -1) {
|
||||
cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
|
||||
fo = getClassFileObject(cn);
|
||||
if (fo != null)
|
||||
return fo;
|
||||
}
|
||||
|
||||
if (!className.endsWith(".class"))
|
||||
return null;
|
||||
|
||||
if (fileManager instanceof StandardJavaFileManager) {
|
||||
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
|
||||
fo = sfm.getJavaFileObjects(className).iterator().next();
|
||||
if (fo != null && fo.getLastModified() != 0) {
|
||||
return fo;
|
||||
}
|
||||
}
|
||||
|
||||
// see if it is a URL, and if so, wrap it in just enough of a JavaFileObject
|
||||
// to suit javap's needs
|
||||
if (className.matches("^[A-Za-z]+:.*")) {
|
||||
try {
|
||||
final URI uri = new URI(className);
|
||||
final URL url = uri.toURL();
|
||||
final URLConnection conn = url.openConnection();
|
||||
return new JavaFileObject() {
|
||||
public Kind getKind() {
|
||||
return JavaFileObject.Kind.CLASS;
|
||||
}
|
||||
|
||||
public boolean isNameCompatible(String simpleName, Kind kind) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public NestingKind getNestingKind() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Modifier getAccessLevel() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public URI toUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
public InputStream openInputStream() throws IOException {
|
||||
return conn.getInputStream();
|
||||
}
|
||||
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Writer openWriter() throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public long getLastModified() {
|
||||
return conn.getLastModified();
|
||||
}
|
||||
|
||||
public boolean delete() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
};
|
||||
} catch (URISyntaxException ignore) {
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ClassFileInfo {
|
||||
ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
|
||||
this.fo = fo;
|
||||
@ -684,7 +856,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
}
|
||||
|
||||
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
|
||||
return JavapFileManager.create(dl, log, options);
|
||||
return JavapFileManager.create(dl, log);
|
||||
}
|
||||
|
||||
private JavaFileObject getClassFileObject(String className) throws IOException {
|
||||
@ -738,10 +910,23 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
}
|
||||
}
|
||||
|
||||
private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
|
||||
private void reportError(String key, Object... args) {
|
||||
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
|
||||
}
|
||||
|
||||
private void reportNote(String key, Object... args) {
|
||||
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args));
|
||||
}
|
||||
|
||||
private void reportWarning(String key, Object... args) {
|
||||
diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args));
|
||||
}
|
||||
|
||||
private Diagnostic<JavaFileObject> createDiagnostic(
|
||||
final Diagnostic.Kind kind, final String key, final Object... args) {
|
||||
return new Diagnostic<JavaFileObject>() {
|
||||
public Kind getKind() {
|
||||
return Diagnostic.Kind.ERROR;
|
||||
return kind;
|
||||
}
|
||||
|
||||
public JavaFileObject getSource() {
|
||||
@ -776,6 +961,11 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
return JavapTask.this.getMessage(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -85,6 +85,9 @@ public class Options {
|
||||
public boolean showAllAttrs;
|
||||
public boolean showConstants;
|
||||
public boolean sysInfo;
|
||||
public boolean showInnerClasses;
|
||||
public int indentWidth = 2; // #spaces per indentWidth level
|
||||
public int tabColumn = 40; // column number for comments
|
||||
|
||||
public boolean compat; // bug-for-bug compatibility mode with old javap
|
||||
public boolean jsr277;
|
||||
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ExtendedAnnotation;
|
||||
import com.sun.tools.classfile.ExtendedAnnotation.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;
|
||||
|
||||
/**
|
||||
* Annotate instructions with details about type annotations.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class TypeAnnotationWriter extends InstructionDetailWriter {
|
||||
public enum NoteKind { VISIBLE, INVISIBLE };
|
||||
public static class Note {
|
||||
Note(NoteKind kind, ExtendedAnnotation anno) {
|
||||
this.kind = kind;
|
||||
this.anno = anno;
|
||||
}
|
||||
public final NoteKind kind;
|
||||
public final ExtendedAnnotation 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 (ExtendedAnnotation 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(n.kind.toString().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationWriter annotationWriter;
|
||||
private ClassWriter classWriter;
|
||||
private Map<Integer, List<Note>> pcMap;
|
||||
}
|
@ -18,12 +18,22 @@ err.unknown.option=unknown option: {0}
|
||||
err.verify.not.supported=-verify not supported
|
||||
err.no.SourceFile.attribute=no SourceFile attribute
|
||||
err.source.file.not.found=source file not found
|
||||
err.bad.innerclasses.attribute=bad InnerClasses attribute for {0}
|
||||
warn.Xold.not.supported=-Xold is no longer available
|
||||
|
||||
main.usage.summary=\
|
||||
Usage: {0} <options> <classes>\n\
|
||||
use -help for a list of possible options
|
||||
|
||||
warn.prefix=Warning:
|
||||
warn.unexpected.class=Binary file {0} contains {1}
|
||||
|
||||
note.prefix=Note:
|
||||
|
||||
main.usage.summary=\
|
||||
Usage: {0} <options> <classes>\n\
|
||||
use -help for a list of possible options
|
||||
|
||||
main.usage=\
|
||||
Usage: {0} <options> <classes>\n\
|
||||
where possible options include:
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6862608
|
||||
* @summary rich diagnostic sometimes contain wrong type variable numbering
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6862608a.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608a.java
|
||||
*/
|
||||
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class T6862608a {
|
||||
|
||||
<T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void test(List<Comparator<?>> x) {
|
||||
Comparator<String> c3 = compound(x);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
T6862608a.java:42:41: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Iterable<? extends java.util.Comparator<? super java.lang.String>>, java.util.List<java.util.Comparator<?>>)
|
||||
- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, <T>compound(java.lang.Iterable<? extends java.util.Comparator<? super T>>))}
|
||||
1 error
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6862608
|
||||
* @summary rich diagnostic sometimes contain wrong type variable numbering
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6862608b.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608b.java
|
||||
*/
|
||||
|
||||
class T66862608b<T extends String, S> {
|
||||
<S, T extends S> void foo(T t) {
|
||||
test(t);
|
||||
}
|
||||
|
||||
void test(T t) {}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
T6862608b.java:34:7: compiler.err.cant.apply.symbol: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b<compiler.misc.type.var: T, 1,compiler.misc.type.var: S, 2>, null
|
||||
- compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,compiler.misc.type.var: S, 1,compiler.misc.type.var: S, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T66862608b),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, compiler.misc.type.var: S, 1, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 1, java.lang.Object, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 2, java.lang.Object, kindname.class, T66862608b)}
|
||||
1 error
|
32
langtools/test/tools/javac/Diagnostics/6864382/T6864382.java
Normal file
32
langtools/test/tools/javac/Diagnostics/6864382/T6864382.java
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6864382
|
||||
* @summary NullPointerException when compiling a negative java source
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6864382.out -XDrawDiagnostics T6864382.java
|
||||
*/
|
||||
|
||||
class T6864382<T> extends T {}
|
@ -0,0 +1,2 @@
|
||||
T6864382.java:32:27: compiler.err.type.found.req: (compiler.misc.type.parameter: T), (compiler.misc.type.req.class)
|
||||
1 error
|
@ -48,7 +48,7 @@ public class ArrayClone {
|
||||
System.out.println(out);
|
||||
|
||||
for (String line: out.split("\n")) {
|
||||
String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+; //Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;";
|
||||
String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+;[ \t]+// Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;";
|
||||
if (line.matches(match))
|
||||
return;
|
||||
}
|
||||
|
@ -30,9 +30,30 @@
|
||||
*/
|
||||
|
||||
class InnerClass {
|
||||
|
||||
InnerClass() {}
|
||||
InnerClass(Object o) {}
|
||||
|
||||
private void a() {
|
||||
new Object() {
|
||||
public <R> void method() { }
|
||||
};
|
||||
}
|
||||
|
||||
Object f1 = new InnerClass() {
|
||||
<R> void method() { }
|
||||
};
|
||||
|
||||
Object f2 = new InnerClass() {
|
||||
<@A R> void method() { }
|
||||
};
|
||||
|
||||
Object f3 = new InnerClass(null) {
|
||||
<R> void method() { }
|
||||
};
|
||||
|
||||
Object f4 = new InnerClass(null) {
|
||||
<@A R> void method() { }
|
||||
};
|
||||
@interface A { }
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class T4111861 {
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.indexOf("public static final") > 0) {
|
||||
sb.append(line);
|
||||
sb.append(line.trim());
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
111
langtools/test/tools/javap/T4777949.java
Normal file
111
langtools/test/tools/javap/T4777949.java
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.tools.*;
|
||||
import com.sun.tools.javap.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4777949
|
||||
* @summary Warn javap usage on package with simple name
|
||||
*/
|
||||
public class T4777949 {
|
||||
public static void main(String... args) throws Exception {
|
||||
new T4777949().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
test(".", "p.q.r.Test", false);
|
||||
test("p", "q.r.Test", true);
|
||||
test("p/q", "r.Test", true);
|
||||
test("p/q/r", "Test", true);
|
||||
test(".", "p.q.r.Test.Inner", false);
|
||||
test(".", "p.q.r.Test$Inner", false);
|
||||
test("p", "q.r.Test.Inner", true);
|
||||
test("p", "q.r.Test$Inner", true);
|
||||
|
||||
if (errors > 0)
|
||||
throw new Exception(errors + " errors found");
|
||||
}
|
||||
|
||||
void test(String classPath, String className, boolean expectWarnings) {
|
||||
List<Diagnostic<? extends JavaFileObject>> diags =
|
||||
javap(Arrays.asList("-classpath", classPath), Arrays.asList(className));
|
||||
boolean foundWarnings = false;
|
||||
for (Diagnostic<? extends JavaFileObject> d: diags) {
|
||||
if (d.getKind() == Diagnostic.Kind.WARNING)
|
||||
foundWarnings = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("package p.q.r;");
|
||||
out.println("class Test { class Inner { } }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { "-d", ".", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
List<Diagnostic<? extends JavaFileObject>> javap(List<String> args, List<String> classes) {
|
||||
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>();
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
JavaFileManager fm = JavapFileManager.create(dc, pw);
|
||||
JavapTask t = new JavapTask(pw, fm, dc, args, classes);
|
||||
boolean ok = t.run();
|
||||
|
||||
List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics();
|
||||
|
||||
if (!ok)
|
||||
error("javap failed unexpectedly");
|
||||
|
||||
System.err.println("args=" + args + " classes=" + classes + "\n"
|
||||
+ diags + "\n"
|
||||
+ sw);
|
||||
|
||||
return diags;
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println("error: " + msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
||||
|
86
langtools/test/tools/javap/T4880672.java
Normal file
86
langtools/test/tools/javap/T4880672.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4880672
|
||||
* @summary javap does not output inner interfaces of an interface
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class T4880672
|
||||
{
|
||||
public static void main(String... args) {
|
||||
new T4880672().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
verify("java.util.Map", "public interface java.util.Map$Entry");
|
||||
verify("T4880672", "class T4880672$A$B extends java.lang.Object");
|
||||
verify("C", ""); // must not give error if no InnerClasses attribute
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
void verify(String className, String... expects) {
|
||||
String output = javap(className);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
|
||||
String javap(String className) {
|
||||
String testClasses = System.getProperty("test.classes", ".");
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
String[] args = { "-XDinner", "-classpath", testClasses, className };
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
out.close();
|
||||
String output = sw.toString();
|
||||
System.out.println("class " + className);
|
||||
System.out.println(output);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
if (output.indexOf("Error:") != -1)
|
||||
throw new Error("javap reported error.");
|
||||
return output;
|
||||
}
|
||||
|
||||
class A {
|
||||
class B { }
|
||||
}
|
||||
}
|
||||
|
||||
class C { }
|
||||
|
@ -46,9 +46,9 @@ public class T4884240 {
|
||||
pw.close();
|
||||
String[] lines = sw.toString().split("\n");
|
||||
if (lines.length < 3
|
||||
|| !lines[0].startsWith("Classfile")
|
||||
|| !lines[1].startsWith("Last modified")
|
||||
|| !lines[2].startsWith("MD5")) {
|
||||
|| !lines[0].trim().startsWith("Classfile")
|
||||
|| !lines[1].trim().startsWith("Last modified")
|
||||
|| !lines[2].trim().startsWith("MD5")) {
|
||||
System.out.println(sw);
|
||||
throw new Exception("unexpected output");
|
||||
}
|
||||
|
@ -40,10 +40,10 @@ public class T4975569
|
||||
verify("T4975569$Anno", "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION");
|
||||
verify("T4975569$E", "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM");
|
||||
verify("T4975569$S", "flags: ACC_BRIDGE, ACC_SYNTHETIC",
|
||||
"InnerClasses: \n static");
|
||||
"InnerClasses:\n static");
|
||||
verify("T4975569$V", "void m(java.lang.String...)",
|
||||
"flags: ACC_VARARGS");
|
||||
verify("T4975569$Prot", "InnerClasses: \n protected");
|
||||
verify("T4975569$Prot", "InnerClasses:\n protected");
|
||||
//verify("T4975569$Priv", "InnerClasses");
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
|
109
langtools/test/tools/javap/T6729471.java
Normal file
109
langtools/test/tools/javap/T6729471.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6729471
|
||||
* @summary javap does not output inner interfaces of an interface
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class T6729471
|
||||
{
|
||||
public static void main(String... args) {
|
||||
new T6729471().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
// simple class
|
||||
verify("java.util.Map",
|
||||
"public abstract boolean containsKey(java.lang.Object)");
|
||||
|
||||
// inner class
|
||||
verify("java.util.Map.Entry",
|
||||
"public abstract K getKey()");
|
||||
|
||||
// file name
|
||||
verify("../classes/tools/javap/T6729471.class",
|
||||
"public static void main(java.lang.String...)");
|
||||
|
||||
// file url
|
||||
verify("file:../classes/tools/javap/T6729471.class",
|
||||
"public static void main(java.lang.String...)");
|
||||
|
||||
// jar url: rt.jar
|
||||
File java_home = new File(System.getProperty("java.home"));
|
||||
if (java_home.getName().equals("jre"))
|
||||
java_home = java_home.getParentFile();
|
||||
File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
|
||||
verify("jar:file:" + rt_jar + "!/java/util/Map.class",
|
||||
"public abstract boolean containsKey(java.lang.Object)");
|
||||
|
||||
// jar url: ct.sym, if it exists
|
||||
File ct_sym = new File(new File(java_home, "lib"), "ct.sym");
|
||||
if (ct_sym.exists()) {
|
||||
verify("jar:file:" + ct_sym + "!/META-INF/sym/rt.jar/java/util/Map.class",
|
||||
"public abstract boolean containsKey(java.lang.Object)");
|
||||
} else
|
||||
System.err.println("warning: ct.sym not found");
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
void verify(String className, String... expects) {
|
||||
String output = javap(className);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
|
||||
String javap(String className) {
|
||||
String testClasses = System.getProperty("test.classes", ".");
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
String[] args = { "-classpath", testClasses, className };
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
out.close();
|
||||
String output = sw.toString();
|
||||
System.out.println("class " + className);
|
||||
System.out.println(output);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
if (output.indexOf("Error:") != -1)
|
||||
throw new Error("javap reported error.");
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
82
langtools/test/tools/javap/T6866657.java
Normal file
82
langtools/test/tools/javap/T6866657.java
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6866657
|
||||
* @summary add byteLength() method to primary classfile types
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.tools.*;
|
||||
import com.sun.tools.javap.*;
|
||||
|
||||
public class T6866657
|
||||
{
|
||||
public static void main(String... args) {
|
||||
new T6866657().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
verify("java.lang.Object");
|
||||
verify("java.lang.String");
|
||||
verify("java.util.List");
|
||||
verify("java.util.ArrayList");
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
void verify(String className) {
|
||||
try {
|
||||
PrintWriter log = new PrintWriter(System.out);
|
||||
JavaFileManager fileManager = JavapFileManager.create(null, log);
|
||||
JavaFileObject fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
|
||||
if (fo == null) {
|
||||
error("Can't find " + className);
|
||||
} else {
|
||||
JavapTask t = new JavapTask(log, fileManager, null);
|
||||
t.handleOptions(new String[] { "-sysinfo", className });
|
||||
JavapTask.ClassFileInfo cfInfo = t.read(fo);
|
||||
expectEqual(cfInfo.cf.byteLength(), cfInfo.size);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
error("Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
void expectEqual(int found, int expected) {
|
||||
if (found != expected)
|
||||
error("bad value found: " + found + " expected: " + expected);
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ grep "frame_type" "${JAVAPFILE}" > "${OUTFILE}"
|
||||
grep "offset_delta" "${JAVAPFILE}" >> "${OUTFILE}"
|
||||
grep "stack = " "${JAVAPFILE}" >> "${OUTFILE}"
|
||||
grep "locals = " "${JAVAPFILE}" >> "${OUTFILE}"
|
||||
diff "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
|
||||
diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
|
||||
result="$?"
|
||||
if [ "$result" -eq 0 ]
|
||||
then
|
||||
|
51
langtools/test/tools/javap/typeAnnotations/T6855990.java
Normal file
51
langtools/test/tools/javap/typeAnnotations/T6855990.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6855990
|
||||
* @summary InstructionDetailWriter should support new 308 annotations attribute
|
||||
*/
|
||||
|
||||
public class T6855990 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6855990().run();
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
@Simple String[] args = { "-c", "-XDdetails:typeAnnotations", "T6855990" };
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(args, pw);
|
||||
pw.close();
|
||||
String out = sw.toString();
|
||||
System.out.println(out);
|
||||
if (out.indexOf("@Simple: LOCAL_VARIABLE") == -1)
|
||||
throw new Exception("expected output not found");
|
||||
}
|
||||
}
|
||||
|
||||
@interface Simple { }
|
||||
|
Loading…
x
Reference in New Issue
Block a user