4075303: Use javap to enquire aboput a specific inner class

4348375: Javap is not internationalized
4459541: "javap -l" shows line numbers as signed short; they should be unsigned
4501660: change diagnostic of -help as 'print this help message and exit'
4776241: unused source file in javap..
4870651: javap should recognize generics, varargs, enum
4876942: javap invoked without args does not print help screen
4880663: javap could output whitespace between class name and opening brace
4975569: javap doesn't print new flag bits
6271787: javap dumps LocalVariableTypeTable attribute in hex, needs to print a table
6305779: javap: support annotations
6439940: Clean up javap implementation
6469569: wrong check of searchpath in JavapEnvironment
6474890: javap does not open .zip files in -classpath
6587786: Javap throws error : "ERROR:Could not find <classname>" for JRE classes
6622215: javap ignores certain relevant access flags
6622216: javap names some attributes incorrectly
6622232: javap gets whitespace confused
6622260: javap prints negative bytes incorrectly in hex

Reviewed-by: ksrini
This commit is contained in:
Jonathan Gibbons 2008-06-03 13:26:47 -07:00
parent e3ba3ecd1d
commit 0a7516d744
87 changed files with 11690 additions and 8 deletions

View File

@ -66,7 +66,7 @@ javac.no.jdk.warnings = -XDignore.symbol.file=true
# set the following to -version to verify the versions of javac being used
javac.version.opt =
# in time, there should be no exceptions to -Xlint:all
javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial -Werror
javac.lint.opts = -Xlint:all,-deprecation,-fallthrough,-serial -Werror
# options for the <javadoc> task for javac
javadoc.jls3.url=http://java.sun.com/docs/books/jls/
@ -120,6 +120,8 @@ javah.tests = \
tools/javah/
javap.includes = \
com/sun/tools/classfile/ \
com/sun/tools/javap/ \
sun/tools/javap/
javap.tests = \

View File

@ -136,7 +136,7 @@
<arg value="-html:${findbugs.home}/src/xsl/fancy.xsl"/>
<arg value="${dist.findbugs.dir}/findbugs.xml"/>
<redirector output="${dist.findbugs.dir}/findbugs.html"/>
</exec>
</exec>
</target>
<target name="coverage" depends="-def-cobertura,build-all-classes,instrument-classes,jtreg,coverage-report"/>
@ -301,14 +301,15 @@
jarmainclass="sun.tools.javap.Main"/>
</target>
<target name="build-classes-javap" depends="build-bootstrap-javac">
<target name="build-classes-javap" depends="build-classes-javac">
<build-classes name="javap" includes="${javap.includes}"/>
</target>
<target name="build-javap" depends="build-bootstrap-javac">
<target name="build-javap" depends="build-javac">
<build-tool name="javap"
includes="${javap.includes}"
jarmainclass="sun.tools.javap.Main"/>
jarmainclass="sun.tools.javap.Main"
jarclasspath="javac.jar"/>
</target>
<!-- (no javadoc for javap) -->
@ -480,7 +481,7 @@
destdir="@{gensrc.dir}"
includes="@{includes}"/>
<copy todir="@{gensrc.dir}">
<fileset dir="${src.classes.dir}" includes="${javac.includes}"/>
<fileset dir="${src.classes.dir}" includes="@{includes}"/>
<globmapper from="*.properties-template" to="*.properties"/>
<filterset begintoken="$(" endtoken=")">
<filter token="JDK_VERSION" value="${jdk.version}"/>

View File

@ -157,5 +157,5 @@
</action>
<action name="javadoc">
<target>javadoc-nb</target>
<target>-javadoc-nb</target>
</action>

View File

@ -157,5 +157,5 @@
</action>
<action name="javadoc">
<target>javadoc-nb</target>
<target>-javadoc-nb</target>
</action>

View File

@ -0,0 +1,254 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* See JVMS3, sections 4.2, 4.6, 4.7.
*
* <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 AccessFlags {
public static final int ACC_PUBLIC = 0x0001; // class, inner, field, method
public static final int ACC_PRIVATE = 0x0002; // inner, field, method
public static final int ACC_PROTECTED = 0x0004; // inner, field, method
public static final int ACC_STATIC = 0x0008; // inner, field, method
public static final int ACC_FINAL = 0x0010; // class, inner, field, method
public static final int ACC_SUPER = 0x0020; // class
public static final int ACC_SYNCHRONIZED = 0x0020; // method
public static final int ACC_VOLATILE = 0x0040; // field
public static final int ACC_BRIDGE = 0x0040; // method
public static final int ACC_TRANSIENT = 0x0080; // field
public static final int ACC_VARARGS = 0x0080; // method
public static final int ACC_NATIVE = 0x0100; // method
public static final int ACC_INTERFACE = 0x0200; // class, inner
public static final int ACC_ABSTRACT = 0x0400; // class, inner, method
public static final int ACC_STRICT = 0x0800; // method
public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method
public static final int ACC_ANNOTATION = 0x2000; // class, inner
public static final int ACC_ENUM = 0x4000; // class, inner, field
public static final int ACC_MODULE = 0x8000; // class, inner, field, method
private static enum Type { Class, InnerClass, Field, Method};
AccessFlags(ClassReader cr) throws IOException {
this(cr.readUnsignedShort());
}
public AccessFlags(int flags) {
this.flags = flags;
}
public AccessFlags ignore(int mask) {
return new AccessFlags(flags & ~mask);
}
public boolean is(int mask) {
return (flags & mask) != 0;
}
private static final int[] classModifiers = {
ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
};
private static final int[] classFlags = {
ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
};
public Set<String> getClassModifiers() {
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
return getModifiers(f, classModifiers, Type.Class);
}
public Set<String> getClassFlags() {
return getFlags(classFlags, Type.Class);
}
private static final int[] innerClassModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_ABSTRACT, ACC_MODULE
};
private static final int[] innerClassFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
};
public Set<String> getInnerClassModifiers() {
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
return getModifiers(f, innerClassModifiers, Type.InnerClass);
}
public Set<String> getInnerClassFlags() {
return getFlags(innerClassFlags, Type.InnerClass);
}
private static final int[] fieldModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
};
private static final int[] fieldFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
};
public Set<String> getFieldModifiers() {
return getModifiers(fieldModifiers, Type.Field);
}
public Set<String> getFieldFlags() {
return getFlags(fieldFlags, Type.Field);
}
private static final int[] methodModifiers = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
};
private static final int[] methodFlags = {
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
};
public Set<String> getMethodModifiers() {
return getModifiers(methodModifiers, Type.Method);
}
public Set<String> getMethodFlags() {
return getFlags(methodFlags, Type.Method);
}
private Set<String> getModifiers(int[] modifierFlags, Type t) {
return getModifiers(flags, modifierFlags, t);
}
private static Set<String> getModifiers(int flags, int[] modifierFlags, Type t) {
Set<String> s = new LinkedHashSet<String>();
for (int m: modifierFlags) {
if ((flags & m) != 0)
s.add(flagToModifier(m, t));
}
return s;
}
private Set<String> getFlags(int[] expectedFlags, Type t) {
Set<String> s = new LinkedHashSet<String>();
int f = flags;
for (int e: expectedFlags) {
if ((f & e) != 0) {
s.add(flagToName(e, t));
f = f & ~e;
}
}
while (f != 0) {
int bit = Integer.highestOneBit(f);
s.add("0x" + Integer.toHexString(bit));
f = f & ~bit;
}
return s;
}
private static String flagToModifier(int flag, Type t) {
switch (flag) {
case ACC_PUBLIC:
return "public";
case ACC_PRIVATE:
return "private";
case ACC_PROTECTED:
return "protected";
case ACC_STATIC:
return "static";
case ACC_FINAL:
return "final";
case ACC_SYNCHRONIZED:
return "synchronized";
case 0x80:
return (t == Type.Field ? "transient" : null);
case ACC_VOLATILE:
return "volatile";
case ACC_NATIVE:
return "native";
case ACC_ABSTRACT:
return "abstract";
case ACC_STRICT:
return "strictfp";
case ACC_MODULE:
return "module";
default:
return null;
}
}
private static String flagToName(int flag, Type t) {
switch (flag) {
case ACC_PUBLIC:
return "ACC_PUBLIC";
case ACC_PRIVATE:
return "ACC_PRIVATE";
case ACC_PROTECTED:
return "ACC_PROTECTED";
case ACC_STATIC:
return "ACC_STATIC";
case ACC_FINAL:
return "ACC_FINAL";
case 0x20:
return (t == Type.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
case 0x40:
return (t == Type.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
case 0x80:
return (t == Type.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
case ACC_NATIVE:
return "ACC_NATIVE";
case ACC_INTERFACE:
return "ACC_INTERFACE";
case ACC_ABSTRACT:
return "ACC_ABSTRACT";
case ACC_STRICT:
return "ACC_STRICT";
case ACC_SYNTHETIC:
return "ACC_SYNTHETIC";
case ACC_ANNOTATION:
return "ACC_ANNOTATION";
case ACC_ENUM:
return "ACC_ENUM";
case ACC_MODULE:
return "ACC_MODULE";
default:
return null;
}
}
final int flags;
}

View File

@ -0,0 +1,243 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.16.
*
* <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 Annotation {
static class InvalidAnnotation extends AttributeException {
InvalidAnnotation(String msg) {
super(msg);
}
}
Annotation(ClassReader cr) throws IOException, InvalidAnnotation {
type_index = cr.readUnsignedShort();
num_element_value_pairs = cr.readUnsignedShort();
element_value_pairs = new element_value_pair[num_element_value_pairs];
for (int i = 0; i < element_value_pairs.length; i++)
element_value_pairs[i] = new element_value_pair(cr);
}
public Annotation(ConstantPool constant_pool,
int type_index,
element_value_pair[] element_value_pairs) {
this.type_index = type_index;
num_element_value_pairs = element_value_pairs.length;
this.element_value_pairs = element_value_pairs;
}
public int length() {
int n = 2 /*type_index*/ + 2 /*num_element_value_pairs*/;
for (element_value_pair pair: element_value_pairs)
n += pair.length();
return n;
}
public final int type_index;
public final int num_element_value_pairs;
public final element_value_pair element_value_pairs[];
/**
* See JVMS3, section 4.8.16.1.
*/
public static abstract class element_value {
public static element_value read(ClassReader cr)
throws IOException, InvalidAnnotation {
int tag = cr.readUnsignedByte();
switch (tag) {
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
case 's':
return new Primitive_element_value(cr, tag);
case 'e':
return new Enum_element_value(cr, tag);
case 'c':
return new Class_element_value(cr, tag);
case '@':
return new Annotation_element_value(cr, tag);
case '[':
return new Array_element_value(cr, tag);
default:
throw new InvalidAnnotation("unrecognized tag: " + tag);
}
}
protected element_value(int tag) {
this.tag = tag;
}
public abstract int length();
public abstract <R,P> R accept(Visitor<R,P> visitor, P p);
public interface Visitor<R,P> {
R visitPrimitive(Primitive_element_value ev, P p);
R visitEnum(Enum_element_value ev, P p);
R visitClass(Class_element_value ev, P p);
R visitAnnotation(Annotation_element_value ev, P p);
R visitArray(Array_element_value ev, P p);
}
public final int tag;
}
public static class Primitive_element_value extends element_value {
Primitive_element_value(ClassReader cr, int tag) throws IOException {
super(tag);
const_value_index = cr.readUnsignedShort();
}
@Override
public int length() {
return 2;
}
public <R,P> R accept(Visitor<R,P> visitor, P p) {
return visitor.visitPrimitive(this, p);
}
public final int const_value_index;
}
public static class Enum_element_value extends element_value {
Enum_element_value(ClassReader cr, int tag) throws IOException {
super(tag);
type_name_index = cr.readUnsignedShort();
const_name_index = cr.readUnsignedShort();
}
@Override
public int length() {
return 4;
}
public <R,P> R accept(Visitor<R,P> visitor, P p) {
return visitor.visitEnum(this, p);
}
public final int type_name_index;
public final int const_name_index;
}
public static class Class_element_value extends element_value {
Class_element_value(ClassReader cr, int tag) throws IOException {
super(tag);
class_info_index = cr.readUnsignedShort();
}
@Override
public int length() {
return 2;
}
public <R,P> R accept(Visitor<R,P> visitor, P p) {
return visitor.visitClass(this, p);
}
public final int class_info_index;
}
public static class Annotation_element_value extends element_value {
Annotation_element_value(ClassReader cr, int tag)
throws IOException, InvalidAnnotation {
super(tag);
annotation_value = new Annotation(cr);
}
@Override
public int length() {
return annotation_value.length();
}
public <R,P> R accept(Visitor<R,P> visitor, P p) {
return visitor.visitAnnotation(this, p);
}
public final Annotation annotation_value;
}
public static class Array_element_value extends element_value {
Array_element_value(ClassReader cr, int tag)
throws IOException, InvalidAnnotation {
super(tag);
num_values = cr.readUnsignedShort();
values = new element_value[num_values];
for (int i = 0; i < values.length; i++)
values[i] = element_value.read(cr);
}
@Override
public int length() {
int n = 2;
for (int i = 0; i < values.length; i++)
n += values[i].length();
return n;
}
public <R,P> R accept(Visitor<R,P> visitor, P p) {
return visitor.visitArray(this, p);
}
public final int num_values;
public final element_value[] values;
}
public static class element_value_pair {
element_value_pair(ClassReader cr)
throws IOException, InvalidAnnotation {
element_name_index = cr.readUnsignedShort();
value = element_value.read(cr);
}
public int length() {
return 2 + value.length();
}
public final int element_name_index;
public final element_value value;
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.15.
*
* <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 AnnotationDefault_attribute extends Attribute {
AnnotationDefault_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(name_index, length);
default_value = Annotation.element_value.read(cr);
}
public AnnotationDefault_attribute(ConstantPool constant_pool, Annotation.element_value default_value)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.AnnotationDefault), default_value);
}
public AnnotationDefault_attribute(int name_index, Annotation.element_value default_value) {
super(name_index, default_value.length());
this.default_value = default_value;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitAnnotationDefault(this, data);
}
public final Annotation.element_value default_value;
}

View File

@ -0,0 +1,199 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
/**
* <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 abstract class Attribute {
public static final String AnnotationDefault = "AnnotationDefault";
public static final String CharacterRangeTable = "CharacterRangeTable";
public static final String Code = "Code";
public static final String ConstantValue = "ConstantValue";
public static final String CompilationID = "CompilationID";
public static final String Deprecated = "Deprecated";
public static final String EnclosingMethod = "EnclosingMethod";
public static final String Exceptions = "Exceptions";
public static final String InnerClasses = "InnerClasses";
public static final String LineNumberTable = "LineNumberTable";
public static final String LocalVariableTable = "LocalVariableTable";
public static final String LocalVariableTypeTable = "LocalVariableTypeTable";
public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
public static final String Signature = "Signature";
public static final String SourceDebugExtension = "SourceDebugExtension";
public static final String SourceFile = "SourceFile";
public static final String SourceID = "SourceID";
public static final String StackMap = "StackMap";
public static final String StackMapTable = "StackMapTable";
public static final String Synthetic = "Synthetic";
// JSR 277/294
public static final String Module = "Module";
public static final String ModuleExportTable = "ModuleExportTable";
public static final String ModuleMemberTable = "ModuleMemberTable";
public static class Factory {
public Factory() {
// defer init of standardAttributeClasses until after options set up
}
public void setCompat(boolean compat) {
this.compat = compat;
}
public void setJSR277(boolean jsr277) {
this.jsr277 = jsr277;
}
public Attribute createAttribute(ClassReader cr, int name_index, byte[] data)
throws IOException {
if (standardAttributes == null)
init();
ConstantPool cp = cr.getConstantPool();
try {
String name = cp.getUTF8Value(name_index);
Class<? extends Attribute> attrClass = standardAttributes.get(name);
if (attrClass != null) {
try {
Class<?>[] constrArgTypes = {ClassReader.class, int.class, int.class};
Constructor<? extends Attribute> constr = attrClass.getDeclaredConstructor(constrArgTypes);
return constr.newInstance(new Object[] { cr, name_index, data.length });
} catch (Throwable t) {
// fall through and use DefaultAttribute
// t.printStackTrace();
}
}
} catch (ConstantPoolException e) {
// fall through and use DefaultAttribute
}
return new DefaultAttribute(cr, name_index, data);
}
protected void init() {
standardAttributes = new HashMap<String,Class<? extends Attribute>>();
standardAttributes.put(AnnotationDefault, AnnotationDefault_attribute.class);
standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
standardAttributes.put(Code, Code_attribute.class);
standardAttributes.put(ConstantValue, ConstantValue_attribute.class);
standardAttributes.put(Deprecated, Deprecated_attribute.class);
standardAttributes.put(EnclosingMethod, EnclosingMethod_attribute.class);
standardAttributes.put(Exceptions, Exceptions_attribute.class);
standardAttributes.put(InnerClasses, InnerClasses_attribute.class);
standardAttributes.put(LineNumberTable, LineNumberTable_attribute.class);
standardAttributes.put(LocalVariableTable, LocalVariableTable_attribute.class);
standardAttributes.put(LocalVariableTypeTable, LocalVariableTypeTable_attribute.class);
if (jsr277) {
standardAttributes.put(Module, Module_attribute.class);
standardAttributes.put(ModuleExportTable, ModuleExportTable_attribute.class);
standardAttributes.put(ModuleMemberTable, ModuleMemberTable_attribute.class);
}
if (!compat) { // old javap does not recognize recent attributes
standardAttributes.put(CompilationID, CompilationID_attribute.class);
standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class);
standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class);
standardAttributes.put(Signature, Signature_attribute.class);
standardAttributes.put(SourceID, SourceID_attribute.class);
}
standardAttributes.put(SourceDebugExtension, SourceDebugExtension_attribute.class);
standardAttributes.put(SourceFile, SourceFile_attribute.class);
standardAttributes.put(StackMap, StackMap_attribute.class);
standardAttributes.put(StackMapTable, StackMapTable_attribute.class);
standardAttributes.put(Synthetic, Synthetic_attribute.class);
}
private Map<String,Class<? extends Attribute>> standardAttributes;
private boolean compat; // don't support recent attrs in compatibility mode
private boolean jsr277; // support new jsr277 attrs
}
public static Attribute read(ClassReader cr) throws IOException {
return cr.readAttribute();
}
protected Attribute(int name_index, int length) {
attribute_name_index = name_index;
attribute_length = length;
}
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(attribute_name_index);
}
public abstract <R,D> R accept(Attribute.Visitor<R,D> visitor, D data);
public final int attribute_name_index;
public final int attribute_length;
public interface Visitor<R,P> {
R visitDefault(DefaultAttribute attr, P p);
R visitAnnotationDefault(AnnotationDefault_attribute attr, P p);
R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p);
R visitCode(Code_attribute attr, P p);
R visitCompilationID(CompilationID_attribute attr, P p);
R visitConstantValue(ConstantValue_attribute attr, P p);
R visitDeprecated(Deprecated_attribute attr, P p);
R visitEnclosingMethod(EnclosingMethod_attribute attr, P p);
R visitExceptions(Exceptions_attribute attr, P p);
R visitInnerClasses(InnerClasses_attribute attr, P p);
R visitLineNumberTable(LineNumberTable_attribute attr, P p);
R visitLocalVariableTable(LocalVariableTable_attribute attr, P p);
R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p);
R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p);
R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
R visitSignature(Signature_attribute attr, P p);
R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
R visitSourceFile(SourceFile_attribute attr, P p);
R visitSourceID(SourceID_attribute attr, P p);
R visitStackMap(StackMap_attribute attr, P p);
R visitStackMapTable(StackMapTable_attribute attr, P p);
R visitSynthetic(Synthetic_attribute attr, P p);
R visitModule(Module_attribute attr, P p);
R visitModuleExportTable(ModuleExportTable_attribute attr, P p);
R visitModuleMemberTable(ModuleMemberTable_attribute attr, P p);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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. 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.classfile;
/*
* <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 AttributeException extends Exception {
AttributeException() { }
AttributeException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/*
* <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 Attributes implements Iterable<Attribute> {
Attributes(ClassReader cr) throws IOException {
map = new HashMap<String,Attribute>();
int attrs_count = cr.readUnsignedShort();
attrs = new Attribute[attrs_count];
for (int i = 0; i < attrs_count; i++) {
Attribute attr = Attribute.read(cr);
attrs[i] = attr;
try {
map.put(attr.getName(cr.getConstantPool()), attr);
} catch (ConstantPoolException e) {
// don't enter invalid names in map
}
}
}
public Attributes(ConstantPool constant_pool, Attribute[] attrs) {
this.attrs = attrs;
map = new HashMap<String,Attribute>();
for (int i = 0; i < attrs.length; i++) {
Attribute attr = attrs[i];
try {
map.put(attr.getName(constant_pool), attr);
} catch (ConstantPoolException e) {
// don't enter invalid names in map
}
}
}
public Iterator<Attribute> iterator() {
return Arrays.asList(attrs).iterator();
}
public Attribute get(int index) {
return attrs[index];
}
public Attribute get(String name) {
return map.get(name);
}
public int size() {
return attrs.length;
}
public final Attribute[] attrs;
public final Map<String, Attribute> map;
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* <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 CharacterRangeTable_attribute extends Attribute {
public static final int CRT_STATEMENT = 0x0001;
public static final int CRT_BLOCK = 0x0002;
public static final int CRT_ASSIGNMENT = 0x0004;
public static final int CRT_FLOW_CONTROLLER = 0x0008;
public static final int CRT_FLOW_TARGET = 0x0010;
public static final int CRT_INVOKE = 0x0020;
public static final int CRT_CREATE = 0x0040;
public static final int CRT_BRANCH_TRUE = 0x0080;
public static final int CRT_BRANCH_FALSE = 0x0100;
CharacterRangeTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
int character_range_table_length = cr.readUnsignedShort();
character_range_table = new Entry[character_range_table_length];
for (int i = 0; i < character_range_table_length; i++)
character_range_table[i] = new Entry(cr);
}
public CharacterRangeTable_attribute(ConstantPool constant_pool, Entry[] character_range_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.CharacterRangeTable), character_range_table);
}
public CharacterRangeTable_attribute(int name_index, Entry[] character_range_table) {
super(name_index, character_range_table.length * Entry.length());
this.character_range_table = character_range_table;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitCharacterRangeTable(this, data);
}
public final Entry[] character_range_table;
public static class Entry {
Entry(ClassReader cr) throws IOException {
start_pc = cr.readUnsignedShort();
end_pc = cr.readUnsignedShort();
character_range_start = cr.readInt();
character_range_end = cr.readInt();
flags = cr.readUnsignedShort();
}
public static int length() {
return 14;
}
public final int start_pc;
public final int end_pc;
public final int character_range_start;
public final int character_range_end;
public final int flags;
};
}

View File

@ -0,0 +1,153 @@
/*
* Copyright 2007 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.classfile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static com.sun.tools.classfile.AccessFlags.*;
/**
* See JVMS3, section 4.2.
*
* <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 ClassFile {
public static ClassFile read(File file)
throws IOException, ConstantPoolException {
return read(file, new Attribute.Factory());
}
public static ClassFile read(File file, Attribute.Factory attributeFactory)
throws IOException, ConstantPoolException {
FileInputStream in = new FileInputStream(file);
try {
return new ClassFile(in, attributeFactory);
} finally {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}
public static ClassFile read(InputStream in)
throws IOException, ConstantPoolException {
return new ClassFile(in, new Attribute.Factory());
}
public static ClassFile read(InputStream in, Attribute.Factory attributeFactory)
throws IOException, ConstantPoolException {
return new ClassFile(in, attributeFactory);
}
ClassFile(InputStream in, Attribute.Factory attributeFactory) throws IOException, ConstantPoolException {
ClassReader cr = new ClassReader(this, in, attributeFactory);
magic = cr.readInt();
minor_version = cr.readUnsignedShort();
major_version = cr.readUnsignedShort();
constant_pool = new ConstantPool(cr);
access_flags = new AccessFlags(cr);
this_class = cr.readUnsignedShort();
super_class = cr.readUnsignedShort();
int interfaces_count = cr.readUnsignedShort();
interfaces = new int[interfaces_count];
for (int i = 0; i < interfaces_count; i++)
interfaces[i] = cr.readUnsignedShort();
int fields_count = cr.readUnsignedShort();
fields = new Field[fields_count];
for (int i = 0; i < fields_count; i++)
fields[i] = new Field(cr);
int methods_count = cr.readUnsignedShort();
methods = new Method[methods_count];
for (int i = 0; i < methods_count; i++)
methods[i] = new Method(cr);
attributes = new Attributes(cr);
}
public ClassFile(int magic, int minor_version, int major_version,
ConstantPool constant_pool, AccessFlags access_flags,
int this_class, int super_class, int[] interfaces,
Field[] fields, Method[] methods, Attributes attributes) {
this.magic = magic;
this.minor_version = minor_version;
this.major_version = major_version;
this.constant_pool = constant_pool;
this.access_flags = access_flags;
this.this_class = this_class;
this.super_class = super_class;
this.interfaces = interfaces;
this.fields = fields;
this.methods = methods;
this.attributes = attributes;
}
public String getName() throws ConstantPoolException {
return constant_pool.getClassInfo(this_class).getName();
}
public String getSuperclassName() throws ConstantPoolException {
return constant_pool.getClassInfo(super_class).getName();
}
public String getInterfaceName(int i) throws ConstantPoolException {
return constant_pool.getClassInfo(interfaces[i]).getName();
}
public Attribute getAttribute(String name) {
return attributes.get(name);
}
public boolean isClass() {
return !isInterface();
}
public boolean isInterface() {
return access_flags.is(ACC_INTERFACE);
}
public final int magic;
public final int minor_version;
public final int major_version;
public final ConstantPool constant_pool;
public final AccessFlags access_flags;
public final int this_class;
public final int super_class;
public final int[] interfaces;
public final Field[] fields;
public final Method[] methods;
public final Attributes attributes;
}

View File

@ -0,0 +1,109 @@
/*
* Copyright 2007 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.classfile;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* <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 ClassReader {
ClassReader(ClassFile classFile, InputStream in, Attribute.Factory attributeFactory) throws IOException {
// null checks
classFile.getClass();
attributeFactory.getClass();
this.classFile = classFile;
this.in = new DataInputStream(new BufferedInputStream(in));
this.attributeFactory = attributeFactory;
}
ClassFile getClassFile() {
return classFile;
}
ConstantPool getConstantPool() {
return classFile.constant_pool;
}
public Attribute readAttribute() throws IOException {
int name_index = readUnsignedShort();
int length = readInt();
byte[] data = new byte[length];
readFully(data);
DataInputStream prev = in;
in = new DataInputStream(new ByteArrayInputStream(data));
try {
return attributeFactory.createAttribute(this, name_index, data);
} finally {
in = prev;
}
}
public void readFully(byte[] b) throws IOException {
in.readFully(b);
}
public int readUnsignedByte() throws IOException {
return in.readUnsignedByte();
}
public int readUnsignedShort() throws IOException {
return in.readUnsignedShort();
}
public int readInt() throws IOException {
return in.readInt();
}
public long readLong() throws IOException {
return in.readLong();
}
public float readFloat() throws IOException {
return in.readFloat();
}
public double readDouble() throws IOException {
return in.readDouble();
}
public String readUTF() throws IOException {
return in.readUTF();
}
private DataInputStream in;
private ClassFile classFile;
private Attribute.Factory attributeFactory;
}

View File

@ -0,0 +1,368 @@
/*
* 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. 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.classfile;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Double_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
import com.sun.tools.classfile.ConstantPool.CPInfo;
import java.util.Map;
/**
* Rewrites a class file using a map of translations.
*
* <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 ClassTranslator
implements ConstantPool.Visitor<ConstantPool.CPInfo,Map<Object,Object>> {
/**
* Create a new ClassFile from {@code cf}, such that for all entries
* {@code k&nbsp;-\&gt;&nbsp;v} in {@code translations},
* each occurrence of {@code k} in {@code cf} will be replaced by {@code v}.
* in
* @param cf the class file to be processed
* @param translations the set of translations to be applied
* @return a copy of {@code} with the values in {@code translations} substituted
*/
public ClassFile translate(ClassFile cf, Map<Object,Object> translations) {
ClassFile cf2 = (ClassFile) translations.get(cf);
if (cf2 == null) {
ConstantPool constant_pool2 = translate(cf.constant_pool, translations);
Field[] fields2 = translate(cf.fields, cf.constant_pool, translations);
Method[] methods2 = translateMethods(cf.methods, cf.constant_pool, translations);
Attributes attributes2 = translateAttributes(cf.attributes, cf.constant_pool,
translations);
if (constant_pool2 == cf.constant_pool &&
fields2 == cf.fields &&
methods2 == cf.methods &&
attributes2 == cf.attributes)
cf2 = cf;
else
cf2 = new ClassFile(
cf.magic,
cf.minor_version,
cf.major_version,
constant_pool2,
cf.access_flags,
cf.this_class,
cf.super_class,
cf.interfaces,
fields2,
methods2,
attributes2);
translations.put(cf, cf2);
}
return cf2;
}
ConstantPool translate(ConstantPool cp, Map<Object,Object> translations) {
ConstantPool cp2 = (ConstantPool) translations.get(cp);
if (cp2 == null) {
ConstantPool.CPInfo[] pool2 = new ConstantPool.CPInfo[cp.size()];
boolean eq = true;
for (int i = 0; i < cp.size(); i++) {
ConstantPool.CPInfo cpInfo;
try {
cpInfo = cp.get(i);
} catch (ConstantPool.InvalidIndex e) {
throw new IllegalStateException(e);
}
ConstantPool.CPInfo cpInfo2 = translate(cpInfo, translations);
eq &= (cpInfo == cpInfo2);
pool2[i] = cpInfo2;
if (cpInfo.getTag() != cpInfo2.getTag())
throw new IllegalStateException();
switch (cpInfo.getTag()) {
case ConstantPool.CONSTANT_Double:
case ConstantPool.CONSTANT_Long:
i += 1;
}
}
if (eq)
cp2 = cp;
else
cp2 = new ConstantPool(pool2);
translations.put(cp, cp2);
}
return cp2;
}
ConstantPool.CPInfo translate(ConstantPool.CPInfo cpInfo, Map<Object,Object> translations) {
ConstantPool.CPInfo cpInfo2 = (ConstantPool.CPInfo) translations.get(cpInfo);
if (cpInfo2 == null) {
cpInfo2 = cpInfo.accept(this, translations);
translations.put(cpInfo, cpInfo2);
}
return cpInfo2;
}
Field[] translate(Field[] fields, ConstantPool constant_pool, Map<Object,Object> translations) {
Field[] fields2 = (Field[]) translations.get(fields);
if (fields2 == null) {
fields2 = new Field[fields.length];
for (int i = 0; i < fields.length; i++)
fields2[i] = translate(fields[i], constant_pool, translations);
if (equal(fields, fields2))
fields2 = fields;
translations.put(fields, fields2);
}
return fields2;
}
Field translate(Field field, ConstantPool constant_pool, Map<Object,Object> translations) {
Field field2 = (Field) translations.get(field);
if (field2 == null) {
Attributes attributes2 = translateAttributes(field.attributes, constant_pool,
translations);
if (attributes2 == field.attributes)
field2 = field;
else
field2 = new Field(
field.access_flags,
field.name_index,
field.descriptor,
attributes2);
translations.put(field, field2);
}
return field2;
}
Method[] translateMethods(Method[] methods, ConstantPool constant_pool, Map<Object,Object> translations) {
Method[] methods2 = (Method[]) translations.get(methods);
if (methods2 == null) {
methods2 = new Method[methods.length];
for (int i = 0; i < methods.length; i++)
methods2[i] = translate(methods[i], constant_pool, translations);
if (equal(methods, methods2))
methods2 = methods;
translations.put(methods, methods2);
}
return methods2;
}
Method translate(Method method, ConstantPool constant_pool, Map<Object,Object> translations) {
Method method2 = (Method) translations.get(method);
if (method2 == null) {
Attributes attributes2 = translateAttributes(method.attributes, constant_pool,
translations);
if (attributes2 == method.attributes)
method2 = method;
else
method2 = new Method(
method.access_flags,
method.name_index,
method.descriptor,
attributes2);
translations.put(method, method2);
}
return method2;
}
Attributes translateAttributes(Attributes attributes,
ConstantPool constant_pool, Map<Object,Object> translations) {
Attributes attributes2 = (Attributes) translations.get(attributes);
if (attributes2 == null) {
Attribute[] attrArray2 = new Attribute[attributes.size()];
ConstantPool constant_pool2 = translate(constant_pool, translations);
boolean attrsEqual = true;
for (int i = 0; i < attributes.size(); i++) {
Attribute attr = attributes.get(i);
Attribute attr2 = translate(attr, translations);
if (attr2 != attr)
attrsEqual = false;
attrArray2[i] = attr2;
}
if ((constant_pool2 == constant_pool) && attrsEqual)
attributes2 = attributes;
else
attributes2 = new Attributes(constant_pool2, attrArray2);
translations.put(attributes, attributes2);
}
return attributes2;
}
Attribute translate(Attribute attribute, Map<Object,Object> translations) {
Attribute attribute2 = (Attribute) translations.get(attribute);
if (attribute2 == null) {
attribute2 = attribute; // don't support translation within attributes yet
// (what about Code attribute)
translations.put(attribute, attribute2);
}
return attribute2;
}
private static <T> boolean equal(T[] a1, T[] a2) {
if (a1 == null || a2 == null)
return (a1 == a2);
if (a1.length != a2.length)
return false;
for (int i = 0; i < a1.length; i++) {
if (a1[i] != a2[i])
return false;
}
return true;
}
public CPInfo visitClass(CONSTANT_Class_info info, Map<Object, Object> translations) {
CONSTANT_Class_info info2 = (CONSTANT_Class_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_Class_info(cp2, info.name_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitDouble(CONSTANT_Double_info info, Map<Object, Object> translations) {
CONSTANT_Double_info info2 = (CONSTANT_Double_info) translations.get(info);
if (info2 == null) {
info2 = info;
translations.put(info, info2);
}
return info;
}
public CPInfo visitFieldref(CONSTANT_Fieldref_info info, Map<Object, Object> translations) {
CONSTANT_Fieldref_info info2 = (CONSTANT_Fieldref_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_Fieldref_info(cp2, info.class_index, info.name_and_type_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitFloat(CONSTANT_Float_info info, Map<Object, Object> translations) {
CONSTANT_Float_info info2 = (CONSTANT_Float_info) translations.get(info);
if (info2 == null) {
info2 = info;
translations.put(info, info2);
}
return info;
}
public CPInfo visitInteger(CONSTANT_Integer_info info, Map<Object, Object> translations) {
CONSTANT_Integer_info info2 = (CONSTANT_Integer_info) translations.get(info);
if (info2 == null) {
info2 = info;
translations.put(info, info2);
}
return info;
}
public CPInfo visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Map<Object, Object> translations) {
CONSTANT_InterfaceMethodref_info info2 = (CONSTANT_InterfaceMethodref_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_InterfaceMethodref_info(cp2, info.class_index, info.name_and_type_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitLong(CONSTANT_Long_info info, Map<Object, Object> translations) {
CONSTANT_Long_info info2 = (CONSTANT_Long_info) translations.get(info);
if (info2 == null) {
info2 = info;
translations.put(info, info2);
}
return info;
}
public CPInfo visitNameAndType(CONSTANT_NameAndType_info info, Map<Object, Object> translations) {
CONSTANT_NameAndType_info info2 = (CONSTANT_NameAndType_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_NameAndType_info(cp2, info.name_index, info.type_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitMethodref(CONSTANT_Methodref_info info, Map<Object, Object> translations) {
CONSTANT_Methodref_info info2 = (CONSTANT_Methodref_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_Methodref_info(cp2, info.class_index, info.name_and_type_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitString(CONSTANT_String_info info, Map<Object, Object> translations) {
CONSTANT_String_info info2 = (CONSTANT_String_info) translations.get(info);
if (info2 == null) {
ConstantPool cp2 = translate(info.cp, translations);
if (cp2 == info.cp)
info2 = info;
else
info2 = new CONSTANT_String_info(cp2, info.string_index);
translations.put(info, info2);
}
return info;
}
public CPInfo visitUtf8(CONSTANT_Utf8_info info, Map<Object, Object> translations) {
CONSTANT_Utf8_info info2 = (CONSTANT_Utf8_info) translations.get(info);
if (info2 == null) {
info2 = info;
translations.put(info, info2);
}
return info;
}
}

View File

@ -0,0 +1,689 @@
/*
* 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. 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.classfile;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import static com.sun.tools.classfile.Annotation.*;
import static com.sun.tools.classfile.ConstantPool.*;
import static com.sun.tools.classfile.StackMapTable_attribute.*;
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
/**
* Write a ClassFile data structure to a file or stream.
*
* <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 ClassWriter {
public ClassWriter() {
attributeWriter = new AttributeWriter();
constantPoolWriter = new ConstantPoolWriter();
out = new ClassOutputStream();
}
/**
* Write a ClassFile data structure to a file.
*/
public void write(ClassFile classFile, File f) throws IOException {
FileOutputStream f_out = new FileOutputStream(f);
try {
write(classFile, f_out);
} finally {
f_out.close();
}
}
/**
* Write a ClassFile data structure to a stream.
*/
public void write(ClassFile classFile, OutputStream s) throws IOException {
this.classFile = classFile;
out.reset();
write();
out.writeTo(s);
}
protected void write() throws IOException {
writeHeader();
writeConstantPool();
writeAccessFlags(classFile.access_flags);
writeClassInfo();
writeFields();
writeMethods();
writeAttributes(classFile.attributes);
}
protected void writeHeader() {
out.writeInt(classFile.magic);
out.writeShort(classFile.minor_version);
out.writeShort(classFile.major_version);
}
protected void writeAccessFlags(AccessFlags flags) {
out.writeShort(flags.flags);
}
protected void writeAttributes(Attributes attributes) {
int size = attributes.size();
out.writeShort(size);
for (Attribute attr: attributes)
attributeWriter.write(attr, out);
}
protected void writeClassInfo() {
out.writeShort(classFile.this_class);
out.writeShort(classFile.super_class);
int[] interfaces = classFile.interfaces;
out.writeShort(interfaces.length);
for (int i: interfaces)
out.writeShort(i);
}
protected void writeDescriptor(Descriptor d) {
out.writeShort(d.index);
}
protected void writeConstantPool() {
ConstantPool pool = classFile.constant_pool;
int size = pool.size();
out.writeShort(size);
try {
for (int i = 1; i < size; ) {
i += constantPoolWriter.write(pool.get(i), out);
}
} catch (ConstantPoolException e) {
throw new Error(e); // ??
}
}
protected void writeFields() throws IOException {
Field[] fields = classFile.fields;
out.writeShort(fields.length);
for (Field f: fields)
writeField(f);
}
protected void writeField(Field f) throws IOException {
writeAccessFlags(f.access_flags);
out.writeShort(f.name_index);
writeDescriptor(f.descriptor);
writeAttributes(f.attributes);
}
protected void writeMethods() throws IOException {
Method[] methods = classFile.methods;
out.writeShort(methods.length);
for (Method m: methods) {
writeMethod(m);
}
}
protected void writeMethod(Method m) throws IOException {
writeAccessFlags(m.access_flags);
out.writeShort(m.name_index);
writeDescriptor(m.descriptor);
writeAttributes(m.attributes);
}
protected ClassFile classFile;
protected ClassOutputStream out;
protected AttributeWriter attributeWriter;
protected ConstantPoolWriter constantPoolWriter;
/**
* Subtype of ByteArrayOutputStream with the convenience methods of
* a DataOutputStream. Since ByteArrayOutputStream does not throw
* IOException, there are no exceptions from the additional
* convenience methods either,
*/
protected static class ClassOutputStream extends ByteArrayOutputStream {
public ClassOutputStream() {
d = new DataOutputStream(this);
}
public void writeByte(int value) {
try {
d.writeByte(value);
} catch (IOException ignore) {
}
}
public void writeShort(int value) {
try {
d.writeShort(value);
} catch (IOException ignore) {
}
}
public void writeInt(int value) {
try {
d.writeInt(value);
} catch (IOException ignore) {
}
}
public void writeLong(long value) {
try {
d.writeLong(value);
} catch (IOException ignore) {
}
}
public void writeFloat(float value) {
try {
d.writeFloat(value);
} catch (IOException ignore) {
}
}
public void writeDouble(double value) {
try {
d.writeDouble(value);
} catch (IOException ignore) {
}
}
public void writeUTF(String value) {
try {
d.writeUTF(value);
} catch (IOException ignore) {
}
}
public void writeTo(ClassOutputStream s) {
try {
super.writeTo(s);
} catch (IOException ignore) {
}
}
private DataOutputStream d;
}
/**
* Writer for the entries in the constant pool.
*/
protected static class ConstantPoolWriter
implements ConstantPool.Visitor<Integer,ClassOutputStream> {
protected int write(CPInfo info, ClassOutputStream out) {
out.writeByte(info.getTag());
return info.accept(this, out);
}
public Integer visitClass(CONSTANT_Class_info info, ClassOutputStream out) {
out.writeShort(info.name_index);
return 1;
}
public Integer visitDouble(CONSTANT_Double_info info, ClassOutputStream out) {
out.writeDouble(info.value);
return 2;
}
public Integer visitFieldref(CONSTANT_Fieldref_info info, ClassOutputStream out) {
writeRef(info, out);
return 1;
}
public Integer visitFloat(CONSTANT_Float_info info, ClassOutputStream out) {
out.writeFloat(info.value);
return 1;
}
public Integer visitInteger(CONSTANT_Integer_info info, ClassOutputStream out) {
out.writeInt(info.value);
return 1;
}
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ClassOutputStream out) {
writeRef(info, out);
return 1;
}
public Integer visitLong(CONSTANT_Long_info info, ClassOutputStream out) {
out.writeLong(info.value);
return 2;
}
public Integer visitNameAndType(CONSTANT_NameAndType_info info, ClassOutputStream out) {
out.writeShort(info.name_index);
out.writeShort(info.type_index);
return 1;
}
public Integer visitMethodref(CONSTANT_Methodref_info info, ClassOutputStream out) {
return writeRef(info, out);
}
public Integer visitString(CONSTANT_String_info info, ClassOutputStream out) {
out.writeShort(info.string_index);
return 1;
}
public Integer visitUtf8(CONSTANT_Utf8_info info, ClassOutputStream out) {
out.writeUTF(info.value);
return 1;
}
protected Integer writeRef(CPRefInfo info, ClassOutputStream out) {
out.writeShort(info.class_index);
out.writeShort(info.name_and_type_index);
return 1;
}
}
/**
* Writer for the different types of attribute.
*/
protected static class AttributeWriter implements Attribute.Visitor<Void,ClassOutputStream> {
public void write(Attributes attributes, ClassOutputStream out) {
int size = attributes.size();
out.writeShort(size);
for (Attribute a: attributes)
write(a, out);
}
// Note: due to the use of shared resources, this method is not reentrant.
public void write(Attribute attr, ClassOutputStream out) {
out.writeShort(attr.attribute_name_index);
sharedOut.reset();
attr.accept(this, sharedOut);
out.writeInt(sharedOut.size());
sharedOut.writeTo(out);
}
protected ClassOutputStream sharedOut = new ClassOutputStream();
protected AnnotationWriter annotationWriter = new AnnotationWriter();
public Void visitDefault(DefaultAttribute attr, ClassOutputStream out) {
out.write(attr.info, 0, attr.info.length);
return null;
}
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, ClassOutputStream out) {
annotationWriter.write(attr.default_value, out);
return null;
}
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.character_range_table.length);
for (CharacterRangeTable_attribute.Entry e: attr.character_range_table)
writeCharacterRangeTableEntry(e, out);
return null;
}
protected void writeCharacterRangeTableEntry(CharacterRangeTable_attribute.Entry entry, ClassOutputStream out) {
out.writeShort(entry.start_pc);
out.writeShort(entry.end_pc);
out.writeInt(entry.character_range_start);
out.writeInt(entry.character_range_end);
out.writeShort(entry.flags);
}
public Void visitCode(Code_attribute attr, ClassOutputStream out) {
out.writeShort(attr.max_stack);
out.writeShort(attr.max_locals);
out.writeInt(attr.code.length);
out.write(attr.code, 0, attr.code.length);
out.writeShort(attr.exception_table.length);
for (Code_attribute.Exception_data e: attr.exception_table)
writeExceptionTableEntry(e, out);
new AttributeWriter().write(attr.attributes, out);
return null;
}
protected void writeExceptionTableEntry(Code_attribute.Exception_data exception_data, ClassOutputStream out) {
out.writeShort(exception_data.start_pc);
out.writeShort(exception_data.end_pc);
out.writeShort(exception_data.handler_pc);
out.writeShort(exception_data.catch_type);
}
public Void visitCompilationID(CompilationID_attribute attr, ClassOutputStream out) {
out.writeShort(attr.compilationID_index);
return null;
}
public Void visitConstantValue(ConstantValue_attribute attr, ClassOutputStream out) {
out.writeShort(attr.constantvalue_index);
return null;
}
public Void visitDeprecated(Deprecated_attribute attr, ClassOutputStream out) {
return null;
}
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, ClassOutputStream out) {
out.writeShort(attr.class_index);
out.writeShort(attr.method_index);
return null;
}
public Void visitExceptions(Exceptions_attribute attr, ClassOutputStream out) {
out.writeShort(attr.exception_index_table.length);
for (int i: attr.exception_index_table)
out.writeShort(i);
return null;
}
public Void visitInnerClasses(InnerClasses_attribute attr, ClassOutputStream out) {
out.writeShort(attr.classes.length);
for (InnerClasses_attribute.Info info: attr.classes)
writeInnerClassesInfo(info, out);
return null;
}
protected void writeInnerClassesInfo(InnerClasses_attribute.Info info, ClassOutputStream out) {
out.writeShort(info.inner_class_info_index);
out.writeShort(info.outer_class_info_index);
out.writeShort(info.inner_name_index);
writeAccessFlags(info.inner_class_access_flags, out);
}
public Void visitLineNumberTable(LineNumberTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.line_number_table.length);
for (LineNumberTable_attribute.Entry e: attr.line_number_table)
writeLineNumberTableEntry(e, out);
return null;
}
protected void writeLineNumberTableEntry(LineNumberTable_attribute.Entry entry, ClassOutputStream out) {
out.writeShort(entry.start_pc);
out.writeShort(entry.line_number);
}
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.local_variable_table.length);
for (LocalVariableTable_attribute.Entry e: attr.local_variable_table)
writeLocalVariableTableEntry(e, out);
return null;
}
protected void writeLocalVariableTableEntry(LocalVariableTable_attribute.Entry entry, ClassOutputStream out) {
out.writeShort(entry.start_pc);
out.writeShort(entry.length);
out.writeShort(entry.name_index);
out.writeShort(entry.descriptor_index);
out.writeShort(entry.index);
}
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, ClassOutputStream out) {
out.writeByte(attr.local_variable_table.length);
for (LocalVariableTypeTable_attribute.Entry e: attr.local_variable_table)
writeLocalVariableTypeTableEntry(e, out);
return null;
}
protected void writeLocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry, ClassOutputStream out) {
out.writeShort(entry.start_pc);
out.writeShort(entry.length);
out.writeShort(entry.name_index);
out.writeShort(entry.signature_index);
out.writeShort(entry.index);
}
public Void visitModule(Module_attribute attr, ClassOutputStream out) {
out.writeShort(attr.module_name);
return null;
}
public Void visitModuleExportTable(ModuleExportTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.export_type_table.length);
for (int i: attr.export_type_table)
out.writeShort(i);
return null;
}
public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, ClassOutputStream out) {
out.writeShort(attr.package_member_table.length);
for (int i: attr.package_member_table)
out.writeShort(i);
return null;
}
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, ClassOutputStream out) {
annotationWriter.write(attr.annotations, out);
return null;
}
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, ClassOutputStream out) {
annotationWriter.write(attr.annotations, out);
return null;
}
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
out.writeByte(attr.parameter_annotations.length);
for (Annotation[] annos: attr.parameter_annotations)
annotationWriter.write(annos, out);
return null;
}
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
out.writeByte(attr.parameter_annotations.length);
for (Annotation[] annos: attr.parameter_annotations)
annotationWriter.write(annos, out);
return null;
}
public Void visitSignature(Signature_attribute attr, ClassOutputStream out) {
out.writeShort(attr.signature_index);
return null;
}
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, ClassOutputStream out) {
out.write(attr.debug_extension, 0, attr.debug_extension.length);
return null;
}
public Void visitSourceFile(SourceFile_attribute attr, ClassOutputStream out) {
out.writeShort(attr.sourcefile_index);
return null;
}
public Void visitSourceID(SourceID_attribute attr, ClassOutputStream out) {
out.writeShort(attr.sourceID_index);
return null;
}
public Void visitStackMap(StackMap_attribute attr, ClassOutputStream out) {
if (stackMapWriter == null)
stackMapWriter = new StackMapTableWriter();
out.writeShort(attr.entries.length);
for (stack_map_frame f: attr.entries)
stackMapWriter.write(f, out);
return null;
}
public Void visitStackMapTable(StackMapTable_attribute attr, ClassOutputStream out) {
if (stackMapWriter == null)
stackMapWriter = new StackMapTableWriter();
out.writeShort(attr.entries.length);
for (stack_map_frame f: attr.entries)
stackMapWriter.write(f, out);
return null;
}
public Void visitSynthetic(Synthetic_attribute attr, ClassOutputStream out) {
return null;
}
protected void writeAccessFlags(AccessFlags flags, ClassOutputStream p) {
sharedOut.writeShort(flags.flags);
}
protected StackMapTableWriter stackMapWriter;
}
/**
* Writer for the frames of StackMap and StackMapTable attributes.
*/
protected static class StackMapTableWriter
implements stack_map_frame.Visitor<Void,ClassOutputStream> {
public void write(stack_map_frame frame, ClassOutputStream out) {
out.write(frame.frame_type);
frame.accept(this, out);
}
public Void visit_same_frame(same_frame frame, ClassOutputStream p) {
return null;
}
public Void visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, ClassOutputStream out) {
writeVerificationTypeInfo(frame.stack[0], out);
return null;
}
public Void visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, ClassOutputStream out) {
out.writeShort(frame.offset_delta);
writeVerificationTypeInfo(frame.stack[0], out);
return null;
}
public Void visit_chop_frame(chop_frame frame, ClassOutputStream out) {
out.writeShort(frame.offset_delta);
return null;
}
public Void visit_same_frame_extended(same_frame_extended frame, ClassOutputStream out) {
out.writeShort(frame.offset_delta);
return null;
}
public Void visit_append_frame(append_frame frame, ClassOutputStream out) {
out.writeShort(frame.offset_delta);
for (verification_type_info l: frame.locals)
writeVerificationTypeInfo(l, out);
return null;
}
public Void visit_full_frame(full_frame frame, ClassOutputStream out) {
out.writeShort(frame.offset_delta);
out.writeShort(frame.locals.length);
for (verification_type_info l: frame.locals)
writeVerificationTypeInfo(l, out);
out.writeShort(frame.stack.length);
for (verification_type_info s: frame.stack)
writeVerificationTypeInfo(s, out);
return null;
}
protected void writeVerificationTypeInfo(verification_type_info info,
ClassOutputStream out) {
out.write(info.tag);
switch (info.tag) {
case ITEM_Top:
case ITEM_Integer:
case ITEM_Float:
case ITEM_Long:
case ITEM_Double:
case ITEM_Null:
case ITEM_UninitializedThis:
break;
case ITEM_Object:
Object_variable_info o = (Object_variable_info) info;
out.writeShort(o.cpool_index);
break;
case ITEM_Uninitialized:
Uninitialized_variable_info u = (Uninitialized_variable_info) info;
out.writeShort(u.offset);
break;
default:
throw new Error();
}
}
}
/**
* Writer for annotations and the values they contain.
*/
protected static class AnnotationWriter
implements Annotation.element_value.Visitor<Void,ClassOutputStream> {
public void write(Annotation[] annos, ClassOutputStream out) {
out.writeShort(annos.length);
for (Annotation anno: annos)
write(anno, out);
}
public void write(Annotation anno, ClassOutputStream out) {
out.writeShort(anno.type_index);
out.writeShort(anno.element_value_pairs.length);
for (element_value_pair p: anno.element_value_pairs)
write(p, out);
}
public void write(element_value_pair pair, ClassOutputStream out) {
out.writeShort(pair.element_name_index);
write(pair.value, out);
}
public void write(element_value ev, ClassOutputStream out) {
out.writeByte(ev.tag);
ev.accept(this, out);
}
public Void visitPrimitive(Primitive_element_value ev, ClassOutputStream out) {
out.writeShort(ev.const_value_index);
return null;
}
public Void visitEnum(Enum_element_value ev, ClassOutputStream out) {
out.writeShort(ev.type_name_index);
out.writeShort(ev.const_name_index);
return null;
}
public Void visitClass(Class_element_value ev, ClassOutputStream out) {
out.writeShort(ev.class_info_index);
return null;
}
public Void visitAnnotation(Annotation_element_value ev, ClassOutputStream out) {
write(ev.annotation_value, out);
return null;
}
public Void visitArray(Array_element_value ev, ClassOutputStream out) {
out.writeShort(ev.num_values);
for (element_value v: ev.values)
write(v, out);
return null;
}
}
}

View File

@ -0,0 +1,123 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.3.
*
* <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 Code_attribute extends Attribute {
public class InvalidIndex extends AttributeException {
InvalidIndex(int index) {
this.index = index;
}
@Override
public String getMessage() {
// i18n
return "invalid index " + index + " in Code attribute";
}
public final int index;
}
Code_attribute(ClassReader cr, int name_index, int length)
throws IOException, ConstantPoolException {
super(name_index, length);
max_stack = cr.readUnsignedShort();
max_locals = cr.readUnsignedShort();
code_length = cr.readInt();
code = new byte[code_length];
cr.readFully(code);
exception_table_langth = cr.readUnsignedShort();
exception_table = new Exception_data[exception_table_langth];
for (int i = 0; i < exception_table_langth; i++)
exception_table[i] = new Exception_data(cr);
attributes = new Attributes(cr);
}
public int getByte(int offset) throws InvalidIndex {
if (offset < 0 || offset >= code.length)
throw new InvalidIndex(offset);
return code[offset];
}
public int getUnsignedByte(int offset) throws InvalidIndex {
if (offset < 0 || offset >= code.length)
throw new InvalidIndex(offset);
return code[offset] & 0xff;
}
public int getShort(int offset) throws InvalidIndex {
if (offset < 0 || offset + 1 >= code.length)
throw new InvalidIndex(offset);
return (code[offset] << 8) | (code[offset + 1] & 0xFF);
}
public int getUnsignedShort(int offset) throws InvalidIndex {
if (offset < 0 || offset + 1 >= code.length)
throw new InvalidIndex(offset);
return ((code[offset] << 8) | (code[offset + 1] & 0xFF)) & 0xFFFF;
}
public int getInt(int offset) throws InvalidIndex {
if (offset < 0 || offset + 3 >= code.length)
throw new InvalidIndex(offset);
return (getShort(offset) << 16) | (getShort(offset + 2) & 0xFFFF);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitCode(this, data);
}
public final int max_stack;
public final int max_locals;
public final int code_length;
public final byte[] code;
public final int exception_table_langth;
public final Exception_data[] exception_table;
public final Attributes attributes;
public class Exception_data {
Exception_data(ClassReader cr) throws IOException {
start_pc = cr.readUnsignedShort();
end_pc = cr.readUnsignedShort();
handler_pc = cr.readUnsignedShort();
catch_type = cr.readUnsignedShort();
}
public final int start_pc;
public final int end_pc;
public final int handler_pc;
public final int catch_type;
}
}

View File

@ -0,0 +1,62 @@
/*
* 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. 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.classfile;
import java.io.IOException;
/**
* <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 CompilationID_attribute extends Attribute {
CompilationID_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
compilationID_index = cr.readUnsignedShort();
}
public CompilationID_attribute(ConstantPool constant_pool, int compilationID_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.CompilationID), compilationID_index);
}
public CompilationID_attribute(int name_index, int compilationID_index) {
super(name_index, 2);
this.compilationID_index = compilationID_index;
}
String getCompilationID(ConstantPool constant_pool)
throws ConstantPoolException {
return constant_pool.getUTF8Value(compilationID_index);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitCompilationID(this, data);
}
public final int compilationID_index;
}

View File

@ -0,0 +1,562 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.5.
*
* <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 ConstantPool {
public class InvalidIndex extends ConstantPoolException {
InvalidIndex(int index) {
super(index);
}
@Override
public String getMessage() {
// i18n
return "invalid index #" + index;
}
}
public class UnexpectedEntry extends ConstantPoolException {
UnexpectedEntry(int index, int expected_tag, int found_tag) {
super(index);
this.expected_tag = expected_tag;
this.found_tag = found_tag;
}
@Override
public String getMessage() {
// i18n?
return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
}
public final int expected_tag;
public final int found_tag;
}
public class InvalidEntry extends ConstantPoolException {
InvalidEntry(int index, int tag) {
super(index);
this.tag = tag;
}
@Override
public String getMessage() {
// i18n?
return "unexpected tag at #" + index + ": " + tag;
}
public final int tag;
}
public class EntryNotFound extends ConstantPoolException {
EntryNotFound(Object value) {
super(-1);
this.value = value;
}
@Override
public String getMessage() {
// i18n?
return "value not found: " + value;
}
public final Object value;
}
public static final int CONSTANT_Utf8 = 1;
public static final int CONSTANT_Integer = 3;
public static final int CONSTANT_Float = 4;
public static final int CONSTANT_Long = 5;
public static final int CONSTANT_Double = 6;
public static final int CONSTANT_Class = 7;
public static final int CONSTANT_String = 8;
public static final int CONSTANT_Fieldref = 9;
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
int count = cr.readUnsignedShort();
pool = new CPInfo[count];
for (int i = 1; i < count; i++) {
int tag = cr.readUnsignedByte();
switch (tag) {
case CONSTANT_Class:
pool[i] = new CONSTANT_Class_info(this, cr);
break;
case CONSTANT_Double:
pool[i] = new CONSTANT_Double_info(cr);
i++;
break;
case CONSTANT_Fieldref:
pool[i] = new CONSTANT_Fieldref_info(this, cr);
break;
case CONSTANT_Float:
pool[i] = new CONSTANT_Float_info(cr);
break;
case CONSTANT_Integer:
pool[i] = new CONSTANT_Integer_info(cr);
break;
case CONSTANT_InterfaceMethodref:
pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
break;
case CONSTANT_Long:
pool[i] = new CONSTANT_Long_info(cr);
i++;
break;
case CONSTANT_Methodref:
pool[i] = new CONSTANT_Methodref_info(this, cr);
break;
case CONSTANT_NameAndType:
pool[i] = new CONSTANT_NameAndType_info(this, cr);
break;
case CONSTANT_String:
pool[i] = new CONSTANT_String_info(cr);
break;
case CONSTANT_Utf8:
pool[i] = new CONSTANT_Utf8_info(cr);
break;
default:
throw new InvalidEntry(i, tag);
}
}
}
public ConstantPool(CPInfo[] pool) {
this.pool = pool;
}
public int size() {
return pool.length;
}
public CPInfo get(int index) throws InvalidIndex {
if (index <= 0 || index >= pool.length)
throw new InvalidIndex(index);
CPInfo info = pool[index];
if (info == null) {
// this occurs for indices referencing the "second half" of an
// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
throw new InvalidIndex(index);
}
return pool[index];
}
private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
CPInfo info = get(index);
if (info.getTag() != expected_type)
throw new UnexpectedEntry(index, expected_type, info.getTag());
return info;
}
public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
}
public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
}
public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
}
public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
return getUTF8Info(index).value;
}
public int getUTF8Index(String value) throws EntryNotFound {
for (int i = 1; i < pool.length; i++) {
CPInfo info = pool[i];
if (info instanceof CONSTANT_Utf8_info &&
((CONSTANT_Utf8_info) info).value.equals(value))
return i;
}
throw new EntryNotFound(value);
}
private CPInfo[] pool;
public interface Visitor<R,P> {
R visitClass(CONSTANT_Class_info info, P p);
R visitDouble(CONSTANT_Double_info info, P p);
R visitFieldref(CONSTANT_Fieldref_info info, P p);
R visitFloat(CONSTANT_Float_info info, P p);
R visitInteger(CONSTANT_Integer_info info, P p);
R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
R visitLong(CONSTANT_Long_info info, P p);
R visitNameAndType(CONSTANT_NameAndType_info info, P p);
R visitMethodref(CONSTANT_Methodref_info info, P p);
R visitString(CONSTANT_String_info info, P p);
R visitUtf8(CONSTANT_Utf8_info info, P p);
}
public static abstract class CPInfo {
CPInfo() {
this.cp = null;
}
CPInfo(ConstantPool cp) {
this.cp = cp;
}
public abstract int getTag();
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
protected final ConstantPool cp;
}
public static abstract class CPRefInfo extends CPInfo {
protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
super(cp);
this.tag = tag;
class_index = cr.readUnsignedShort();
name_and_type_index = cr.readUnsignedShort();
}
protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
super(cp);
this.tag = tag;
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
public int getTag() {
return tag;
}
public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
return cp.getClassInfo(class_index);
}
public String getClassName() throws ConstantPoolException {
return cp.getClassInfo(class_index).getName();
}
public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
return cp.getNameAndTypeInfo(name_and_type_index);
}
public final int tag;
public final int class_index;
public final int name_and_type_index;
}
public static class CONSTANT_Class_info extends CPInfo {
CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp);
name_index = cr.readUnsignedShort();
}
public CONSTANT_Class_info(ConstantPool cp, int name_index) {
super(cp);
this.name_index = name_index;
}
public int getTag() {
return CONSTANT_Class;
}
public String getName() throws ConstantPoolException {
return cp.getUTF8Value(name_index);
}
@Override
public String toString() {
return "CONSTANT_Class_info[name_index: " + name_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitClass(this, data);
}
public final int name_index;
}
public static class CONSTANT_Double_info extends CPInfo {
CONSTANT_Double_info(ClassReader cr) throws IOException {
value = cr.readDouble();
}
public CONSTANT_Double_info(double value) {
this.value = value;
}
public int getTag() {
return CONSTANT_Double;
}
@Override
public String toString() {
return "CONSTANT_Double_info[value: " + value + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitDouble(this, data);
}
public final double value;
}
public static class CONSTANT_Fieldref_info extends CPRefInfo {
CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp, cr, CONSTANT_Fieldref);
}
public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
}
@Override
public String toString() {
return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitFieldref(this, data);
}
}
public static class CONSTANT_Float_info extends CPInfo {
CONSTANT_Float_info(ClassReader cr) throws IOException {
value = cr.readFloat();
}
public CONSTANT_Float_info(float value) {
this.value = value;
}
public int getTag() {
return CONSTANT_Float;
}
@Override
public String toString() {
return "CONSTANT_Float_info[value: " + value + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitFloat(this, data);
}
public final float value;
}
public static class CONSTANT_Integer_info extends CPInfo {
CONSTANT_Integer_info(ClassReader cr) throws IOException {
value = cr.readInt();
}
public CONSTANT_Integer_info(int value) {
this.value = value;
}
public int getTag() {
return CONSTANT_Integer;
}
@Override
public String toString() {
return "CONSTANT_Integer_info[value: " + value + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitInteger(this, data);
}
public final int value;
}
public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp, cr, CONSTANT_InterfaceMethodref);
}
public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
}
@Override
public String toString() {
return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitInterfaceMethodref(this, data);
}
}
public static class CONSTANT_Long_info extends CPInfo {
CONSTANT_Long_info(ClassReader cr) throws IOException {
value = cr.readLong();
}
public CONSTANT_Long_info(long value) {
this.value = value;
}
public int getTag() {
return CONSTANT_Long;
}
@Override
public String toString() {
return "CONSTANT_Long_info[value: " + value + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitLong(this, data);
}
public final long value;
}
public static class CONSTANT_Methodref_info extends CPRefInfo {
CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp, cr, CONSTANT_Methodref);
}
public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
}
@Override
public String toString() {
return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitMethodref(this, data);
}
}
public static class CONSTANT_NameAndType_info extends CPInfo {
CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
super(cp);
name_index = cr.readUnsignedShort();
type_index = cr.readUnsignedShort();
}
public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
super(cp);
this.name_index = name_index;
this.type_index = type_index;
}
public int getTag() {
return CONSTANT_NameAndType;
}
public String getName() throws ConstantPoolException {
return cp.getUTF8Value(name_index);
}
public String getType() throws ConstantPoolException {
return cp.getUTF8Value(type_index);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitNameAndType(this, data);
}
public final int name_index;
public final int type_index;
}
public static class CONSTANT_String_info extends CPInfo {
CONSTANT_String_info(ClassReader cr) throws IOException {
string_index = cr.readUnsignedShort();
}
public CONSTANT_String_info(ConstantPool cp, int string_index) {
super(cp);
this.string_index = string_index;
}
public int getTag() {
return CONSTANT_String;
}
public String getString() throws ConstantPoolException {
return cp.getUTF8Value(string_index);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitString(this, data);
}
public final int string_index;
}
public static class CONSTANT_Utf8_info extends CPInfo {
CONSTANT_Utf8_info(ClassReader cr) throws IOException {
value = cr.readUTF();
}
public CONSTANT_Utf8_info(String value) {
this.value = value;
}
public int getTag() {
return CONSTANT_Utf8;
}
@Override
public String toString() {
return "CONSTANT_Utf8_info[value: " + value + "]";
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitUtf8(this, data);
}
public final String value;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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. 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.classfile;
/*
* <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 ConstantPoolException extends Exception {
ConstantPoolException(int index) {
this.index = index;
}
public final int index;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.2.
*
* <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 ConstantValue_attribute extends Attribute {
ConstantValue_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
constantvalue_index = cr.readUnsignedShort();
}
public ConstantValue_attribute(ConstantPool constant_pool, int constantvalue_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.ConstantValue), constantvalue_index);
}
public ConstantValue_attribute(int name_index, int constantvalue_index) {
super(name_index, 2);
this.constantvalue_index = constantvalue_index;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitConstantValue(this, data);
}
public final int constantvalue_index;
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2007 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.classfile;
/*
* <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 DefaultAttribute extends Attribute {
DefaultAttribute(ClassReader cr, int name_index, byte[] data) {
super(name_index, data.length);
info = data;
}
public DefaultAttribute(ConstantPool constant_pool, int name_index, byte[] info) {
super(name_index, info.length);
this.info = info;
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitDefault(this, p);
}
public final byte[] info;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.15.
*
* <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 Deprecated_attribute extends Attribute {
Deprecated_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
}
public Deprecated_attribute(ConstantPool constant_pool)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Deprecated));
}
public Deprecated_attribute(int name_index) {
super(name_index, 0);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitDeprecated(this, data);
}
}

View File

@ -0,0 +1,198 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.4.
*
* <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 Descriptor {
public class InvalidDescriptor extends DescriptorException {
InvalidDescriptor(String desc) {
this.desc = desc;
this.index = -1;
}
InvalidDescriptor(String desc, int index) {
this.desc = desc;
this.index = index;
}
@Override
public String getMessage() {
// i18n
if (index == -1)
return "invalid descriptor \"" + desc + "\"";
else
return "descriptor is invalid at offset " + index + " in \"" + desc + "\"";
}
public final String desc;
public final int index;
}
public Descriptor(ClassReader cr) throws IOException {
this(cr.readUnsignedShort());
}
public Descriptor(int index) {
this.index = index;
}
public String getValue(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(index);
}
public int getParameterCount(ConstantPool constant_pool)
throws ConstantPoolException, InvalidDescriptor {
String desc = getValue(constant_pool);
int end = desc.indexOf(")");
if (end == -1)
throw new InvalidDescriptor(desc);
parse(desc, 0, end + 1);
return count;
}
public String getParameterTypes(ConstantPool constant_pool)
throws ConstantPoolException, InvalidDescriptor {
String desc = getValue(constant_pool);
int end = desc.indexOf(")");
if (end == -1)
throw new InvalidDescriptor(desc);
return parse(desc, 0, end + 1);
}
public String getReturnType(ConstantPool constant_pool)
throws ConstantPoolException, InvalidDescriptor {
String desc = getValue(constant_pool);
int end = desc.indexOf(")");
if (end == -1)
throw new InvalidDescriptor(desc);
return parse(desc, end + 1, desc.length());
}
public String getFieldType(ConstantPool constant_pool)
throws ConstantPoolException, InvalidDescriptor {
String desc = getValue(constant_pool);
return parse(desc, 0, desc.length());
}
private String parse(String desc, int start, int end)
throws InvalidDescriptor {
int p = start;
StringBuffer sb = new StringBuffer();
int dims = 0;
count = 0;
while (p < end) {
String type;
char ch;
switch (ch = desc.charAt(p++)) {
case '(':
sb.append('(');
continue;
case ')':
sb.append(')');
continue;
case '[':
dims++;
continue;
case 'B':
type = "byte";
break;
case 'C':
type = "char";
break;
case 'D':
type = "double";
break;
case 'F':
type = "float";
break;
case 'I':
type = "int";
break;
case 'J':
type = "long";
break;
case 'L':
int sep = desc.indexOf(';', p);
if (sep == -1)
throw new InvalidDescriptor(desc, p - 1);
type = desc.substring(p, sep).replace('/', '.');
p = sep + 1;
break;
case 'S':
type = "short";
break;
case 'Z':
type = "boolean";
break;
case 'V':
type = "void";
break;
default:
throw new InvalidDescriptor(desc, p - 1);
}
if (sb.length() > 1 && sb.charAt(0) == '(')
sb.append(", ");
sb.append(type);
for ( ; dims > 0; dims-- )
sb.append("[]");
count++;
}
return sb.toString();
}
public final int index;
private int count;
}

View File

@ -0,0 +1,36 @@
/*
* 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. 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.classfile;
/*
* <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 DescriptorException extends Exception {
}

View File

@ -0,0 +1,73 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.7.
*
* <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 EnclosingMethod_attribute extends Attribute {
EnclosingMethod_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
class_index = cr.readUnsignedShort();
method_index = cr.readUnsignedShort();
}
public EnclosingMethod_attribute(ConstantPool constant_pool, int class_index, int method_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.EnclosingMethod), class_index, method_index);
}
public EnclosingMethod_attribute(int name_index, int class_index, int method_index) {
super(name_index, 4);
this.class_index = class_index;
this.method_index = method_index;
}
public String getClassName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getClassInfo(class_index).getName();
}
public String getMethodName(ConstantPool constant_pool) throws ConstantPoolException {
if (method_index == 0)
return "";
return constant_pool.getNameAndTypeInfo(method_index).getName();
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitEnclosingMethod(this, data);
}
public final int class_index;
public final int method_index;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.5.
*
* <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 Exceptions_attribute extends Attribute {
Exceptions_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
number_of_exceptions = cr.readUnsignedShort();
exception_index_table = new int[number_of_exceptions];
for (int i = 0; i < number_of_exceptions; i++)
exception_index_table[i] = cr.readUnsignedShort();
}
public Exceptions_attribute(ConstantPool constant_pool, int[] exception_index_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Exceptions), exception_index_table);
}
public Exceptions_attribute(int name_index, int[] exception_index_table) {
super(name_index, 2 + 2 * exception_index_table.length);
this.number_of_exceptions = exception_index_table.length;
this.exception_index_table = exception_index_table;
}
public String getException(int index, ConstantPool constant_pool) throws ConstantPoolException {
int exception_index = exception_index_table[index];
return constant_pool.getClassInfo(exception_index).getName();
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitExceptions(this, data);
}
public final int number_of_exceptions;
public final int[] exception_index_table;
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/*
* <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 Field {
Field(ClassReader cr) throws IOException {
access_flags = new AccessFlags(cr);
name_index = cr.readUnsignedShort();
descriptor = new Descriptor(cr);
attributes = new Attributes(cr);
}
public Field(AccessFlags access_flags,
int name_index, Descriptor descriptor,
Attributes attributes) {
this.access_flags = access_flags;
this.name_index = name_index;
this.descriptor = descriptor;
this.attributes = attributes;
}
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(name_index);
}
public final AccessFlags access_flags;
public final int name_index;
public final Descriptor descriptor;
public final Attributes attributes;
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
import com.sun.tools.classfile.ConstantPool.*;
/**
* See JVMS3, section 4.8.6.
*
* <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 InnerClasses_attribute extends Attribute {
InnerClasses_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
number_of_classes = cr.readUnsignedShort();
classes = new Info[number_of_classes];
for (int i = 0; i < number_of_classes; i++)
classes[i] = new Info(cr);
}
public InnerClasses_attribute(ConstantPool constant_pool, Info[] classes)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.InnerClasses), classes);
}
public InnerClasses_attribute(int name_index, Info[] classes) {
super(name_index, 2 + Info.length() * classes.length);
this.number_of_classes = classes.length;
this.classes = classes;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitInnerClasses(this, data);
}
public final int number_of_classes;
public final Info[] classes;
public static class Info {
Info(ClassReader cr) throws IOException {
inner_class_info_index = cr.readUnsignedShort();
outer_class_info_index = cr.readUnsignedShort();
inner_name_index = cr.readUnsignedShort();
inner_class_access_flags = new AccessFlags(cr.readUnsignedShort());
}
public CONSTANT_Class_info getInnerClassInfo(ConstantPool constant_pool) throws ConstantPoolException {
if (inner_class_info_index == 0)
return null;
return constant_pool.getClassInfo(inner_class_info_index);
}
public CONSTANT_Class_info getOuterClassInfo(ConstantPool constant_pool) throws ConstantPoolException {
if (outer_class_info_index == 0)
return null;
return constant_pool.getClassInfo(outer_class_info_index);
}
public String getInnerName(ConstantPool constant_pool) throws ConstantPoolException {
if (inner_name_index == 0)
return null;
return constant_pool.getUTF8Value(inner_name_index);
}
public static int length() {
return 8;
}
public final int inner_class_info_index;
public final int outer_class_info_index;
public final int inner_name_index;
public final AccessFlags inner_class_access_flags;
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.12.
*
* <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 LineNumberTable_attribute extends Attribute {
LineNumberTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
line_number_table_length = cr.readUnsignedShort();
line_number_table = new Entry[line_number_table_length];
for (int i = 0; i < line_number_table_length; i++)
line_number_table[i] = new Entry(cr);
}
public LineNumberTable_attribute(ConstantPool constant_pool, Entry[] line_number_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.LineNumberTable), line_number_table);
}
public LineNumberTable_attribute(int name_index, Entry[] line_number_table) {
super(name_index, line_number_table.length * Entry.length());
this.line_number_table_length = line_number_table.length;
this.line_number_table = line_number_table;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitLineNumberTable(this, data);
}
public final int line_number_table_length;
public final Entry[] line_number_table;
public static class Entry {
Entry(ClassReader cr) throws IOException {
start_pc = cr.readUnsignedShort();
line_number = cr.readUnsignedShort();
}
public static int length() {
return 4;
}
public final int start_pc;
public final int line_number;
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.13.
*
* <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 LocalVariableTable_attribute extends Attribute {
LocalVariableTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
local_variable_table_length = cr.readUnsignedShort();
local_variable_table = new Entry[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++)
local_variable_table[i] = new Entry(cr);
}
public LocalVariableTable_attribute(ConstantPool constant_pool, Entry[] local_variable_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.LocalVariableTable), local_variable_table);
}
public LocalVariableTable_attribute(int name_index, Entry[] local_variable_table) {
super(name_index, local_variable_table.length * Entry.length());
this.local_variable_table_length = local_variable_table.length;
this.local_variable_table = local_variable_table;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitLocalVariableTable(this, data);
}
public final int local_variable_table_length;
public final Entry[] local_variable_table;
public static class Entry {
Entry(ClassReader cr) throws IOException {
start_pc = cr.readUnsignedShort();
length = cr.readUnsignedShort();
name_index = cr.readUnsignedShort();
descriptor_index = cr.readUnsignedShort();
index = cr.readUnsignedShort();
}
public static int length() {
return 10;
}
public final int start_pc;
public final int length;
public final int name_index;
public final int descriptor_index;
public final int index;
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.14.
*
* <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 LocalVariableTypeTable_attribute extends Attribute {
LocalVariableTypeTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
local_variable_table_length = cr.readUnsignedShort();
local_variable_table = new Entry[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++)
local_variable_table[i] = new Entry(cr);
}
public LocalVariableTypeTable_attribute(ConstantPool constant_pool, Entry[] local_variable_table)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.LocalVariableTypeTable), local_variable_table);
}
public LocalVariableTypeTable_attribute(int name_index, Entry[] local_variable_table) {
super(name_index, local_variable_table.length * Entry.length());
this.local_variable_table_length = local_variable_table.length;
this.local_variable_table = local_variable_table;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitLocalVariableTypeTable(this, data);
}
public final int local_variable_table_length;
public final Entry[] local_variable_table;
public static class Entry {
Entry(ClassReader cr) throws IOException {
start_pc = cr.readUnsignedShort();
length = cr.readUnsignedShort();
name_index = cr.readUnsignedShort();
signature_index = cr.readUnsignedShort();
index = cr.readUnsignedShort();
}
public static int length() {
return 10;
}
public final int start_pc;
public final int length;
public final int name_index;
public final int signature_index;
public final int index;
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/*
* <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 Method {
Method(ClassReader cr) throws IOException {
access_flags = new AccessFlags(cr);
name_index = cr.readUnsignedShort();
descriptor = new Descriptor(cr);
attributes = new Attributes(cr);
}
public Method(AccessFlags access_flags,
int name_index, Descriptor descriptor,
Attributes attributes) {
this.access_flags = access_flags;
this.name_index = name_index;
this.descriptor = descriptor;
this.attributes = attributes;
}
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(name_index);
}
public final AccessFlags access_flags;
public final int name_index;
public final Descriptor descriptor;
public final Attributes attributes;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JSR 277.
*
* <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 ModuleExportTable_attribute extends Attribute {
ModuleExportTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
int export_type_length = cr.readUnsignedShort();
export_type_table = new int[export_type_length];
for (int i = 0; i < export_type_table.length; i++)
export_type_table[i] = cr.readUnsignedShort();
}
public ModuleExportTable_attribute(ConstantPool cp, int[] export_type_table)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.ModuleExportTable), export_type_table);
}
public ModuleExportTable_attribute(int name_index, int[] export_type_table) {
super(name_index, 2 * export_type_table.length);
this.export_type_table = export_type_table;
}
public int getExportTypeCount() {
return export_type_table.length;
}
public String getExportTypeName(int index, ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(export_type_table[index]);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitModuleExportTable(this, p);
}
public final int[] export_type_table;
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JSR 277.
*
* <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 ModuleMemberTable_attribute extends Attribute {
ModuleMemberTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
int package_member_length = cr.readUnsignedShort();
package_member_table = new int[package_member_length];
for (int i = 0; i < package_member_table.length; i++)
package_member_table[i] = cr.readUnsignedShort();
}
public ModuleMemberTable_attribute(ConstantPool cp, int[] package_member_table)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.ModuleMemberTable), package_member_table);
}
public ModuleMemberTable_attribute(int name_index, int[] package_member_table) {
super(name_index, 2 * package_member_table.length);
this.package_member_table = package_member_table;
}
public int getPackageMemberCount() {
return package_member_table.length;
}
public String getPackageMemberName(int index, ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(package_member_table[index]);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitModuleMemberTable(this, p);
}
public final int[] package_member_table;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JSR 277.
*
* <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 Module_attribute extends Attribute {
Module_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
module_name = cr.readUnsignedShort();
}
public Module_attribute(ConstantPool constant_pool, int module_name)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Module), module_name);
}
public Module_attribute(int name_index, int module_name) {
super(name_index, 2);
this.module_name = module_name;
}
public String getModuleName(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(module_name);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitModule(this, data);
}
public final int module_name;
}

View File

@ -0,0 +1,868 @@
/*
* Copyright 2007 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.classfile;
import java.util.HashMap;
/**
* See JVMS3, section 6.
*
* <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 OpCodes {
public static int opcLength(int opc) throws IllegalArgumentException {
switch (opc >> 8) {
case 0:
return opcLengthsTab[opc];
case opc_wide:
switch (opc & 0xFF) {
case opc_aload:
case opc_astore:
case opc_fload:
case opc_fstore:
case opc_iload:
case opc_istore:
case opc_lload:
case opc_lstore:
case opc_dload:
case opc_dstore:
case opc_ret:
return 4;
case opc_iinc:
return 6;
default:
throw new IllegalArgumentException();
}
case opc_nonpriv:
case opc_priv:
return 2;
default:
throw new IllegalArgumentException();
}
}
public static String opcName(int opc) {
try {
switch (opc >> 8) {
case 0:
return opcNamesTab[opc];
case opc_wide:
{
String mnem = opcNamesTab[opc & 0xFF] + "_w";
if (mnemocodes.get(mnem) == null) {
return null; // non-existent opcode
}
return mnem;
}
case opc_nonpriv:
return opcExtNamesTab[opc & 0xFF];
case opc_priv:
return opcPrivExtNamesTab[opc & 0xFF];
default:
return null;
}
} catch (ArrayIndexOutOfBoundsException e) {
switch (opc) {
case opc_nonpriv:
return "nonpriv";
case opc_priv:
return "priv";
default:
return null;
}
}
}
/* Opcodes */
public static final int opc_dead = -2;
public static final int opc_label = -1;
public static final int opc_nop = 0;
public static final int opc_aconst_null = 1;
public static final int opc_iconst_m1 = 2;
public static final int opc_iconst_0 = 3;
public static final int opc_iconst_1 = 4;
public static final int opc_iconst_2 = 5;
public static final int opc_iconst_3 = 6;
public static final int opc_iconst_4 = 7;
public static final int opc_iconst_5 = 8;
public static final int opc_lconst_0 = 9;
public static final int opc_lconst_1 = 10;
public static final int opc_fconst_0 = 11;
public static final int opc_fconst_1 = 12;
public static final int opc_fconst_2 = 13;
public static final int opc_dconst_0 = 14;
public static final int opc_dconst_1 = 15;
public static final int opc_bipush = 16;
public static final int opc_sipush = 17;
public static final int opc_ldc = 18;
public static final int opc_ldc_w = 19;
public static final int opc_ldc2_w = 20;
public static final int opc_iload = 21;
public static final int opc_lload = 22;
public static final int opc_fload = 23;
public static final int opc_dload = 24;
public static final int opc_aload = 25;
public static final int opc_iload_0 = 26;
public static final int opc_iload_1 = 27;
public static final int opc_iload_2 = 28;
public static final int opc_iload_3 = 29;
public static final int opc_lload_0 = 30;
public static final int opc_lload_1 = 31;
public static final int opc_lload_2 = 32;
public static final int opc_lload_3 = 33;
public static final int opc_fload_0 = 34;
public static final int opc_fload_1 = 35;
public static final int opc_fload_2 = 36;
public static final int opc_fload_3 = 37;
public static final int opc_dload_0 = 38;
public static final int opc_dload_1 = 39;
public static final int opc_dload_2 = 40;
public static final int opc_dload_3 = 41;
public static final int opc_aload_0 = 42;
public static final int opc_aload_1 = 43;
public static final int opc_aload_2 = 44;
public static final int opc_aload_3 = 45;
public static final int opc_iaload = 46;
public static final int opc_laload = 47;
public static final int opc_faload = 48;
public static final int opc_daload = 49;
public static final int opc_aaload = 50;
public static final int opc_baload = 51;
public static final int opc_caload = 52;
public static final int opc_saload = 53;
public static final int opc_istore = 54;
public static final int opc_lstore = 55;
public static final int opc_fstore = 56;
public static final int opc_dstore = 57;
public static final int opc_astore = 58;
public static final int opc_istore_0 = 59;
public static final int opc_istore_1 = 60;
public static final int opc_istore_2 = 61;
public static final int opc_istore_3 = 62;
public static final int opc_lstore_0 = 63;
public static final int opc_lstore_1 = 64;
public static final int opc_lstore_2 = 65;
public static final int opc_lstore_3 = 66;
public static final int opc_fstore_0 = 67;
public static final int opc_fstore_1 = 68;
public static final int opc_fstore_2 = 69;
public static final int opc_fstore_3 = 70;
public static final int opc_dstore_0 = 71;
public static final int opc_dstore_1 = 72;
public static final int opc_dstore_2 = 73;
public static final int opc_dstore_3 = 74;
public static final int opc_astore_0 = 75;
public static final int opc_astore_1 = 76;
public static final int opc_astore_2 = 77;
public static final int opc_astore_3 = 78;
public static final int opc_iastore = 79;
public static final int opc_lastore = 80;
public static final int opc_fastore = 81;
public static final int opc_dastore = 82;
public static final int opc_aastore = 83;
public static final int opc_bastore = 84;
public static final int opc_castore = 85;
public static final int opc_sastore = 86;
public static final int opc_pop = 87;
public static final int opc_pop2 = 88;
public static final int opc_dup = 89;
public static final int opc_dup_x1 = 90;
public static final int opc_dup_x2 = 91;
public static final int opc_dup2 = 92;
public static final int opc_dup2_x1 = 93;
public static final int opc_dup2_x2 = 94;
public static final int opc_swap = 95;
public static final int opc_iadd = 96;
public static final int opc_ladd = 97;
public static final int opc_fadd = 98;
public static final int opc_dadd = 99;
public static final int opc_isub = 100;
public static final int opc_lsub = 101;
public static final int opc_fsub = 102;
public static final int opc_dsub = 103;
public static final int opc_imul = 104;
public static final int opc_lmul = 105;
public static final int opc_fmul = 106;
public static final int opc_dmul = 107;
public static final int opc_idiv = 108;
public static final int opc_ldiv = 109;
public static final int opc_fdiv = 110;
public static final int opc_ddiv = 111;
public static final int opc_irem = 112;
public static final int opc_lrem = 113;
public static final int opc_frem = 114;
public static final int opc_drem = 115;
public static final int opc_ineg = 116;
public static final int opc_lneg = 117;
public static final int opc_fneg = 118;
public static final int opc_dneg = 119;
public static final int opc_ishl = 120;
public static final int opc_lshl = 121;
public static final int opc_ishr = 122;
public static final int opc_lshr = 123;
public static final int opc_iushr = 124;
public static final int opc_lushr = 125;
public static final int opc_iand = 126;
public static final int opc_land = 127;
public static final int opc_ior = 128;
public static final int opc_lor = 129;
public static final int opc_ixor = 130;
public static final int opc_lxor = 131;
public static final int opc_iinc = 132;
public static final int opc_i2l = 133;
public static final int opc_i2f = 134;
public static final int opc_i2d = 135;
public static final int opc_l2i = 136;
public static final int opc_l2f = 137;
public static final int opc_l2d = 138;
public static final int opc_f2i = 139;
public static final int opc_f2l = 140;
public static final int opc_f2d = 141;
public static final int opc_d2i = 142;
public static final int opc_d2l = 143;
public static final int opc_d2f = 144;
public static final int opc_i2b = 145;
public static final int opc_int2byte = 145;
public static final int opc_i2c = 146;
public static final int opc_int2char = 146;
public static final int opc_i2s = 147;
public static final int opc_int2short = 147;
public static final int opc_lcmp = 148;
public static final int opc_fcmpl = 149;
public static final int opc_fcmpg = 150;
public static final int opc_dcmpl = 151;
public static final int opc_dcmpg = 152;
public static final int opc_ifeq = 153;
public static final int opc_ifne = 154;
public static final int opc_iflt = 155;
public static final int opc_ifge = 156;
public static final int opc_ifgt = 157;
public static final int opc_ifle = 158;
public static final int opc_if_icmpeq = 159;
public static final int opc_if_icmpne = 160;
public static final int opc_if_icmplt = 161;
public static final int opc_if_icmpge = 162;
public static final int opc_if_icmpgt = 163;
public static final int opc_if_icmple = 164;
public static final int opc_if_acmpeq = 165;
public static final int opc_if_acmpne = 166;
public static final int opc_goto = 167;
public static final int opc_jsr = 168;
public static final int opc_ret = 169;
public static final int opc_tableswitch = 170;
public static final int opc_lookupswitch = 171;
public static final int opc_ireturn = 172;
public static final int opc_lreturn = 173;
public static final int opc_freturn = 174;
public static final int opc_dreturn = 175;
public static final int opc_areturn = 176;
public static final int opc_return = 177;
public static final int opc_getstatic = 178;
public static final int opc_putstatic = 179;
public static final int opc_getfield = 180;
public static final int opc_putfield = 181;
public static final int opc_invokevirtual = 182;
public static final int opc_invokenonvirtual = 183;
public static final int opc_invokespecial = 183;
public static final int opc_invokestatic = 184;
public static final int opc_invokeinterface = 185;
// public static final int opc_xxxunusedxxx = 186;
public static final int opc_new = 187;
public static final int opc_newarray = 188;
public static final int opc_anewarray = 189;
public static final int opc_arraylength = 190;
public static final int opc_athrow = 191;
public static final int opc_checkcast = 192;
public static final int opc_instanceof = 193;
public static final int opc_monitorenter = 194;
public static final int opc_monitorexit = 195;
public static final int opc_wide = 196;
public static final int opc_multianewarray = 197;
public static final int opc_ifnull = 198;
public static final int opc_ifnonnull = 199;
public static final int opc_goto_w = 200;
public static final int opc_jsr_w = 201;
/* Pseudo-instructions */
public static final int opc_bytecode = 203;
public static final int opc_try = 204;
public static final int opc_endtry = 205;
public static final int opc_catch = 206;
public static final int opc_var = 207;
public static final int opc_endvar = 208;
public static final int opc_localsmap = 209;
public static final int opc_stackmap = 210;
/* PicoJava prefixes */
public static final int opc_nonpriv = 254;
public static final int opc_priv = 255;
/* Wide instructions */
public static final int opc_iload_w = (opc_wide << 8 ) | opc_iload;
public static final int opc_lload_w = (opc_wide << 8 ) | opc_lload;
public static final int opc_fload_w = (opc_wide << 8 ) | opc_fload;
public static final int opc_dload_w = (opc_wide << 8 ) | opc_dload;
public static final int opc_aload_w = (opc_wide << 8 ) | opc_aload;
public static final int opc_istore_w = (opc_wide << 8 ) | opc_istore;
public static final int opc_lstore_w = (opc_wide << 8 ) | opc_lstore;
public static final int opc_fstore_w = (opc_wide << 8 ) | opc_fstore;
public static final int opc_dstore_w = (opc_wide << 8 ) | opc_dstore;
public static final int opc_astore_w = (opc_wide << 8 ) | opc_astore;
public static final int opc_ret_w = (opc_wide << 8 ) | opc_ret;
public static final int opc_iinc_w = (opc_wide << 8 ) | opc_iinc;
/* Opcode Names */
private static final String opcNamesTab[] = {
"nop",
"aconst_null",
"iconst_m1",
"iconst_0",
"iconst_1",
"iconst_2",
"iconst_3",
"iconst_4",
"iconst_5",
"lconst_0",
"lconst_1",
"fconst_0",
"fconst_1",
"fconst_2",
"dconst_0",
"dconst_1",
"bipush",
"sipush",
"ldc",
"ldc_w",
"ldc2_w",
"iload",
"lload",
"fload",
"dload",
"aload",
"iload_0",
"iload_1",
"iload_2",
"iload_3",
"lload_0",
"lload_1",
"lload_2",
"lload_3",
"fload_0",
"fload_1",
"fload_2",
"fload_3",
"dload_0",
"dload_1",
"dload_2",
"dload_3",
"aload_0",
"aload_1",
"aload_2",
"aload_3",
"iaload",
"laload",
"faload",
"daload",
"aaload",
"baload",
"caload",
"saload",
"istore",
"lstore",
"fstore",
"dstore",
"astore",
"istore_0",
"istore_1",
"istore_2",
"istore_3",
"lstore_0",
"lstore_1",
"lstore_2",
"lstore_3",
"fstore_0",
"fstore_1",
"fstore_2",
"fstore_3",
"dstore_0",
"dstore_1",
"dstore_2",
"dstore_3",
"astore_0",
"astore_1",
"astore_2",
"astore_3",
"iastore",
"lastore",
"fastore",
"dastore",
"aastore",
"bastore",
"castore",
"sastore",
"pop",
"pop2",
"dup",
"dup_x1",
"dup_x2",
"dup2",
"dup2_x1",
"dup2_x2",
"swap",
"iadd",
"ladd",
"fadd",
"dadd",
"isub",
"lsub",
"fsub",
"dsub",
"imul",
"lmul",
"fmul",
"dmul",
"idiv",
"ldiv",
"fdiv",
"ddiv",
"irem",
"lrem",
"frem",
"drem",
"ineg",
"lneg",
"fneg",
"dneg",
"ishl",
"lshl",
"ishr",
"lshr",
"iushr",
"lushr",
"iand",
"land",
"ior",
"lor",
"ixor",
"lxor",
"iinc",
"i2l",
"i2f",
"i2d",
"l2i",
"l2f",
"l2d",
"f2i",
"f2l",
"f2d",
"d2i",
"d2l",
"d2f",
"i2b",
"i2c",
"i2s",
"lcmp",
"fcmpl",
"fcmpg",
"dcmpl",
"dcmpg",
"ifeq",
"ifne",
"iflt",
"ifge",
"ifgt",
"ifle",
"if_icmpeq",
"if_icmpne",
"if_icmplt",
"if_icmpge",
"if_icmpgt",
"if_icmple",
"if_acmpeq",
"if_acmpne",
"goto",
"jsr",
"ret",
"tableswitch",
"lookupswitch",
"ireturn",
"lreturn",
"freturn",
"dreturn",
"areturn",
"return",
"getstatic",
"putstatic",
"getfield",
"putfield",
"invokevirtual",
"invokespecial", // was "invokenonvirtual",
"invokestatic",
"invokeinterface",
"bytecode 186", //"xxxunusedxxx",
"new",
"newarray",
"anewarray",
"arraylength",
"athrow",
"checkcast",
"instanceof",
"monitorenter",
"monitorexit",
null, // "wide",
"multianewarray",
"ifnull",
"ifnonnull",
"goto_w",
"jsr_w",
"bytecode 202", // "breakpoint",
"bytecode",
"try",
"endtry",
"catch",
"var",
"endvar",
"locals_map",
"stack_map"
};
/* Opcode Lengths */
private static final int opcLengthsTab[] = {
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
3,
2,
3,
3,
2,
2,
2,
2,
2,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
2,
2,
2,
2,
2,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
3,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
2,
99,
99,
1,
1,
1,
1,
1,
1,
3,
3,
3,
3,
3,
3,
3,
5,
0,
3,
2,
3,
1,
1,
3,
3,
1,
1,
0, // wide
4,
3,
3,
5,
5,
1,
1, 0, 0, 0, 0, 0 // pseudo
};
/* Type codes, used in newarray opcode */
public static final int T_CLASS = 0x00000002;
public static final int T_BOOLEAN = 0x00000004;
public static final int T_CHAR = 0x00000005;
public static final int T_FLOAT = 0x00000006;
public static final int T_DOUBLE = 0x00000007;
public static final int T_BYTE = 0x00000008;
public static final int T_SHORT = 0x00000009;
public static final int T_INT = 0x0000000a;
public static final int T_LONG = 0x0000000b;
private static HashMap<String,Integer> mnemocodes = new HashMap<String,Integer>(301, 0.5f);
private static String opcExtNamesTab[]=new String[128];
private static String opcPrivExtNamesTab[]=new String[128];
private static void defineNonPriv(int opc, String mnem) {
mnemocodes.put(opcExtNamesTab[opc] = mnem, opc_nonpriv * 256 + opc);
}
private static void definePriv(int opc, String mnem) {
mnemocodes.put(opcPrivExtNamesTab[opc] = "priv_" + mnem, opc_priv * 256 + opc);
}
private static void defineExt(int opc, String mnem) {
defineNonPriv(opc, mnem);
definePriv(opc, mnem);
}
static {
for (int i = 0; i < opc_wide; i++) {
mnemocodes.put(opcNamesTab[i], i);
}
for (int i = opc_wide + 1; i < opcNamesTab.length; i++) {
mnemocodes.put(opcNamesTab[i], i);
}
mnemocodes.put("invokenonvirtual", opc_invokespecial);
mnemocodes.put("iload_w", opc_iload_w);
mnemocodes.put("lload_w", opc_lload_w);
mnemocodes.put("fload_w", opc_fload_w);
mnemocodes.put("dload_w", opc_dload_w);
mnemocodes.put("aload_w", opc_aload_w);
mnemocodes.put("istore_w", opc_istore_w);
mnemocodes.put("lstore_w", opc_lstore_w);
mnemocodes.put("fstore_w", opc_fstore_w);
mnemocodes.put("dstore_w", opc_dstore_w);
mnemocodes.put("astore_w", opc_astore_w);
mnemocodes.put("ret_w", opc_ret_w);
mnemocodes.put("iinc_w", opc_iinc_w);
mnemocodes.put("nonpriv", opc_nonpriv);
mnemocodes.put("priv", opc_priv);
defineExt(0, "load_ubyte");
defineExt(1, "load_byte");
defineExt(2, "load_char");
defineExt(3, "load_short");
defineExt(4, "load_word");
defineExt(10, "load_char_oe");
defineExt(11, "load_short_oe");
defineExt(12, "load_word_oe");
defineExt(16, "ncload_ubyte");
defineExt(17, "ncload_byte");
defineExt(18, "ncload_char");
defineExt(19, "ncload_short");
defineExt(20, "ncload_word");
defineExt(26, "ncload_char_oe");
defineExt(27, "ncload_short_oe");
defineExt(28, "ncload_word_oe");
defineExt(30, "cache_flush");
defineExt(32, "store_byte");
defineExt(34, "store_short");
defineExt(36, "store_word");
defineExt(42, "store_short_oe");
defineExt(44, "store_word_oe");
defineExt(48, "ncstore_byte");
defineExt(50, "ncstore_short");
defineExt(52, "ncstore_word");
defineExt(58, "ncstore_short_oe");
defineExt(60, "ncstore_word_oe");
defineExt(62, "zero_line");
defineNonPriv(5, "ret_from_sub");
defineNonPriv(63, "enter_sync_method");
definePriv(5, "ret_from_trap");
definePriv(6, "read_dcache_tag");
definePriv(7, "read_dcache_data");
definePriv(14, "read_icache_tag");
definePriv(15, "read_icache_data");
definePriv(22, "powerdown");
definePriv(23, "read_scache_data");
definePriv(31, "cache_index_flush");
definePriv(38, "write_dcache_tag");
definePriv(39, "write_dcache_data");
definePriv(46, "write_icache_tag");
definePriv(47, "write_icache_data");
definePriv(54, "reset");
definePriv(55, "write_scache_data");
for (int i = 0; i < 32; i++) {
definePriv(i + 64, "read_reg_" + i);
}
for (int i = 0; i < 32; i++) {
definePriv(i + 96, "write_reg_" + i);
}
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.16 and 4.8.17.
*
* <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 abstract class RuntimeAnnotations_attribute extends Attribute {
protected RuntimeAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(name_index, length);
int num_annotations = cr.readUnsignedShort();
annotations = new Annotation[num_annotations];
for (int i = 0; i < annotations.length; i++)
annotations[i] = new Annotation(cr);
}
protected RuntimeAnnotations_attribute(int name_index, Annotation[] annotations) {
super(name_index, length(annotations));
this.annotations = annotations;
}
private static int length(Annotation[] annos) {
int n = 2;
for (Annotation anno: annos)
n += anno.length();
return n;
}
public final Annotation[] annotations;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.17.
*
* <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 RuntimeInvisibleAnnotations_attribute extends RuntimeAnnotations_attribute {
RuntimeInvisibleAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, AttributeException {
super(cr, name_index, length);
}
public RuntimeInvisibleAnnotations_attribute(ConstantPool cp, Annotation[] annotations)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.RuntimeInvisibleAnnotations), annotations);
}
public RuntimeInvisibleAnnotations_attribute(int name_index, Annotation[] annotations) {
super(name_index, annotations);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitRuntimeInvisibleAnnotations(this, p);
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.18.
*
* <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 RuntimeInvisibleParameterAnnotations_attribute extends RuntimeParameterAnnotations_attribute {
RuntimeInvisibleParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(cr, name_index, length);
}
public RuntimeInvisibleParameterAnnotations_attribute(ConstantPool cp, Annotation[][] parameter_annotations)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.RuntimeInvisibleParameterAnnotations), parameter_annotations);
}
public RuntimeInvisibleParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
super(name_index, parameter_annotations);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitRuntimeInvisibleParameterAnnotations(this, p);
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.18 and 4.8.19.
*
* <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 abstract class RuntimeParameterAnnotations_attribute extends Attribute {
RuntimeParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(name_index, length);
int num_parameters = cr.readUnsignedByte();
parameter_annotations = new Annotation[num_parameters][];
for (int p = 0; p < parameter_annotations.length; p++) {
int num_annotations = cr.readUnsignedShort();
Annotation[] annotations = new Annotation[num_annotations];
for (int i = 0; i < num_annotations; i++)
annotations[i] = new Annotation(cr);
parameter_annotations[p] = annotations;
}
}
protected RuntimeParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
super(name_index, length(parameter_annotations));
this.parameter_annotations = parameter_annotations;
}
private static int length(Annotation[][] anno_arrays) {
int n = 1;
for (Annotation[] anno_array: anno_arrays) {
n += 2;
for (Annotation anno: anno_array)
n += anno.length();
}
return n;
}
public final Annotation[][] parameter_annotations;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.16.
*
* <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 RuntimeVisibleAnnotations_attribute extends RuntimeAnnotations_attribute {
RuntimeVisibleAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(cr, name_index, length);
}
public RuntimeVisibleAnnotations_attribute(ConstantPool cp, Annotation[] annotations)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.RuntimeVisibleAnnotations), annotations);
}
public RuntimeVisibleAnnotations_attribute(int name_index, Annotation[] annotations) {
super(name_index, annotations);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitRuntimeVisibleAnnotations(this, p);
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.18.
*
* <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 RuntimeVisibleParameterAnnotations_attribute extends RuntimeParameterAnnotations_attribute {
RuntimeVisibleParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
throws IOException, Annotation.InvalidAnnotation {
super(cr, name_index, length);
}
public RuntimeVisibleParameterAnnotations_attribute(ConstantPool cp, Annotation[][] parameter_annotations)
throws ConstantPoolException {
this(cp.getUTF8Index(Attribute.RuntimeVisibleParameterAnnotations), parameter_annotations);
}
public RuntimeVisibleParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
super(name_index, parameter_annotations);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitRuntimeVisibleParameterAnnotations(this, p);
}
}

View File

@ -0,0 +1,275 @@
/*
* Copyright 2007 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.classfile;
import java.util.ArrayList;
import java.util.List;
/**
* See JVMS3 4.4.4.
*
* <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 Signature extends Descriptor {
public Signature(int index) {
super(index);
}
public Type getType(ConstantPool constant_pool) throws ConstantPoolException {
if (type == null)
type = parse(getValue(constant_pool));
return type;
}
@Override
public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException {
Type.MethodType m = (Type.MethodType) getType(constant_pool);
return m.argTypes.size();
}
@Override
public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException {
Type.MethodType m = (Type.MethodType) getType(constant_pool);
StringBuilder sb = new StringBuilder();
sb.append("(");
String sep = "";
for (Type argType: m.argTypes) {
sb.append(sep);
sb.append(argType);
sep = ", ";
}
sb.append(")");
return sb.toString();
}
@Override
public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException {
Type.MethodType m = (Type.MethodType) getType(constant_pool);
return m.returnType.toString();
}
@Override
public String getFieldType(ConstantPool constant_pool) throws ConstantPoolException {
return getType(constant_pool).toString();
}
private Type parse(String sig) {
this.sig = sig;
sigp = 0;
List<Type> typeArgTypes = null;
if (sig.charAt(sigp) == '<')
typeArgTypes = parseTypeArgTypes();
if (sig.charAt(sigp) == '(') {
List<Type> argTypes = parseTypeSignatures(')');
Type returnType = parseTypeSignature();
List<Type> throwsTypes = null;
while (sigp < sig.length() && sig.charAt(sigp) == '^') {
sigp++;
if (throwsTypes == null)
throwsTypes = new ArrayList<Type>();
throwsTypes.add(parseTypeSignature());
}
return new Type.MethodType(typeArgTypes, argTypes, returnType, throwsTypes);
} else {
Type t = parseTypeSignature();
if (typeArgTypes == null && sigp == sig.length())
return t;
Type superclass = t;
List<Type> superinterfaces = new ArrayList<Type>();
while (sigp < sig.length())
superinterfaces.add(parseTypeSignature());
return new Type.ClassSigType(typeArgTypes, superclass, superinterfaces);
}
}
private Type parseTypeSignature() {
switch (sig.charAt(sigp)) {
case 'B':
sigp++;
return new Type.SimpleType("byte");
case 'C':
sigp++;
return new Type.SimpleType("char");
case 'D':
sigp++;
return new Type.SimpleType("double");
case 'F':
sigp++;
return new Type.SimpleType("float");
case 'I':
sigp++;
return new Type.SimpleType("int");
case 'J':
sigp++;
return new Type.SimpleType("long");
case 'L':
return parseClassTypeSignature();
case 'S':
sigp++;
return new Type.SimpleType("short");
case 'T':
return parseTypeVariableSignature();
case 'V':
sigp++;
return new Type.SimpleType("void");
case 'Z':
sigp++;
return new Type.SimpleType("boolean");
case '[':
sigp++;
return new Type.ArrayType(parseTypeSignature());
case '*':
sigp++;
return new Type.WildcardType();
case '+':
sigp++;
return new Type.WildcardType("extends", parseTypeSignature());
case '-':
sigp++;
return new Type.WildcardType("super", parseTypeSignature());
default:
throw new IllegalStateException(debugInfo());
}
}
private List<Type> parseTypeSignatures(char term) {
sigp++;
List<Type> types = new ArrayList<Type>();
while (sig.charAt(sigp) != term)
types.add(parseTypeSignature());
sigp++;
return types;
}
private Type parseClassTypeSignature() {
assert sig.charAt(sigp) == 'L';
sigp++;
return parseClassTypeSignatureRest();
}
private Type parseClassTypeSignatureRest() {
StringBuilder sb = new StringBuilder();
Type t = null;
char sigch;
while (true) {
switch (sigch = sig.charAt(sigp)) {
case '/':
sigp++;
sb.append(".");
break;
case '.':
sigp++;
if (t == null)
t = new Type.SimpleType(sb.toString());
return new Type.InnerClassType(t, parseClassTypeSignatureRest());
case ';':
sigp++;
if (t == null)
t = new Type.SimpleType(sb.toString());
return t;
case '<':
List<Type> argTypes = parseTypeSignatures('>');
t = new Type.ClassType(sb.toString(), argTypes);
break;
default:
sigp++;
sb.append(sigch);
break;
}
}
}
private List<Type> parseTypeArgTypes() {
assert sig.charAt(sigp) == '<';
sigp++;
List<Type> types = null;
types = new ArrayList<Type>();
while (sig.charAt(sigp) != '>')
types.add(parseTypeArgType());
sigp++;
return types;
}
private Type parseTypeArgType() {
int sep = sig.indexOf(":", sigp);
String name = sig.substring(sigp, sep);
Type classBound = null;
List<Type> interfaceBounds = null;
sigp = sep + 1;
if (sig.charAt(sigp) != ':')
classBound = parseTypeSignature();
while (sig.charAt(sigp) == ':') {
sigp++;
if (interfaceBounds == null)
interfaceBounds = new ArrayList<Type>();
interfaceBounds.add(parseTypeSignature());
}
return new Type.TypeArgType(name, classBound, interfaceBounds);
}
private Type parseTypeVariableSignature() {
sigp++;
int sep = sig.indexOf(';', sigp);
Type t = new Type.SimpleType(sig.substring(sigp, sep));
sigp = sep + 1;
return t;
}
private String debugInfo() {
return sig.substring(0, sigp) + "!" + sig.charAt(sigp) + "!" + sig.substring(sigp+1);
}
private String sig;
private int sigp;
private Type type;
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.9.
*
* <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 Signature_attribute extends Attribute {
Signature_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
signature_index = cr.readUnsignedShort();
}
public Signature_attribute(ConstantPool constant_pool, int signature_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Signature), signature_index);
}
public Signature_attribute(int name_index, int signature_index) {
super(name_index, 2);
this.signature_index = signature_index;
}
public String getSignature(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(signature_index);
}
public Signature getParsedSignature() {
return new Signature(signature_index);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitSignature(this, data);
}
public final int signature_index;
}

View File

@ -0,0 +1,71 @@
/*
* Copyright 2007 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.classfile;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
/**
* See JVMS3, section 4.8.15.
*
* <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 SourceDebugExtension_attribute extends Attribute {
SourceDebugExtension_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
debug_extension = new byte[attribute_length];
cr.readFully(debug_extension);
}
public SourceDebugExtension_attribute(ConstantPool constant_pool, byte[] debug_extension)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.SourceDebugExtension), debug_extension);
}
public SourceDebugExtension_attribute(int name_index, byte[] debug_extension) {
super(name_index, debug_extension.length);
this.debug_extension = debug_extension;
}
public String getValue() {
DataInputStream d = new DataInputStream(new ByteArrayInputStream(debug_extension));
try {
return d.readUTF();
} catch (IOException e) {
return null;
}
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitSourceDebugExtension(this, data);
}
public final byte[] debug_extension;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.10.
*
* <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 SourceFile_attribute extends Attribute {
SourceFile_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
sourcefile_index = cr.readUnsignedShort();
}
public SourceFile_attribute(ConstantPool constant_pool, int sourcefile_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.SourceFile), sourcefile_index);
}
public SourceFile_attribute(int name_index, int sourcefile_index) {
super(name_index, 2);
this.sourcefile_index = sourcefile_index;
}
public String getSourceFile(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(sourcefile_index);
}
public <R, P> R accept(Visitor<R, P> visitor, P p) {
return visitor.visitSourceFile(this, p);
}
public final int sourcefile_index;
}

View File

@ -0,0 +1,61 @@
/*
* 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. 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.classfile;
import java.io.IOException;
/**
* <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 SourceID_attribute extends Attribute {
SourceID_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
sourceID_index = cr.readUnsignedShort();
}
public SourceID_attribute(ConstantPool constant_pool, int sourceID_index)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.SourceID), sourceID_index);
}
public SourceID_attribute(int name_index, int sourceID_index) {
super(name_index, 2);
this.sourceID_index = sourceID_index;
}
String getSourceID(ConstantPool constant_pool) throws ConstantPoolException {
return constant_pool.getUTF8Value(sourceID_index);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitSourceID(this, data);
}
public final int sourceID_index;
}

View File

@ -0,0 +1,349 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.4.
*
* <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 StackMapTable_attribute extends Attribute {
static class InvalidStackMap extends AttributeException {
InvalidStackMap(String msg) {
super(msg);
}
}
StackMapTable_attribute(ClassReader cr, int name_index, int length)
throws IOException, InvalidStackMap {
super(name_index, length);
number_of_entries = cr.readUnsignedShort();
entries = new stack_map_frame[number_of_entries];
for (int i = 0; i < number_of_entries; i++)
entries[i] = stack_map_frame.read(cr);
}
public StackMapTable_attribute(ConstantPool constant_pool, stack_map_frame[] entries)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.StackMapTable), entries);
}
public StackMapTable_attribute(int name_index, stack_map_frame[] entries) {
super(name_index, length(entries));
this.number_of_entries = entries.length;
this.entries = entries;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitStackMapTable(this, data);
}
static int length(stack_map_frame[] entries) {
int n = 2;
for (stack_map_frame entry: entries)
n += entry.length();
return n;
}
public final int number_of_entries;
public final stack_map_frame entries[];
public static abstract class stack_map_frame {
static stack_map_frame read(ClassReader cr)
throws IOException, InvalidStackMap {
int frame_type = cr.readUnsignedByte();
if (frame_type <= 63)
return new same_frame(frame_type);
else if (frame_type <= 127)
return new same_locals_1_stack_item_frame(frame_type, cr);
else if (frame_type <= 246)
throw new Error("unknown frame_type " + frame_type);
else if (frame_type == 247)
return new same_locals_1_stack_item_frame_extended(frame_type, cr);
else if (frame_type <= 250)
return new chop_frame(frame_type, cr);
else if (frame_type == 251)
return new same_frame_extended(frame_type, cr);
else if (frame_type <= 254)
return new append_frame(frame_type, cr);
else
return new full_frame(frame_type, cr);
}
protected stack_map_frame(int frame_type) {
this.frame_type = frame_type;
}
public int length() {
return 1;
}
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
public final int frame_type;
public static interface Visitor<R,P> {
R visit_same_frame(same_frame frame, P p);
R visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, P p);
R visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, P p);
R visit_chop_frame(chop_frame frame, P p);
R visit_same_frame_extended(same_frame_extended frame, P p);
R visit_append_frame(append_frame frame, P p);
R visit_full_frame(full_frame frame, P p);
}
}
public static class same_frame extends stack_map_frame {
same_frame(int frame_type) {
super(frame_type);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_same_frame(this, data);
}
}
public static class same_locals_1_stack_item_frame extends stack_map_frame {
same_locals_1_stack_item_frame(int frame_type, ClassReader cr)
throws IOException, InvalidStackMap {
super(frame_type);
stack = new verification_type_info[1];
stack[0] = verification_type_info.read(cr);
}
@Override
public int length() {
return super.length() + stack[0].length();
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_same_locals_1_stack_item_frame(this, data);
}
public final verification_type_info[] stack;
}
public static class same_locals_1_stack_item_frame_extended extends stack_map_frame {
same_locals_1_stack_item_frame_extended(int frame_type, ClassReader cr)
throws IOException, InvalidStackMap {
super(frame_type);
offset_delta = cr.readUnsignedShort();
stack = new verification_type_info[1];
stack[0] = verification_type_info.read(cr);
}
@Override
public int length() {
return super.length() + 2 + stack[0].length();
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_same_locals_1_stack_item_frame_extended(this, data);
}
public final int offset_delta;
public final verification_type_info[] stack;
}
public static class chop_frame extends stack_map_frame {
chop_frame(int frame_type, ClassReader cr) throws IOException {
super(frame_type);
offset_delta = cr.readUnsignedShort();
}
@Override
public int length() {
return super.length() + 2;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_chop_frame(this, data);
}
public final int offset_delta;
}
public static class same_frame_extended extends stack_map_frame {
same_frame_extended(int frame_type, ClassReader cr) throws IOException {
super(frame_type);
offset_delta = cr.readUnsignedShort();
}
@Override
public int length() {
return super.length() + 2;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_same_frame_extended(this, data);
}
public final int offset_delta;
}
public static class append_frame extends stack_map_frame {
append_frame(int frame_type, ClassReader cr)
throws IOException, InvalidStackMap {
super(frame_type);
offset_delta = cr.readUnsignedShort();
locals = new verification_type_info[frame_type - 251];
for (int i = 0; i < locals.length; i++)
locals[i] = verification_type_info.read(cr);
}
@Override
public int length() {
int n = super.length() + 2;
for (verification_type_info local: locals)
n += local.length();
return n;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_append_frame(this, data);
}
public final int offset_delta;
public final verification_type_info[] locals;
}
public static class full_frame extends stack_map_frame {
full_frame(int frame_type, ClassReader cr)
throws IOException, InvalidStackMap {
super(frame_type);
offset_delta = cr.readUnsignedShort();
number_of_locals = cr.readUnsignedShort();
locals = new verification_type_info[number_of_locals];
for (int i = 0; i < locals.length; i++)
locals[i] = verification_type_info.read(cr);
number_of_stack_items = cr.readUnsignedShort();
stack = new verification_type_info[number_of_stack_items];
for (int i = 0; i < stack.length; i++)
stack[i] = verification_type_info.read(cr);
}
@Override
public int length() {
int n = super.length() + 2;
for (verification_type_info local: locals)
n += local.length();
n += 2;
for (verification_type_info item: stack)
n += item.length();
return n;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visit_full_frame(this, data);
}
public final int offset_delta;
public final int number_of_locals;
public final verification_type_info[] locals;
public final int number_of_stack_items;
public final verification_type_info[] stack;
}
public static class verification_type_info {
public static final int ITEM_Top = 0;
public static final int ITEM_Integer = 1;
public static final int ITEM_Float = 2;
public static final int ITEM_Long = 4;
public static final int ITEM_Double = 3;
public static final int ITEM_Null = 5;
public static final int ITEM_UninitializedThis = 6;
public static final int ITEM_Object = 7;
public static final int ITEM_Uninitialized = 8;
static verification_type_info read(ClassReader cr)
throws IOException, InvalidStackMap {
int tag = cr.readUnsignedByte();
switch (tag) {
case ITEM_Top:
case ITEM_Integer:
case ITEM_Float:
case ITEM_Long:
case ITEM_Double:
case ITEM_Null:
case ITEM_UninitializedThis:
return new verification_type_info(tag);
case ITEM_Object:
return new Object_variable_info(cr);
case ITEM_Uninitialized:
return new Uninitialized_variable_info(cr);
default:
throw new InvalidStackMap("unrecognized verification_type_info tag");
}
}
verification_type_info(int tag) {
this.tag = tag;
}
public int length() {
return 1;
}
public final int tag;
}
public static class Object_variable_info extends verification_type_info {
Object_variable_info(ClassReader cr) throws IOException {
super(ITEM_Object);
cpool_index = cr.readUnsignedShort();
}
@Override
public int length() {
return super.length() + 2;
}
public final int cpool_index;
}
public static class Uninitialized_variable_info extends verification_type_info {
Uninitialized_variable_info(ClassReader cr) throws IOException {
super(ITEM_Uninitialized);
offset = cr.readUnsignedShort();
}
@Override
public int length() {
return super.length() + 2;
}
public final int offset;
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* <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 StackMap_attribute extends Attribute {
StackMap_attribute(ClassReader cr, int name_index, int length)
throws IOException, StackMapTable_attribute.InvalidStackMap {
super(name_index, length);
number_of_entries = cr.readUnsignedShort();
entries = new stack_map_frame[number_of_entries];
for (int i = 0; i < number_of_entries; i++)
entries[i] = new stack_map_frame(cr);
}
public StackMap_attribute(ConstantPool constant_pool, stack_map_frame[] entries)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.StackMap), entries);
}
public StackMap_attribute(int name_index, stack_map_frame[] entries) {
super(name_index, StackMapTable_attribute.length(entries));
this.number_of_entries = entries.length;
this.entries = entries;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitStackMap(this, data);
}
public final int number_of_entries;
public final stack_map_frame entries[];
public static class stack_map_frame extends StackMapTable_attribute.full_frame {
stack_map_frame(ClassReader cr)
throws IOException, StackMapTable_attribute.InvalidStackMap {
super(255, cr);
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2007 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.classfile;
import java.io.IOException;
/**
* See JVMS3, section 4.8.8.
*
* <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 Synthetic_attribute extends Attribute {
Synthetic_attribute(ClassReader cr, int name_index, int length) throws IOException {
super(name_index, length);
}
public Synthetic_attribute(ConstantPool constant_pool)
throws ConstantPoolException {
this(constant_pool.getUTF8Index(Attribute.Synthetic));
}
public Synthetic_attribute(int name_index) {
super(name_index, 0);
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
return visitor.visitSynthetic(this, data);
}
}

View File

@ -0,0 +1,232 @@
/*
* 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. 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.classfile;
import java.util.List;
/*
* <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 Type {
protected Type() { }
public boolean isObject() {
return false;
}
protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
sb.append(prefix);
String sep = "";
for (Type t: types) {
sb.append(sep);
sb.append(t);
sep = ", ";
}
sb.append(suffix);
}
protected static void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
if (types != null && types.size() > 0)
append(sb, prefix, types, suffix);
}
public static class SimpleType extends Type {
public SimpleType(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
@Override
public boolean isObject() {
return name.equals("java.lang.Object");
}
public final String name;
}
public static class ArrayType extends Type {
public ArrayType(Type elemType) {
this.elemType = elemType;
}
@Override
public String toString() {
return elemType + "[]";
}
public final Type elemType;
}
public static class MethodType extends Type {
public MethodType(List<? extends Type> argTypes, Type resultType) {
this(null, argTypes, resultType, null);
}
public MethodType(List<? extends Type> typeArgTypes,
List<? extends Type> argTypes,
Type returnType,
List<? extends Type> throwsTypes) {
this.typeArgTypes = typeArgTypes;
this.argTypes = argTypes;
this.returnType = returnType;
this.throwsTypes = throwsTypes;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendIfNotEmpty(sb, "<", typeArgTypes, "> ");
sb.append(returnType);
append(sb, " (", argTypes, ")");
appendIfNotEmpty(sb, " throws ", throwsTypes, "");
return sb.toString();
}
public final List<? extends Type> typeArgTypes;
public final List<? extends Type> argTypes;
public final Type returnType;
public final List<? extends Type> throwsTypes;
}
public static class ClassSigType extends Type {
public ClassSigType(List<Type> typeArgTypes, Type superclassType, List<Type> superinterfaceTypes) {
this.typeArgTypes = typeArgTypes;
this.superclassType = superclassType;
this.superinterfaceTypes = superinterfaceTypes;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
appendIfNotEmpty(sb, "<", typeArgTypes, ">");
if (superclassType != null && !superclassType.isObject()) {
sb.append(" extends ");
sb.append(superclassType);
}
appendIfNotEmpty(sb, " implements ", superinterfaceTypes, "");
return sb.toString();
}
public final List<Type> typeArgTypes;
public final Type superclassType;
public final List<Type> superinterfaceTypes;
}
public static class ClassType extends Type {
public ClassType(String name, List<Type> typeArgs) {
this.name = name;
this.typeArgs = typeArgs;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
appendIfNotEmpty(sb, "<", typeArgs, ">");
return sb.toString();
}
public final String name;
public final List<Type> typeArgs;
}
public static class InnerClassType extends Type {
public InnerClassType(Type outerType, Type innerType) {
this.outerType = outerType;
this.innerType = innerType;
}
@Override
public String toString() {
return outerType + "." + innerType;
}
public final Type outerType;
public final Type innerType;
}
public static class TypeArgType extends Type {
public TypeArgType(String name, Type classBound, List<Type> interfaceBounds) {
this.name = name;
this.classBound = classBound;
this.interfaceBounds = interfaceBounds;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(name);
String sep = " extends ";
if (classBound != null && !classBound.isObject()) {
sb.append(sep);
sb.append(classBound);
sep = " & ";
}
if (interfaceBounds != null) {
for (Type bound: interfaceBounds) {
sb.append(sep);
sb.append(bound);
sep = " & ";
}
}
return sb.toString();
}
public final String name;
public final Type classBound;
public final List<Type> interfaceBounds;
}
public static class WildcardType extends Type {
public WildcardType() {
this(null, null);
}
public WildcardType(String kind, Type boundType) {
this.kind = kind;
this.boundType = boundType;
}
@Override
public String toString() {
if (kind == null)
return "?";
else
return "? " + kind + " " + boundType;
}
public final String kind;
public final Type boundType;
}
}

View File

@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
A minimalist library to read and write class files into objects closely
based on the corresponding definitions in the Java Virtual Machine
Specification (JVMS).
</body>
</html>

View File

@ -0,0 +1,114 @@
/*
* Copyright 2007 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.Annotation;
import com.sun.tools.classfile.Annotation.Annotation_element_value;
import com.sun.tools.classfile.Annotation.Array_element_value;
import com.sun.tools.classfile.Annotation.Class_element_value;
import com.sun.tools.classfile.Annotation.Enum_element_value;
import com.sun.tools.classfile.Annotation.Primitive_element_value;
/**
* A writer for writing annotations as text.
*
* <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 AnnotationWriter extends BasicWriter {
static AnnotationWriter instance(Context context) {
AnnotationWriter instance = context.get(AnnotationWriter.class);
if (instance == null)
instance = new AnnotationWriter(context);
return instance;
}
protected AnnotationWriter(Context context) {
super(context);
}
public void write(Annotation annot) {
print("#" + annot.type_index + "(");
for (int i = 0; i < annot.num_element_value_pairs; i++) {
if (i > 0)
print(",");
write(annot.element_value_pairs[i]);
}
print(")");
}
public void write(Annotation.element_value_pair pair) {
print("#" + pair.element_name_index + ":");
write(pair.value);
}
public void write(Annotation.element_value value) {
ev_writer.write(value);
}
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);
}
public Void visitPrimitive(Primitive_element_value ev, Void p) {
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);
return null;
}
public Void visitClass(Class_element_value ev, Void p) {
print(((char) ev.tag) + "#" + ev.class_info_index);
return null;
}
public Void visitAnnotation(Annotation_element_value ev, Void p) {
print((char) ev.tag);
AnnotationWriter.this.write(ev.annotation_value);
return null;
}
public Void visitArray(Array_element_value ev, Void p) {
print("[");
for (int i = 0; i < ev.num_values; i++) {
if (i > 0)
print(",");
write(ev.values[i]);
}
print("]");
return null;
}
}
}

View File

@ -0,0 +1,679 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.util.Formatter;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.AnnotationDefault_attribute;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.CharacterRangeTable_attribute;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.CompilationID_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.ConstantValue_attribute;
import com.sun.tools.classfile.DefaultAttribute;
import com.sun.tools.classfile.Deprecated_attribute;
import com.sun.tools.classfile.EnclosingMethod_attribute;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.InnerClasses_attribute;
import com.sun.tools.classfile.LineNumberTable_attribute;
import com.sun.tools.classfile.LocalVariableTable_attribute;
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
import com.sun.tools.classfile.ModuleExportTable_attribute;
import com.sun.tools.classfile.ModuleMemberTable_attribute;
import com.sun.tools.classfile.Module_attribute;
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.Signature_attribute;
import com.sun.tools.classfile.SourceDebugExtension_attribute;
import com.sun.tools.classfile.SourceFile_attribute;
import com.sun.tools.classfile.SourceID_attribute;
import com.sun.tools.classfile.StackMapTable_attribute;
import com.sun.tools.classfile.StackMap_attribute;
import com.sun.tools.classfile.Synthetic_attribute;
import static com.sun.tools.classfile.AccessFlags.*;
/*
* A writer for writing Attributes as text.
*
* <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 AttributeWriter extends BasicWriter
implements Attribute.Visitor<Void,Void>
{
static AttributeWriter instance(Context context) {
AttributeWriter instance = context.get(AttributeWriter.class);
if (instance == null)
instance = new AttributeWriter(context);
return instance;
}
protected AttributeWriter(Context context) {
super(context);
context.put(AttributeWriter.class, this);
annotationWriter = AnnotationWriter.instance(context);
codeWriter = CodeWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
options = Options.instance(context);
}
public void write(Object owner, Attribute attr, ConstantPool constant_pool) {
if (attr != null) {
// null checks
owner.getClass();
constant_pool.getClass();
this.constant_pool = constant_pool;
this.owner = owner;
attr.accept(this, null);
}
}
public void write(Object owner, Attributes attrs, ConstantPool constant_pool) {
if (attrs != null) {
// null checks
owner.getClass();
constant_pool.getClass();
this.constant_pool = constant_pool;
this.owner = owner;
for (Attribute attr: attrs)
attr.accept(this, null);
}
}
public Void visitDefault(DefaultAttribute attr, Void ignore) {
byte[] data = attr.info;
int i = 0;
int j = 0;
print(" ");
try {
print(attr.getName(constant_pool));
} catch (ConstantPoolException e) {
report(e);
print("attribute name = #" + attr.attribute_name_index);
}
print(": ");
println("length = 0x" + toHex(attr.info.length));
print(" ");
while (i < data.length) {
print(toHex(data[i], 2));
j++;
if (j == 16) {
println();
print(" ");
j = 0;
} else {
print(" ");
}
i++;
}
println();
return null;
}
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
println(" AnnotationDefault: ");
print(" default_value: ");
annotationWriter.write(attr.default_value);
return null;
}
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
print(" CharacterRangeTable: ");
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// ");
print(e.start_pc + ", " +
e.end_pc + ", " +
(e.character_range_start >> 10) + ":" + (e.character_range_start & 0x3ff) + ", " +
(e.character_range_end >> 10) + ":" + (e.character_range_end & 0x3ff));
if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0)
print(", statement");
if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0)
print(", block");
if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0)
print(", assignment");
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0)
print(", flow-controller");
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0)
print(", flow-target");
if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0)
print(", invoke");
if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0)
print(", create");
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0)
print(", branch-true");
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
print(", branch-false");
}
return null;
}
public Void visitCode(Code_attribute attr, Void ignore) {
codeWriter.write(attr, constant_pool);
println();
return null;
}
public Void visitCompilationID(CompilationID_attribute attr, Void ignore) {
constantWriter.write(attr.compilationID_index);
return null;
}
public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
if (options.compat) // BUG 6622216 javap names some attributes incorrectly
print(" Constant value: ");
else
print(" ConstantValue: ");
constantWriter.write(attr.constantvalue_index);
if (!options.compat) // BUG 6622232 javap gets whitespace confused
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));
if (attr.method_index != 0)
print("." + getMethodName(attr));
println();
return null;
}
private String getJavaClassName(EnclosingMethod_attribute a) {
try {
return getJavaName(a.getClassName(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
}
}
private String getMethodName(EnclosingMethod_attribute a) {
try {
return a.getMethodName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
println(" Exceptions: ");
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();
return null;
}
String getJavaException(Exceptions_attribute attr, int index) {
try {
return getJavaName(attr.getException(index, constant_pool));
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) {
boolean first = true;
if (options.compat) {
writeInnerClassHeader();
first = false;
}
for (int i = 0 ; i < attr.classes.length; i++) {
InnerClasses_attribute.Info info = attr.classes[i];
//access
AccessFlags access_flags = info.inner_class_access_flags;
if (options.compat) {
// BUG 6622215: javap ignores certain relevant access flags
access_flags = access_flags.ignore(ACC_STATIC | ACC_PROTECTED | ACC_PRIVATE | ACC_INTERFACE | ACC_SYNTHETIC | ACC_ENUM);
// BUG 6622232: javap gets whitespace confused
print(" ");
}
if (options.checkAccess(access_flags)) {
if (first) {
writeInnerClassHeader();
first = false;
}
if (!options.compat) // BUG 6622232: javap gets whitespace confused
print(" ");
for (String name: access_flags.getInnerClassModifiers())
print(name + " ");
if (info.inner_name_index!=0) {
print("#" + info.inner_name_index + "= ");
}
print("#" + info.inner_class_info_index);
if (info.outer_class_info_index != 0) {
print(" of #" + info.outer_class_info_index);
}
print("; //");
if (info.inner_name_index != 0) {
print(getInnerName(constant_pool, info) + "=");
}
constantWriter.write(info.inner_class_info_index);
if (info.outer_class_info_index != 0) {
print(" of ");
constantWriter.write(info.outer_class_info_index);
}
println();
}
}
return null;
}
String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) {
try {
return info.getInnerName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
private void writeInnerClassHeader() {
print(" ");
if (options.compat) // BUG 6622216: javap names some attributes incorrectly
print("InnerClass");
else
print("InnerClasses");
println(": ");
}
public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
println(" LineNumberTable: ");
for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
println(" line " + entry.line_number + ": " + entry.start_pc);
}
return null;
}
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
println(" LocalVariableTable: ");
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",
entry.start_pc, entry.length, entry.index,
constantWriter.stringValue(entry.name_index),
constantWriter.stringValue(entry.descriptor_index)));
}
return null;
}
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
println(" LocalVariableTypeTable: ");
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",
entry.start_pc, entry.length, entry.index,
constantWriter.stringValue(entry.name_index),
constantWriter.stringValue(entry.signature_index)));
}
return null;
}
public Void visitModule(Module_attribute attr, Void ignore) {
println(" Module: #" + attr.module_name + "\t// " + getModuleName(attr));
return null;
}
String getModuleName(Module_attribute attr) {
try {
return attr.getModuleName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitModuleExportTable(ModuleExportTable_attribute attr, Void ignore) {
println(" ModuleExportTable:");
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));
}
return null;
}
String getExportTypeName(ModuleExportTable_attribute attr, int index) {
try {
return attr.getExportTypeName(index, constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, Void ignore) {
println(" ModuleMemberTable:");
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));
}
return null;
}
String getPackageMemberName(ModuleMemberTable_attribute attr, int index) {
try {
return attr.getPackageMemberName(index, constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
println(" RuntimeVisibleAnnotations: ");
for (int i = 0; i < attr.annotations.length; i++) {
print(" " + i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
return null;
}
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
println(" RuntimeInvisibleAnnotations: ");
for (int i = 0; i < attr.annotations.length; i++) {
print(" " + i + ": ");
annotationWriter.write(attr.annotations[i]);
println();
}
return null;
}
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
println(" RuntimeVisibleParameterAnnotations: ");
for (int param = 0; param < attr.parameter_annotations.length; param++) {
println(" parameter " + param + ": ");
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
print(" " + i + ": ");
annotationWriter.write(attr.parameter_annotations[param][i]);
println();
}
}
return null;
}
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) {
println(" RuntimeInvisibleParameterAnnotations: ");
for (int param = 0; param < attr.parameter_annotations.length; param++) {
println(" " + param + ": ");
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
print(" " + i + ": ");
annotationWriter.write(attr.parameter_annotations[param][i]);
println();
}
}
return null;
}
public Void visitSignature(Signature_attribute attr, Void ignore) {
println(" Signature: #" + attr.signature_index + "\t// " + getSignature(attr));
return null;
}
String getSignature(Signature_attribute info) {
try {
return info.getSignature(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
println(" SourceDebugExtension: " + attr.getValue());
return null;
}
public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
println(" SourceFile: \"" + getSourceFile(attr) + "\"");
return null;
}
private String getSourceFile(SourceFile_attribute attr) {
try {
return attr.getSourceFile(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
public Void visitSourceID(SourceID_attribute attr, Void ignore) {
constantWriter.write(attr.sourceID_index);
return null;
}
public Void visitStackMap(StackMap_attribute attr, Void ignore) {
println(" StackMap: number_of_entries = " + attr.number_of_entries);
StackMapTableWriter w = new StackMapTableWriter();
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
w.write(entry);
}
println();
return null;
}
public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
println(" StackMapTable: number_of_entries = " + attr.number_of_entries);
StackMapTableWriter w = new StackMapTableWriter();
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
w.write(entry);
}
println();
return null;
}
class StackMapTableWriter // also handles CLDC StackMap attributes
implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> {
public void write(StackMapTable_attribute.stack_map_frame frame) {
frame.accept(this, null);
}
public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) {
printHeader(frame);
println(" /* same */");
return null;
}
public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
printHeader(frame);
println(" /* same_locals_1_stack_item */");
printMap("stack", frame.stack);
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);
printMap("stack", frame.stack);
return null;
}
public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) {
printHeader(frame);
println(" /* chop */");
println(" offset_delta = " + frame.offset_delta);
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);
return null;
}
public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) {
printHeader(frame);
println(" /* append */");
println(" offset_delta = " + frame.offset_delta);
printMap("locals", frame.locals);
return null;
}
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);
} else {
println(" /* full_frame */");
println(" offset_delta = " + frame.offset_delta);
}
printMap("locals", frame.locals);
printMap("stack", frame.stack);
return null;
}
void printHeader(StackMapTable_attribute.stack_map_frame frame) {
print(" frame_type = " + frame.frame_type);
}
void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
print(" " + name + " = [");
for (int i = 0; i < map.length; i++) {
StackMapTable_attribute.verification_type_info info = map[i];
int tag = info.tag;
switch (tag) {
case StackMapTable_attribute.verification_type_info.ITEM_Object:
print(" ");
constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index);
break;
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
print(" " + mapTypeName(tag));
print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset);
break;
default:
print(" " + mapTypeName(tag));
}
print(i == (map.length - 1) ? " " : ",");
}
println("]");
}
String mapTypeName(int tag) {
switch (tag) {
case StackMapTable_attribute.verification_type_info.ITEM_Top:
return "top";
case StackMapTable_attribute.verification_type_info.ITEM_Integer:
return "int";
case StackMapTable_attribute.verification_type_info.ITEM_Float:
return "float";
case StackMapTable_attribute.verification_type_info.ITEM_Long:
return "long";
case StackMapTable_attribute.verification_type_info.ITEM_Double:
return "double";
case StackMapTable_attribute.verification_type_info.ITEM_Null:
return "null";
case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis:
return "this";
case StackMapTable_attribute.verification_type_info.ITEM_Object:
return "CP";
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
return "uninitialized";
default:
report("unrecognized verification_type_info tag: " + tag);
return "[tag:" + tag + "]";
}
}
}
public Void visitSynthetic(Synthetic_attribute attr, Void ignore) {
println("Synthetic: true");
return null;
}
static String getJavaName(String name) {
return name.replace('/', '.');
}
String toHex(byte b, int w) {
if (options.compat) // BUG 6622260: javap prints negative bytes incorrectly in hex
return toHex((int) b, w);
else
return toHex(b & 0xff, w);
}
static String toHex(int i) {
return Integer.toString(i, 16).toUpperCase();
}
static String toHex(int i, int w) {
String s = Integer.toHexString(i).toUpperCase();
while (s.length() < w)
s = "0" + s;
return s.toUpperCase();
}
private AnnotationWriter annotationWriter;
private CodeWriter codeWriter;
private ConstantWriter constantWriter;
private Options options;
private ConstantPool constant_pool;
private Object owner;
}

View File

@ -0,0 +1,131 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.io.PrintWriter;
import com.sun.tools.classfile.AttributeException;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.DescriptorException;
/*
* A writer similar to a PrintWriter but which does not hide exceptions.
* The standard print calls are line-buffered; report calls write messages directly.
*
* <p><b>This is NOT part of any 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 BasicWriter {
protected BasicWriter(Context context) {
lineWriter = LineWriter.instance(context);
out = context.get(PrintWriter.class);
}
protected void print(String s) {
lineWriter.print(s);
}
protected void print(Object o) {
lineWriter.print(o == null ? null : o.toString());
}
protected void println() {
lineWriter.println();
}
protected void println(String s) {
lineWriter.print(s);
lineWriter.println();
}
protected void println(Object o) {
lineWriter.print(o == null ? null : o.toString());
lineWriter.println();
}
protected String report(AttributeException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(ConstantPoolException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(DescriptorException e) {
out.println("Error: " + e.getMessage()); // i18n?
return "???";
}
protected String report(String msg) {
out.println("Error: " + msg); // i18n?
return "???";
}
private LineWriter lineWriter;
private PrintWriter out;
private static class LineWriter {
static LineWriter instance(Context context) {
LineWriter instance = context.get(LineWriter.class);
if (instance == null)
instance = new LineWriter(context);
return instance;
}
protected LineWriter(Context context) {
context.put(LineWriter.class, this);
out = context.get(PrintWriter.class);
buffer = new StringBuilder();
}
protected void print(String s) {
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);
}
}
}
protected void println() {
out.println(buffer);
buffer.setLength(0);
}
private PrintWriter out;
private StringBuilder buffer;
}
}

View File

@ -0,0 +1,488 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.util.Collection;
import java.util.List;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.Attributes;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Descriptor;
import com.sun.tools.classfile.DescriptorException;
import com.sun.tools.classfile.Exceptions_attribute;
import com.sun.tools.classfile.Field;
import com.sun.tools.classfile.Method;
import com.sun.tools.classfile.Signature;
import com.sun.tools.classfile.Signature_attribute;
import com.sun.tools.classfile.SourceFile_attribute;
import com.sun.tools.classfile.Type;
import static com.sun.tools.classfile.AccessFlags.*;
/*
* The main javap class to write the contents of a class file as text.
*
* <p><b>This is NOT part of any 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 ClassWriter extends BasicWriter {
static ClassWriter instance(Context context) {
ClassWriter instance = context.get(ClassWriter.class);
if (instance == null)
instance = new ClassWriter(context);
return instance;
}
protected ClassWriter(Context context) {
super(context);
context.put(ClassWriter.class, this);
options = Options.instance(context);
attrWriter = AttributeWriter.instance(context);
codeWriter = CodeWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
}
ClassFile getClassFile() {
return classFile;
}
Method getMethod() {
return method;
}
public void write(ClassFile cf) {
classFile = cf;
constant_pool = classFile.constant_pool;
Attribute sfa = cf.getAttribute(Attribute.SourceFile);
if (sfa instanceof SourceFile_attribute) {
println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
}
String name = getJavaName(classFile);
AccessFlags flags = cf.access_flags;
writeModifiers(flags.getClassModifiers());
if (classFile.isClass())
print("class ");
else if (classFile.isInterface())
print("interface ");
print(name);
Signature_attribute sigAttr = getSignature(cf.attributes);
if (sigAttr == null) {
// use info from class file header
if (classFile.isClass()) {
if (classFile.super_class != 0 ) {
String sn = getJavaSuperclassName(cf);
if (!sn.equals("java.lang.Object") || options.compat) { // BUG XXXXXXXX
print(" extends ");
print(sn);
}
}
}
for (int i = 0; i < classFile.interfaces.length; i++) {
print(i == 0 ? (classFile.isClass() ? " implements " : " extends ") : ",");
print(getJavaInterfaceName(classFile, i));
}
} else {
try {
Type t = sigAttr.getParsedSignature().getType(constant_pool);
// The signature parser cannot disambiguate between a
// FieldType and a ClassSignatureType that only contains a superclass type.
if (t instanceof Type.ClassSigType)
print(t);
else if (!t.isObject()) {
print(" extends ");
print(t);
}
} catch (ConstantPoolException e) {
print(report(e));
}
}
if (options.verbose) {
println();
attrWriter.write(cf, cf.attributes, constant_pool);
println(" minor version: " + cf.minor_version);
println(" major version: " + cf.major_version);
if (!options.compat)
writeList(" flags: ", flags.getClassFlags(), NEWLINE);
constantWriter.writeConstantPool();
println();
} else {
if (!options.compat)
print(" ");
}
println("{");
writeFields();
writeMethods();
println("}");
println();
}
void writeFields() {
for (Field f: classFile.fields) {
writeField(f);
}
}
void writeField(Field f) {
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);
if (sigAttr == null)
print(getFieldType(f.descriptor));
else {
try {
Type t = sigAttr.getParsedSignature().getType(constant_pool);
print(t);
} catch (ConstantPoolException e) {
// report error?
// fall back on non-generic descriptor
print(getFieldType(f.descriptor));
}
}
print(" ");
print(getFieldName(f));
print(";");
println();
if (options.showInternalSignatures)
println(" Signature: " + getValue(f.descriptor));
if (options.verbose && !options.compat)
writeList(" flags: ", flags.getFieldFlags(), NEWLINE);
if (options.showAllAttrs) {
for (Attribute attr: f.attributes)
attrWriter.write(f, attr, constant_pool);
println();
}
if (options.showDisassembled || options.showLineAndLocalVariableTables)
println();
}
void writeMethods() {
for (Method m: classFile.methods)
writeMethod(m);
}
void writeMethod(Method m) {
if (!options.checkAccess(m.access_flags))
return;
method = m;
if (!(options.showLineAndLocalVariableTables
|| options.showDisassembled
|| options.verbose
|| options.showInternalSignatures
|| options.showAllAttrs)) {
print(" ");
}
AccessFlags flags = m.access_flags;
Descriptor d;
Type.MethodType methodType;
List<? extends Type> methodExceptions;
Signature_attribute sigAttr = getSignature(m.attributes);
if (sigAttr == null) {
d = m.descriptor;
methodType = null;
methodExceptions = null;
} else {
Signature methodSig = sigAttr.getParsedSignature();
d = methodSig;
try {
methodType = (Type.MethodType) methodSig.getType(constant_pool);
methodExceptions = methodType.throwsTypes;
if (methodExceptions != null && methodExceptions.size() == 0)
methodExceptions = null;
} catch (ConstantPoolException e) {
// report error?
// fall back on standard descriptor
methodType = null;
methodExceptions = null;
}
}
writeModifiers(flags.getMethodModifiers());
if (methodType != null) {
writeListIfNotEmpty("<", methodType.typeArgTypes, "> ");
}
if (getName(m).equals("<init>")) {
print(getJavaName(classFile));
print(getParameterTypes(d, flags));
} else if (getName(m).equals("<clinit>")) {
print("{}");
} else {
print(getReturnType(d));
print(" ");
print(getName(m));
print(getParameterTypes(d, flags));
}
Attribute e_attr = m.attributes.get(Attribute.Exceptions);
if (e_attr != null) { // if there are generic exceptions, there must be erased exceptions
if (e_attr instanceof Exceptions_attribute) {
Exceptions_attribute exceptions = (Exceptions_attribute) e_attr;
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, "");
} else {
for (int i = 0; i < exceptions.number_of_exceptions; i++) {
if (i > 0)
print(", ");
print(attrWriter.getJavaException(exceptions, i));
}
}
} else {
report("Unexpected or invalid value for Exceptions attribute");
}
}
print(";");
println();
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);
if (c_attr != null) {
if (c_attr instanceof Code_attribute)
code = (Code_attribute) c_attr;
else
report("Unexpected or invalid value for Code attribute");
}
if (options.showDisassembled && !options.showAllAttrs) {
if (code != null) {
println(" Code:");
codeWriter.writeInstrs(code);
codeWriter.writeExceptionTable(code);
}
println();
}
if (options.showLineAndLocalVariableTables) {
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();
}
}
void writeModifiers(Collection<String> items) {
for (Object item: items) {
print(item);
print(" ");
}
}
void writeList(String prefix, Collection<?> items, String suffix) {
print(prefix);
String sep = "";
for (Object item: items) {
print(sep);
print(item);
sep = ", ";
}
print(suffix);
}
void writeListIfNotEmpty(String prefix, List<?> items, String suffix) {
if (items != null && items.size() > 0)
writeList(prefix, items, suffix);
}
Signature_attribute getSignature(Attributes attributes) {
if (options.compat) // javap does not recognize recent attributes
return null;
return (Signature_attribute) attributes.get(Attribute.Signature);
}
String adjustVarargs(AccessFlags flags, String params) {
if (flags.is(ACC_VARARGS) && !options.compat) {
int i = params.lastIndexOf("[]");
if (i > 0)
return params.substring(0, i) + "..." + params.substring(i+2);
}
return params;
}
String getJavaName(ClassFile cf) {
try {
return getJavaName(cf.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getJavaSuperclassName(ClassFile cf) {
try {
return getJavaName(cf.getSuperclassName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getJavaInterfaceName(ClassFile cf, int index) {
try {
return getJavaName(cf.getInterfaceName(index));
} catch (ConstantPoolException e) {
return report(e);
}
}
String getFieldType(Descriptor d) {
try {
return d.getFieldType(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getReturnType(Descriptor d) {
try {
return d.getReturnType(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getParameterTypes(Descriptor d, AccessFlags flags) {
try {
return adjustVarargs(flags, d.getParameterTypes(constant_pool));
} catch (ConstantPoolException e) {
return report(e);
} catch (DescriptorException e) {
return report(e);
}
}
String getValue(Descriptor d) {
try {
return d.getValue(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
String getFieldName(Field f) {
try {
return f.getName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
String getName(Method m) {
try {
return m.getName(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
static String getJavaName(String name) {
return name.replace('/', '.');
}
String getSourceFile(SourceFile_attribute attr) {
try {
return attr.getSourceFile(constant_pool);
} catch (ConstantPoolException e) {
return report(e);
}
}
private Options options;
private AttributeWriter attrWriter;
private CodeWriter codeWriter;
private ConstantWriter constantWriter;
private ClassFile classFile;
private ConstantPool constant_pool;
private Method method;
private static final String NEWLINE = System.getProperty("line.separator", "\n");
}

View File

@ -0,0 +1,344 @@
/*
* Copyright 2007 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.AccessFlags;
import com.sun.tools.classfile.Code_attribute;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.DescriptorException;
import com.sun.tools.classfile.Method;
import static com.sun.tools.classfile.OpCodes.*;
/*
* Write the contents of a Code attribute.
*
* <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>
*/
class CodeWriter extends BasicWriter {
static CodeWriter instance(Context context) {
CodeWriter instance = context.get(CodeWriter.class);
if (instance == null)
instance = new CodeWriter(context);
return instance;
}
protected CodeWriter(Context context) {
super(context);
context.put(CodeWriter.class, this);
attrWriter = AttributeWriter.instance(context);
classWriter = ClassWriter.instance(context);
constantWriter = ConstantWriter.instance(context);
}
void write(Code_attribute attr, ConstantPool constant_pool) {
println(" Code:");
writeVerboseHeader(attr, constant_pool);
writeInstrs(attr);
writeExceptionTable(attr);
attrWriter.write(attr, attr.attributes, constant_pool);
}
public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
Method method = classWriter.getMethod();
String argCount;
try {
int n = method.descriptor.getParameterCount(constant_pool);
if (!method.access_flags.is(AccessFlags.ACC_STATIC))
++n; // for 'this'
argCount = Integer.toString(n);
} catch (ConstantPoolException e) {
argCount = report(e);
} catch (DescriptorException e) {
argCount = report(e);
}
println(" Stack=" + attr.max_stack +
", Locals=" + attr.max_locals +
", Args_size=" + argCount);
}
public void writeInstrs(Code_attribute attr) {
try {
for (int pc = 0; pc < attr.code_length;) {
print(" " + pc + ":\t");
pc += writeInstr(attr, pc);
println();
}
} catch (Code_attribute.InvalidIndex e) {
println(report(e));
}
}
public int writeInstr(Code_attribute attr, int pc)
throws Code_attribute.InvalidIndex {
String lP = "";
int opcode = attr.getUnsignedByte(pc);
int opcode2;
String mnem;
switch (opcode) {
case opc_nonpriv:
case opc_priv: {
opcode2 = attr.getUnsignedByte(pc + 1);
mnem = opcName((opcode << 8) + opcode2);
if (mnem == null) {
mnem = opcName(opcode) + " " + opcode2;
}
print(mnem);
return 2;
}
case opc_wide: {
opcode2 = attr.getUnsignedByte(pc + 1);
mnem = opcName((opcode << 8) + opcode2);
if (mnem == null) {
print("bytecode " + opcode);
return 1;
}
print(mnem + " " + attr.getUnsignedShort(pc + 2));
if (opcode2 == opc_iinc) {
print(", " + attr.getShort(pc + 4));
return 6;
}
return 4;
}
}
mnem = opcName(opcode);
if (mnem == null) {
print("bytecode " + opcode);
return 1;
}
if (opcode > opc_jsr_w) {
print("bytecode " + opcode);
return 1;
}
print(opcName(opcode));
switch (opcode) {
case opc_aload:
case opc_astore:
case opc_fload:
case opc_fstore:
case opc_iload:
case opc_istore:
case opc_lload:
case opc_lstore:
case opc_dload:
case opc_dstore:
case opc_ret:
print("\t" + attr.getUnsignedByte(pc + 1));
return 2;
case opc_iinc:
print("\t" + attr.getUnsignedByte(pc + 1) + ", " + attr.getByte(pc + 2));
return 3;
case opc_tableswitch:
{
int tb = align(pc + 1);
int default_skip = attr.getInt(tb);
int low = attr.getInt(tb + 4);
int high = attr.getInt(tb + 8);
int count = high - low;
print("{ //" + low + " to " + high);
for (int i = 0; i <= count; i++) {
print("\n\t\t" + (i + low) + ": " + lP + (pc + attr.getInt(tb + 12 + 4 * i)) + ";");
}
print("\n\t\tdefault: " + lP + (default_skip + pc) + " }");
return tb - pc + 16 + count * 4;
}
case opc_lookupswitch:
{
int tb = align(pc + 1);
int default_skip = attr.getInt(tb);
int npairs = attr.getInt(tb + 4);
print("{ //" + npairs);
for (int i = 1; i <= npairs; i++) {
print("\n\t\t" + attr.getInt(tb + i * 8) + ": " + lP + (pc + attr.getInt(tb + 4 + i * 8)) + ";");
}
print("\n\t\tdefault: " + lP + (default_skip + pc) + " }");
return tb - pc + (npairs + 1) * 8;
}
case opc_newarray:
int type = attr.getUnsignedByte(pc + 1);
switch (type) {
case T_BOOLEAN:
print(" boolean");
break;
case T_BYTE:
print(" byte");
break;
case T_CHAR:
print(" char");
break;
case T_SHORT:
print(" short");
break;
case T_INT:
print(" int");
break;
case T_LONG:
print(" long");
break;
case T_FLOAT:
print(" float");
break;
case T_DOUBLE:
print(" double");
break;
case T_CLASS:
print(" class");
break;
default:
print(" BOGUS TYPE:" + type);
}
return 2;
case opc_anewarray:
{
int index = attr.getUnsignedShort(pc + 1);
print("\t#" + index + "; //");
printConstant(index);
return 3;
}
case opc_sipush:
print("\t" + attr.getShort(pc + 1));
return 3;
case opc_bipush:
print("\t" + attr.getByte(pc + 1));
return 2;
case opc_ldc:
{
int index = attr.getUnsignedByte(pc + 1);
print("\t#" + index + "; //");
printConstant(index);
return 2;
}
case opc_ldc_w:
case opc_ldc2_w:
case opc_instanceof:
case opc_checkcast:
case opc_new:
case opc_putstatic:
case opc_getstatic:
case opc_putfield:
case opc_getfield:
case opc_invokevirtual:
case opc_invokespecial:
case opc_invokestatic:
{
int index = attr.getUnsignedShort(pc + 1);
print("\t#" + index + "; //");
printConstant(index);
return 3;
}
case opc_invokeinterface:
{
int index = attr.getUnsignedShort(pc + 1);
int nargs = attr.getUnsignedByte(pc + 3);
print("\t#" + index + ", " + nargs + "; //");
printConstant(index);
return 5;
}
case opc_multianewarray:
{
int index = attr.getUnsignedShort(pc + 1);
int dimensions = attr.getUnsignedByte(pc + 3);
print("\t#" + index + ", " + dimensions + "; //");
printConstant(index);
return 4;
}
case opc_jsr:
case opc_goto:
case opc_ifeq:
case opc_ifge:
case opc_ifgt:
case opc_ifle:
case opc_iflt:
case opc_ifne:
case opc_if_icmpeq:
case opc_if_icmpne:
case opc_if_icmpge:
case opc_if_icmpgt:
case opc_if_icmple:
case opc_if_icmplt:
case opc_if_acmpeq:
case opc_if_acmpne:
case opc_ifnull:
case opc_ifnonnull:
print("\t" + lP + (pc + attr.getShort(pc + 1)));
return 3;
case opc_jsr_w:
case opc_goto_w:
print("\t" + lP + (pc + attr.getInt(pc + 1)));
return 5;
default:
return 1;
}
}
public void writeExceptionTable(Code_attribute attr) {
if (attr.exception_table_langth > 0) {
println(" Exception table:");
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(" ");
int catch_type = handler.catch_type;
if (catch_type == 0) {
println("any");
} else {
print("Class ");
println(constantWriter.stringValue(catch_type));
println("");
}
}
}
}
private void printConstant(int index) {
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 static int align(int n) {
return (n + 3) & ~3;
}
private AttributeWriter attrWriter;
private ClassWriter classWriter;
private ConstantWriter constantWriter;
}

View File

@ -0,0 +1,352 @@
/*
* Copyright 2007 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.ClassFile;
import com.sun.tools.classfile.ConstantPool;
import com.sun.tools.classfile.ConstantPoolException;
import static com.sun.tools.classfile.ConstantPool.*;
/*
* Write a constant pool entry.
*
* <p><b>This is NOT part of any 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 ConstantWriter extends BasicWriter {
static ConstantWriter instance(Context context) {
ConstantWriter instance = context.get(ConstantWriter.class);
if (instance == null)
instance = new ConstantWriter(context);
return instance;
}
protected ConstantWriter(Context context) {
super(context);
context.put(ConstantWriter.class, this);
classWriter = ClassWriter.instance(context);
options = Options.instance(context);
}
void writeConstantPool() {
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));
return 1;
}
public Integer visitDouble(CONSTANT_Double_info info, Void p) {
println(stringValue(info) + ";");
return 2;
}
public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
return 1;
}
public Integer visitFloat(CONSTANT_Float_info info, Void p) {
println(stringValue(info) + ";");
return 1;
}
public Integer visitInteger(CONSTANT_Integer_info info, Void p) {
println(stringValue(info) + ";");
return 1;
}
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
return 1;
}
public Integer visitLong(CONSTANT_Long_info info, Void p) {
println(stringValue(info) + ";");
return 2;
}
public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
String tab = (options.compat ? "" : "\t"); // BUG 6622232 javap gets whitespace confused
println("#" + info.name_index + ":#" + info.type_index + ";" + tab + "// " + 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));
return 1;
}
public Integer visitString(CONSTANT_String_info info, Void p) {
println("#" + info.string_index + ";\t// " + stringValue(info));
return 1;
}
public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) {
println(stringValue(info) + ";");
return 1;
}
};
println(" Constant pool:");
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
int cpx = 1;
while (cpx < constant_pool.size()) {
try {
CPInfo cpInfo = constant_pool.get(cpx);
print("const #" + cpx + " = " + tagName(cpInfo.getTag()) + "\t");
cpx += cpInfo.accept(v, null);
} catch (ConstantPool.InvalidIndex ex) {
print("const #" + cpx); // should not happen
}
}
}
void write(int cpx) {
ClassFile classFile = classWriter.getClassFile();
if (cpx == 0) {
print("#0");
return;
}
CPInfo cpInfo;
try {
cpInfo = classFile.constant_pool.get(cpx);
} catch (ConstantPoolException e) {
print("#" + cpx);
return;
}
int tag = cpInfo.getTag();
switch (tag) {
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_Fieldref:
// simplify references within this class
CPRefInfo ref = (CPRefInfo) cpInfo;
try {
if (ref.class_index == classFile.this_class)
cpInfo = classFile.constant_pool.get(ref.name_and_type_index);
} catch (ConstantPool.InvalidIndex e) {
// ignore, for now
}
}
print(tagName(tag) + " " + stringValue(cpInfo));
}
String tagName(int tag) {
switch (tag) {
case CONSTANT_Utf8:
return "Asciz";
case CONSTANT_Integer:
return "int";
case CONSTANT_Float:
return "float";
case CONSTANT_Long:
return "long";
case CONSTANT_Double:
return "double";
case CONSTANT_Class:
return "class";
case CONSTANT_String:
return "String";
case CONSTANT_Fieldref:
return "Field";
case CONSTANT_Methodref:
return "Method";
case CONSTANT_InterfaceMethodref:
return "InterfaceMethod";
case CONSTANT_NameAndType:
return "NameAndType";
default:
return "unknown tag";
}
}
String stringValue(int constant_pool_index) {
ClassFile classFile = classWriter.getClassFile();
try {
return stringValue(classFile.constant_pool.get(constant_pool_index));
} catch (ConstantPool.InvalidIndex e) {
return report(e);
}
}
String stringValue(CPInfo cpInfo) {
return stringValueVisitor.visit(cpInfo);
}
StringValueVisitor stringValueVisitor = new StringValueVisitor();
private class StringValueVisitor implements ConstantPool.Visitor<String, Void> {
public String visit(CPInfo info) {
return info.accept(this, null);
}
public String visitClass(CONSTANT_Class_info info, Void p) {
return getCheckedName(info);
}
String getCheckedName(CONSTANT_Class_info info) {
try {
return checkName(info.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitDouble(CONSTANT_Double_info info, Void p) {
return info.value + "d";
}
public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
return visitRef(info, p);
}
public String visitFloat(CONSTANT_Float_info info, Void p) {
return info.value + "f";
}
public String visitInteger(CONSTANT_Integer_info info, Void p) {
return String.valueOf(info.value);
}
public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
return visitRef(info, p);
}
public String visitLong(CONSTANT_Long_info info, Void p) {
return info.value + "l";
}
public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
return getCheckedName(info) + ":" + getType(info);
}
String getCheckedName(CONSTANT_NameAndType_info info) {
try {
return checkName(info.getName());
} catch (ConstantPoolException e) {
return report(e);
}
}
String getType(CONSTANT_NameAndType_info info) {
try {
return info.getType();
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
return visitRef(info, p);
}
public String visitString(CONSTANT_String_info info, Void p) {
try {
ClassFile classFile = classWriter.getClassFile();
int string_index = info.string_index;
return stringValue(classFile.constant_pool.getUTF8Info(string_index));
} catch (ConstantPoolException e) {
return report(e);
}
}
public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
String s = info.value;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\t':
sb.append('\\').append('t');
break;
case '\n':
sb.append('\\').append('n');
break;
case '\r':
sb.append('\\').append('r');
break;
case '\"':
sb.append('\\').append('\"');
break;
default:
sb.append(c);
}
}
return sb.toString();
}
String visitRef(CPRefInfo info, Void p) {
String cn = getCheckedClassName(info);
String nat;
try {
nat = stringValue(info.getNameAndTypeInfo());
} catch (ConstantPoolException e) {
nat = report(e);
}
return cn + "." + nat;
}
String getCheckedClassName(CPRefInfo info) {
try {
return checkName(info.getClassName());
} catch (ConstantPoolException e) {
return report(e);
}
}
}
/* If name is a valid binary name, return it; otherwise quote it. */
private static String checkName(String name) {
if (name == null)
return "null";
int len = name.length();
if (len == 0)
return "\"\"";
int cc = '/';
int cp;
for (int k = 0; k < len; k += Character.charCount(cp)) {
cp = name.codePointAt(k);
if ((cc == '/' && !Character.isJavaIdentifierStart(cp))
|| (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
return "\"" + name + "\"";
}
cc = cp;
}
return name;
}
private ClassWriter classWriter;
private Options options;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.util.HashMap;
import java.util.Map;
/*
* Class from which to put/get shared resources.
*
* <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 Context {
public Context() {
map = new HashMap<Class<?>, Object>();
}
@SuppressWarnings("unchecked")
public <T> T get(Class<T> key) {
return (T) map.get(key);
}
@SuppressWarnings("unchecked")
public <T> T put(Class<T> key, T value) {
return (T) map.put(key, value);
}
Map<Class<?>, Object> map;
}

View File

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

View File

@ -0,0 +1,46 @@
/*
* Copyright 2007 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;
/**
* <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 InternalError extends Error {
InternalError(Throwable t, Object... args) {
super("Internal error", t);
this.args = args;
}
InternalError(Object... args) {
super("Internal error");
this.args = args;
}
public final Object[] args;
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.io.File;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JavacFileManager;
/**
* javap's implementation of JavaFileManager.
*
* <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>
*/
class JavapFileManager extends JavacFileManager {
private JavapFileManager(Context context, Charset charset) {
super(context, true, charset);
}
static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) {
Context javac_context = new Context();
if (dl != null) {
// Workaround bug 6625520: javac handles missing entries on classpath badly
// Ignore spurious errors for missing files
DiagnosticListener<JavaFileObject> wrapper = new DiagnosticListener<JavaFileObject>() {
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic instanceof JCDiagnostic) {
JCDiagnostic jcd = (JCDiagnostic) diagnostic;
if (jcd.getCode().equals("compiler.err.error.reading.file")) {
Object[] args = jcd.getArgs();
if (args.length > 0 && args[0] != null && args[0].toString().length() > 0) {
File f = new File(args[0].toString());
if (!f.exists())
return;
}
}
}
dl.report(diagnostic);
}
};
javac_context.put(DiagnosticListener.class, wrapper);
}
javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
return new JavapFileManager(javac_context, null);
}
void setIgnoreSymbolFile(boolean b) {
ignoreSymbolFile = b;
}
}

View File

@ -0,0 +1,624 @@
/*
* Copyright 2007 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-15301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.classfile.*;
/**
* "Main" class for javap, normally accessed from the command line
* via Main, or from JSR199 via DisassemblerTool.
*
* <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 JavapTask implements DisassemblerTool.DisassemblerTask {
public class BadArgs extends Exception {
static final long serialVersionUID = 8765093759964640721L;
BadArgs(String key, Object... args) {
super(JavapTask.this.getMessage(key, args));
this.key = key;
this.args = args;
}
BadArgs showUsage(boolean b) {
showUsage = b;
return this;
}
final String key;
final Object[] args;
boolean showUsage;
}
static abstract class Option {
Option(boolean hasArg, String... aliases) {
this.hasArg = hasArg;
this.aliases = aliases;
}
boolean matches(String opt) {
for (String a: aliases) {
if (a.equals(opt))
return true;
}
return false;
}
boolean ignoreRest() {
return false;
}
abstract void process(JavapTask task, String opt, String arg) throws BadArgs;
final boolean hasArg;
final String[] aliases;
}
static Option[] recognizedOptions = {
new Option(false, "-help", "--help", "-?") {
void process(JavapTask task, String opt, String arg) {
task.options.help = true;
}
},
new Option(false, "-version") {
void process(JavapTask task, String opt, String arg) {
task.options.version = true;
}
},
new Option(false, "-fullversion") {
void process(JavapTask task, String opt, String arg) {
task.options.fullVersion = true;
}
},
new Option(false, "-v", "-verbose", "-all") {
void process(JavapTask task, String opt, String arg) {
task.options.verbose = true;
task.options.showFlags = true;
task.options.showAllAttrs = true;
}
},
new Option(false, "-l") {
void process(JavapTask task, String opt, String arg) {
task.options.showLineAndLocalVariableTables = true;
}
},
new Option(false, "-public") {
void process(JavapTask task, String opt, String arg) {
task.options.showAccess = AccessFlags.ACC_PUBLIC;
}
},
new Option(false, "-protected") {
void process(JavapTask task, String opt, String arg) {
task.options.showAccess = AccessFlags.ACC_PROTECTED;
}
},
new Option(false, "-package") {
void process(JavapTask task, String opt, String arg) {
task.options.showAccess = 0;
}
},
new Option(false, "-p", "-private") {
void process(JavapTask task, String opt, String arg) {
task.options.showAccess = AccessFlags.ACC_PRIVATE;
}
},
new Option(false, "-c") {
void process(JavapTask task, String opt, String arg) {
task.options.showDisassembled = true;
}
},
new Option(false, "-s") {
void process(JavapTask task, String opt, String arg) {
task.options.showInternalSignatures = true;
}
},
// new Option(false, "-all") {
// void process(JavapTask task, String opt, String arg) {
// task.options.showAllAttrs = true;
// }
// },
new Option(false, "-h") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
throw task.new BadArgs("err.h.not.supported");
}
},
new Option(false, "-verify", "-verify-verbose") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
throw task.new BadArgs("err.verify.not.supported");
}
},
new Option(false, "-Xold") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
// -Xold is only supported as first arg when invoked from
// command line; this is handled in Main,main
throw task.new BadArgs("err.Xold.not.supported.here");
}
},
new Option(false, "-Xnew") {
void process(JavapTask task, String opt, String arg) throws BadArgs {
// ignore: this _is_ the new version
}
},
new Option(false, "-XDcompat") {
void process(JavapTask task, String opt, String arg) {
task.options.compat = true;
}
},
new Option(false, "-XDjsr277") {
void process(JavapTask task, String opt, String arg) {
task.options.jsr277 = true;
}
},
new Option(false, "-XDignore.symbol.file") {
void process(JavapTask task, String opt, String arg) {
task.options.ignoreSymbolFile = true;
}
}
};
JavapTask() {
context = new Context();
options = Options.instance(context);
}
JavapTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
this();
this.log = getPrintWriterForWriter(out);
this.fileManager = fileManager;
this.diagnosticListener = 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);
}
}
public void setLocale(Locale locale) {
if (locale == null)
locale = Locale.getDefault();
task_locale = locale;
}
public void setLog(PrintWriter log) {
this.log = log;
}
public void setLog(OutputStream s) {
setLog(getPrintWriterForStream(s));
}
private static PrintWriter getPrintWriterForStream(OutputStream s) {
return new PrintWriter(s, true);
}
private static PrintWriter getPrintWriterForWriter(Writer w) {
if (w == null)
return getPrintWriterForStream(null);
else if (w instanceof PrintWriter)
return (PrintWriter) w;
else
return new PrintWriter(w, true);
}
public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
diagnosticListener = dl;
}
public void setDiagnosticListener(OutputStream s) {
setDiagnosticListener(getDiagnosticListenerForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
final PrintWriter pw = getPrintWriterForWriter(w);
return new DiagnosticListener<JavaFileObject> () {
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
pw.print(getMessage("err.prefix"));
pw.print(" ");
}
pw.println(diagnostic.getMessage(null));
}
};
}
int run(String[] args) {
try {
handleOptions(args);
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
diagnosticListener.report(createDiagnostic(e.key, e.args));
return 1;
} catch (InternalError e) {
Object[] e_args;
if (e.getCause() == null)
e_args = e.args;
else {
e_args = new Object[e.args.length + 1];
e_args[0] = e.getCause();
System.arraycopy(e.args, 0, e_args, 1, e.args.length);
}
diagnosticListener.report(createDiagnostic("err.internal.error", e_args));
return 1;
} finally {
log.flush();
}
}
public void handleOptions(String[] args) throws BadArgs {
handleOptions(Arrays.asList(args), true);
}
private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
if (log == null) {
log = getPrintWriterForStream(System.out);
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForStream(System.err);
} else {
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForWriter(log);
}
if (fileManager == null)
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = args.iterator();
if (!iter.hasNext())
options.help = true;
while (iter.hasNext()) {
String arg = iter.next();
if (arg.startsWith("-"))
handleOption(arg, iter);
else if (allowClasses) {
if (classes == null)
classes = new ArrayList<String>();
classes.add(arg);
while (iter.hasNext())
classes.add(iter.next());
} else
throw new BadArgs("err.unknown.option", arg).showUsage(true);
}
if (options.ignoreSymbolFile && fileManager instanceof JavapFileManager)
((JavapFileManager) fileManager).setIgnoreSymbolFile(true);
if ((classes == null || classes.size() == 0) &&
!(options.help || options.version || options.fullVersion)) {
throw new BadArgs("err.no.classes.specified");
}
}
private void handleOption(String name, Iterator<String> rest) throws BadArgs {
for (Option o: recognizedOptions) {
if (o.matches(name)) {
if (o.hasArg) {
if (rest.hasNext())
o.process(this, name, rest.next());
else
throw new BadArgs("err.missing.arg", name).showUsage(true);
} else
o.process(this, name, null);
if (o.ignoreRest()) {
while (rest.hasNext())
rest.next();
}
return;
}
}
if (fileManager.handleOption(name, rest))
return;
throw new BadArgs("err.unknown.option", name).showUsage(true);
}
public Boolean call() {
return run();
}
public boolean run() {
if (options.help)
showHelp();
if (options.version || options.fullVersion)
showVersion(options.fullVersion);
if (classes == null || classes.size() == 0)
return true;
context.put(PrintWriter.class, log);
ClassWriter classWriter = ClassWriter.instance(context);
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;
}
}
Attribute.Factory attributeFactory = new Attribute.Factory();
attributeFactory.setCompat(options.compat);
attributeFactory.setJSR277(options.jsr277);
ClassFile cf = ClassFile.read(fo.openInputStream(), attributeFactory);
classWriter.write(cf);
} catch (ConstantPoolException e) {
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
ok = false;
} catch (EOFException e) {
diagnosticListener.report(createDiagnostic("err.end.of.file", className));
ok = false;
} catch (FileNotFoundException e) {
diagnosticListener.report(createDiagnostic("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));
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()));
}
}
return ok;
}
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
return JavapFileManager.create(dl, log, options);
}
private JavaFileObject getClassFileObject(String className) throws IOException {
JavaFileObject fo;
fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
if (fo == null)
fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
return fo;
}
private void showHelp() {
log.println(getMessage("main.usage", progname));
for (Option o: recognizedOptions) {
String name = o.aliases[0].substring(1); // there must always be at least one name
if (name.startsWith("X") || name.equals("fullversion") || name.equals("h") || name.equals("verify"))
continue;
log.println(getMessage("main.opt." + name));
}
String[] fmOptions = { "-classpath", "-bootclasspath" };
for (String o: fmOptions) {
if (fileManager.isSupportedOption(o) == -1)
continue;
String name = o.substring(1);
log.println(getMessage("main.opt." + name));
}
}
private void showVersion(boolean full) {
log.println(version(full ? "full" : "release"));
}
private static final String versionRBName = "com.sun.tools.javap.resources.version";
private static ResourceBundle versionRB;
private String version(String key) {
// key=version: mm.nn.oo[-milestone]
// key=full: mm.mm.oo[-milestone]-build
if (versionRB == null) {
try {
versionRB = ResourceBundle.getBundle(versionRBName);
} catch (MissingResourceException e) {
return getMessage("version.resource.missing", System.getProperty("java.version"));
}
}
try {
return versionRB.getString(key);
}
catch (MissingResourceException e) {
return getMessage("version.unknown", System.getProperty("java.version"));
}
}
private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
return new Diagnostic<JavaFileObject>() {
public Kind getKind() {
return Diagnostic.Kind.ERROR;
}
public JavaFileObject getSource() {
return null;
}
public long getPosition() {
return Diagnostic.NOPOS;
}
public long getStartPosition() {
return Diagnostic.NOPOS;
}
public long getEndPosition() {
return Diagnostic.NOPOS;
}
public long getLineNumber() {
return Diagnostic.NOPOS;
}
public long getColumnNumber() {
return Diagnostic.NOPOS;
}
public String getCode() {
return key;
}
public String getMessage(Locale locale) {
return JavapTask.this.getMessage(locale, key, args);
}
};
}
private String getMessage(String key, Object... args) {
return getMessage(task_locale, key, args);
}
private String getMessage(Locale locale, String key, Object... args) {
if (bundles == null) {
// could make this a HashMap<Locale,SoftReference<ResourceBundle>>
// and for efficiency, keep a hard reference to the bundle for the task
// locale
bundles = new HashMap<Locale, ResourceBundle>();
}
if (locale == null)
locale = Locale.getDefault();
ResourceBundle b = bundles.get(locale);
if (b == null) {
try {
b = ResourceBundle.getBundle("com.sun.tools.javap.resources.javap", locale);
bundles.put(locale, b);
} catch (MissingResourceException e) {
throw new InternalError("Cannot find javap resource bundle for locale " + locale);
}
}
try {
return MessageFormat.format(b.getString(key), args);
} catch (MissingResourceException e) {
throw new InternalError(e, key);
}
}
Context context;
JavaFileManager fileManager;
PrintWriter log;
DiagnosticListener<? super JavaFileObject> diagnosticListener;
List<String> classes;
Options options;
//ResourceBundle bundle;
Locale task_locale;
Map<Locale, ResourceBundle> bundles;
private static final String progname = "javap";
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javap;
import java.io.PrintWriter;
/**
* Main entry point.
*
* <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 Main {
/**
* Main entry point for the launcher.
* Note: This method calls System.exit.
* @param args command line arguments
*/
public static void main(String[] args) {
if (args.length >= 1 && args[0].equals("-Xold")) {
String[] nArgs = new String[args.length - 1];
System.arraycopy(args, 1, nArgs, 0, nArgs.length);
sun.tools.javap.Main.main(args); // calls System.exit
System.exit(1);
}
JavapTask t = new JavapTask();
int rc = t.run(args);
System.exit(rc);
}
/**
* Entry point that does <i>not</i> call System.exit.
* @param args command line arguments
* @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(String[] args, PrintWriter out) {
JavapTask t = new JavapTask();
t.setLog(out);
return t.run(args);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2007 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.AccessFlags;
/*
* Provides access to javap's options, set via the command line
* or JSR 199 API.
* <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 Options {
public static Options instance(Context context) {
Options instance = context.get(Options.class);
if (instance == null)
instance = new Options(context);
return instance;
}
protected Options(Context context) {
context.put(Options.class, this);
}
/**
* Checks access of class, field or method.
*/
public boolean checkAccess(AccessFlags flags){
boolean isPublic = flags.is(AccessFlags.ACC_PUBLIC);
boolean isProtected = flags.is(AccessFlags.ACC_PROTECTED);
boolean isPrivate = flags.is(AccessFlags.ACC_PRIVATE);
boolean isPackage = !(isPublic || isProtected || isPrivate);
if ((showAccess == AccessFlags.ACC_PUBLIC) && (isProtected || isPrivate || isPackage))
return false;
else if ((showAccess == AccessFlags.ACC_PROTECTED) && (isPrivate || isPackage))
return false;
else if ((showAccess == 0) && (isPrivate))
return false;
else
return true;
}
public boolean help;
public boolean verbose;
public boolean version;
public boolean fullVersion;
public boolean showFlags;
public boolean showLineAndLocalVariableTables;
public int showAccess;
public boolean showDisassembled;
public boolean showInternalSignatures;
public boolean showAllAttrs;
public boolean compat; // bug-for-bug compatibility mode with old javap
public boolean jsr277;
public boolean ignoreSymbolFile; // file manager should ignore ct.sym
}

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>javap: class file disassembler</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Javap is a class file disassembler.
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Classes to dump class files in text format.
</body>
</html>

View File

@ -0,0 +1,62 @@
err.prefix=Error:
err.bad.constant.pool=error while reading constant pool for {0}: {1}
err.class.not.found=class not found: {0}
err.crash=A serious internal error has occurred: {0}\nPlease file a bug report, and include the following information:\n{1}
err.end.of.file=unexpected end of file while reading {0}
err.file.not.found=file not found: {0}
err.h.not.supported=-h is no longer available - use the 'javah' program
err.internal.error=internal error: {0} {1} {2}
err.ioerror=IO error reading {0}: {1}
err.missing.arg=no value given for {0}
err.no.classes.specified=no classes specified
err.not.standard.file.manager=can only specify class files when using a standard file manager
err.unknown.option=unknown option: {0}
err.verify.not.supported=-verify not supported
err.Xold.not.supported.here=-Xold must be given as the first option
main.usage=\
Usage: {0} <options> <classes>\n\
where possible options include:
main.opt.help=\
\ -help --help -? Print this usage message
main.opt.version=\
\ -version Version information
main.opt.v=\
\ -v -verbose Print additional information
main.opt.l=\
\ -l Print line number and local variable tables
main.opt.public=\
\ -public Show only public classes and members
main.opt.protected=\
\ -protected Show protected/public classes and members
main.opt.package=\
\ -package Show package/protected/public classes\n\
\ and members (default)
main.opt.p=\
\ -p -private Show all classes and members
main.opt.c=\
\ -c Disassemble the code
main.opt.s=\
\ -s Print internal type signatures
main.opt.classpath=\
\ -classpath <path> Specify where to find user class files
main.opt.bootclasspath=\
\ -bootclasspath <path> Override location of bootstrap class files

View File

@ -0,0 +1,28 @@
#
# Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
jdk=$(JDK_VERSION)
full=$(FULL_VERSION)
release=$(RELEASE)

View File

@ -49,6 +49,12 @@ public class Main {
}
public static void main(String argv[]) {
// unless first arg is -Xold, use new javap
if (!(argv.length >= 1 && argv[0].equals("-Xold"))) {
com.sun.tools.javap.Main.main(argv);
return;
}
entry(argv);
if (errorOccurred) {
System.exit(1);
@ -178,6 +184,8 @@ public class Main {
}
} else if (arg.equals("-all")) {
env.showallAttr = true;
} else if (arg.equals("-Xold")) {
// ignore: this is old javap
} else {
error("invalid flag: " + arg);
usage();

View File

@ -0,0 +1,81 @@
/*
* 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.
*/
/*
* @test
* @bug 4870651
* @summary javap should recognize generics, varargs, enum
* @build T4870651 Test
* @run main T4870651
*/
import java.io.*;
public class T4870651 {
public static void main(String[] args) throws Exception {
new T4870651().run();
}
public void run() throws IOException {
verify("Test",
"class Test<T, E extends java.lang.Exception & java.lang.Comparable<T>, U extends java.lang.Comparable>",
"v1(java.lang.String...)");
verify("Test$Enum",
"flags: ACC_FINAL, ACC_SUPER, ACC_ENUM",
"flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM");
if (errors > 0)
throw new Error(errors + " found.");
}
String javap(String className) {
String testClasses = System.getProperty("test.classes", ".");
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
String[] args = { "-classpath", testClasses, "-v", className };
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
String output = sw.toString();
System.out.println("class " + className);
System.out.println(output);
return output;
}
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;
}

View File

@ -0,0 +1,76 @@
/*
* 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.util.*;
abstract class Test<T,E extends Exception & Comparable<T>,U extends Comparable> {
T t;
Test(T t) { }
<G> Test(G g, int i) { }
Test(String... args) { }
Test(int i, Object[]... args) { }
abstract void v1(String... args);
abstract void v2(int i, String[]... args);
abstract void a1(int x);
abstract void a2(int[] x);
abstract void a3(T x);
abstract void a4(T[] x);
abstract int r1();
abstract int[] r2();
abstract T r3();
abstract T[] r4();
abstract <G> void ga1(int x);
abstract <G> void ga2(int[] x);
abstract <G> void ga3(G x);
abstract <G> void ga4(G[] x);
abstract <G> int gr1();
abstract <G> int[] gr2();
abstract <G> G gr3();
abstract <G> G[] gr4();
abstract <G extends Exception> void ge() throws G;
abstract void w(List<?> l);
abstract void we(List<? extends T> l);
abstract void ws(List<? super T> l);
abstract void t1() throws Error;
abstract void t2() throws E;
abstract void t3() throws E,Error;
abstract void i1(Test<T, E, Comparable> x);
abstract void i3(Test<T, E, Comparable>.Inner<String> x);
class Inner<Q> { }
class Inner2<Q> extends Inner<Q> { }
class Simple { }
enum Enum { e1, e2, e3 }
}

View File

@ -0,0 +1,147 @@
/*
* 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.*;
/*
* @test
* @bug 6439940
* @summary Cleanup javap implementation
* @run main/othervm ListTest
*/
public class ListTest {
public static void main(String[] args) throws Exception {
new ListTest().run();
}
ListTest() {
String v = System.getProperty("view.cmd");
// v = "/opt/teamware/7.7/bin/filemerge -r";
if (v != null) {
viewResults = true;
viewCmd = Arrays.asList(v.split(" +"));
}
}
void run() throws Exception {
StandardLocation[] locs = new StandardLocation[] {
StandardLocation.PLATFORM_CLASS_PATH,
StandardLocation.CLASS_PATH,
};
int count = 0;
int pass = 0;
for (StandardLocation loc: locs) {
for (String testClassName: list(loc)) {
count++;
if (test(testClassName))
pass++;
}
}
if (pass < count)
throw new Error(pass + "/" + count + " test cases passed");
}
Iterable<String> list(StandardLocation loc) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sfm = compiler.getStandardFileManager(null, null, null);
Set<JavaFileObject.Kind> kinds = Collections.singleton(JavaFileObject.Kind.CLASS);
List<String> list = new ArrayList<String>();
for (JavaFileObject fo: sfm.list(loc, testPackage, kinds, true)) {
//System.err.println(com.sun.tools.javac.util.Old199.getPath(fo));
list.add(sfm.inferBinaryName(loc, fo));
}
return list;
}
boolean test(String testClassName) throws Exception {
String[] args = new String[options.size() + 1];
options.toArray(args);
args[args.length - 1] = testClassName;
String oldOut = runOldJavap(args);
String newOut = runNewJavap(args);
boolean ok = oldOut.equals(newOut);
System.err.println((ok ? "pass" : "FAIL") + ": " + testClassName);
if (!ok && viewResults)
view(oldOut, newOut);
return ok;
}
String runOldJavap(String[] args) {
//System.err.println("OLD: " + Arrays.asList(args));
PrintStream oldOut = System.out;
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try {
sun.tools.javap.Main.entry(args);
} finally {
System.setOut(oldOut);
}
return out.toString();
}
String runNewJavap(String[] args) {
String[] nArgs = new String[args.length + 2];
nArgs[0] = "-XDcompat";
nArgs[1] = "-XDignore.symbol.file";
System.arraycopy(args, 0, nArgs, 2, args.length);
//System.err.println("NEW: " + Arrays.asList(nArgs));
StringWriter out = new StringWriter();
com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true));
return out.toString();
}
File write(String text, String suffix) throws IOException {
File f = File.createTempFile("ListTest", suffix);
FileWriter out = new FileWriter(f);
out.write(text);
out.close();
return f;
}
void view(String oldOut, String newOut) throws Exception {
File oldFile = write(oldOut, "old");
File newFile = write(newOut, "new");
List<String> cmd = new ArrayList<String>();
cmd.addAll(viewCmd);
cmd.add(oldFile.getPath());
cmd.add(newFile.getPath());
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
p.getOutputStream().close();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
System.err.println(line);
in.close();
p.waitFor();
}
String testPackage = "java.lang";
List<String> options = Arrays.asList("-v");
boolean viewResults;
List<String> viewCmd;
}

View File

@ -0,0 +1,143 @@
/*
* Copyright 2007 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.*;
/*
* @test
* @bug 6439940
* @summary Cleanup javap implementation
* @run main/othervm OptionTest
*/
public class OptionTest {
public static void main(String[] args) throws Exception {
new OptionTest().run();
}
OptionTest() {
String v = System.getProperty("view.cmd");
if (v != null) {
viewResults = true;
viewCmd = Arrays.asList(v.split(" +"));
}
}
void run() throws Exception {
int count = 0;
int pass = 0;
// try combinations of options and compare old javap against new javap
for (int i = 0; i < (1<<8); i++) {
List<String> options = new ArrayList<String>();
if ((i & 0x01) != 0)
options.add("-c");
if ((i & 0x02) != 0)
options.add("-l");
if ((i & 0x04) != 0)
options.add("-public");
if ((i & 0x08) != 0)
options.add("-protected");
if ((i & 0x10) != 0)
options.add("-package");
if ((i & 0x20) != 0)
options.add("-private");
if ((i & 0x40) != 0)
options.add("-s");
if ((i & 0x80) != 0)
options.add("-verbose");
count++;
if (test(options))
pass++;
}
if (pass < count)
throw new Error(pass + "/" + count + " test cases passed");
}
boolean test(List<String> options) throws Exception {
String[] args = new String[options.size() + 1];
options.toArray(args);
args[args.length - 1] = testClassName;
String oldOut = runOldJavap(args);
String newOut = runNewJavap(args);
boolean ok = oldOut.equals(newOut);
System.err.println((ok ? "pass" : "FAIL") + ": " + options);
if (!ok && viewResults)
view(oldOut, newOut);
return ok;
}
String runOldJavap(String[] args) {
//System.err.println("OLD: " + Arrays.asList(args));
PrintStream oldOut = System.out;
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
try {
sun.tools.javap.Main.entry(args);
} finally {
System.setOut(oldOut);
}
return out.toString();
}
String runNewJavap(String[] args) {
String[] nArgs = new String[args.length + 2];
nArgs[0] = "-XDcompat";
nArgs[1] = "-XDignore.symbol.file";
System.arraycopy(args, 0, nArgs, 2, args.length);
//System.err.println("NEW: " + Arrays.asList(nArgs));
StringWriter out = new StringWriter();
com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true));
return out.toString();
}
File write(String text, String suffix) throws IOException {
File f = File.createTempFile("OptionTest", suffix);
FileWriter out = new FileWriter(f);
out.write(text);
out.close();
return f;
}
void view(String oldOut, String newOut) throws Exception {
File oldFile = write(oldOut, "old");
File newFile = write(newOut, "new");
List<String> cmd = new ArrayList<String>();
cmd.addAll(viewCmd);
cmd.add(oldFile.getPath());
cmd.add(newFile.getPath());
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
p.getOutputStream().close();
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null)
System.err.println(line);
in.close();
p.waitFor();
}
String testClassName = "java.lang.SecurityManager";
boolean viewResults;
List<String> viewCmd;
}

View File

@ -0,0 +1,73 @@
/*
* 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.
*/
/*
* @test
* @bug 4075403
* @summary Use javap to inquire about a specific inner class
*/
import java.io.*;
public class T4075403 {
public static void main(String[] args) throws Exception {
new T4075403().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
javap("Outer.Inner");
}
File writeTestFile() throws IOException {
File f = new File("Outer.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class Outer { ");
out.println(" class Inner { }");
out.println("}");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", 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");
}
String javap(String className) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-classpath", ".", className }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
System.out.println(sw.toString());
return sw.toString();
}
}

View File

@ -0,0 +1,112 @@
/*
* 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.
*/
/*
* @test
* @bug 4459541
* @summary "javap -l" shows line numbers as signed short; they should be unsigned.
*/
import java.io.*;
public class T4459541 {
public static void main(String[] args) throws Exception {
new T4459541().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
String output = javap(classFile);
verify(output);
}
File writeTestFile() throws IOException {
File f = new File("Test.java");
out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
println("class Test {");
println("void begin(int i) {");
println("i++;");
println("i++;");
println("}");
while (line < 32750)
println("// " + line);
println("void before_32767(int i) {");
println("i++;");
println("i++;");
println("}");
while (line < 32768-4)
println("// " + line);
println("void straddle_32768(int i) {");
while (line < 32768+4)
println("i++;");
println("}");
while (line < 65520)
println("// " + line);
println("void between_32768_and_65536(int i) {");
println("i++;");
println("i++;");
println("}");
while (line < 65536-4)
println("// " + line);
println("void straddle_65536(int i) {");
while (line < 65536+4)
println("i++;");
println("}");
println("}");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { 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");
}
String javap(File f) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-l", f.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
void verify(String output) {
System.out.println(output);
if (output.indexOf("-") >= 0)
throw new Error("- found in output");
}
void println(String text) {
out.println(text);
line++;
}
PrintWriter out;
int line = 1;
}

View File

@ -0,0 +1,76 @@
/*
* 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.
*/
/*
* @test
* @bug 4501660
* @summary change diagnostic of -help as 'print this help message and exit'
* (actually, verify -help does not cause premature exit)
*/
import java.io.*;
import java.util.zip.*;
public class T4501660 {
public static void main(String[] args) throws Exception {
new T4501660().run();
}
public void run() throws IOException {
String testClasses = System.getProperty("test.classes", ".");
String output = javap("-classpath", testClasses, "-help", "T4501660");
verify(output,
"-public", "-protected", "-private", // check -help output is present
"class T4501660" // check class output is present
);
if (errors > 0)
throw new Error(errors + " found.");
}
String javap(String... args) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
//sun.tools.javap.Main.entry(args);
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
System.out.println(sw);
return sw.toString();
}
void verify(String output, String... expects) {
for (String expect: expects) {
if (output.indexOf(expect)< 0)
error(expect + " not found");
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

View File

@ -0,0 +1,70 @@
/*
* 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.
*/
/*
* @test
* @bug 4876942
* @summary javap invoked without args does not print help screen
*/
import java.io.*;
import java.util.zip.*;
public class T4876942 {
public static void main(String[] args) throws Exception {
new T4876942().run();
}
public void run() throws IOException {
String output = javap();
verify(output, "-public", "-protected", "-private"); // check that some of the options are listed
if (errors > 0)
throw new Error(errors + " found.");
}
String javap(String... args) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
//sun.tools.javap.Main.entry(args);
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
void verify(String output, String... expects) {
for (String expect: expects) {
if (output.indexOf(expect)< 0)
error(expect + " not found");
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

View File

@ -0,0 +1,88 @@
/*
* 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.
*/
/*
* @test
* @bug 4880663
* @summary javap could output whitespace between class name and opening brace
*/
import java.io.*;
public class T4880663 {
public static void main(String[] args) throws Exception {
new T4880663().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
verify(classFile, "class Test {");
if (errors > 0)
throw new Error(errors + " found.");
}
File writeTestFile() throws IOException {
File f = new File("Test.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class Test { }");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", 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");
}
String javap(File classFile) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { classFile.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
System.out.println(sw.toString());
return sw.toString();
}
void verify(File classFile, String... expects) {
String output = javap(classFile);
for (String expect: expects) {
if (output.indexOf(expect)< 0)
error(expect + " not found");
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

View File

@ -0,0 +1,94 @@
/*
* 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.
*/
/*
* @test
* @bug 4975569 6622215
* @summary javap doesn't print new flag bits
*/
import java.io.*;
import java.util.*;
public class T4975569
{
public static void main(String... args) {
new T4975569().run();
}
void run() {
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");
verify("T4975569$V", "void m(java.lang.String...)",
"flags: ACC_VARARGS");
verify("T4975569$Prot", "InnerClasses: \n protected");
//verify("T4975569$Priv", "InnerClasses");
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 = { "-v", "-classpath", testClasses, className };
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
String output = sw.toString();
System.out.println("class " + className);
System.out.println(output);
return output;
}
List x() { return null; };
class V { void m(String... args) { } }
enum E { e; }
@interface Anno { }
static class S extends T4975569 {
ArrayList x() { return null; }
}
protected class Prot { }
//private class Priv { int i; }
}

View File

@ -0,0 +1,90 @@
/*
* 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.
*/
/*
* @test
* @bug 6271787
* @summary javap dumps LocalVariableTypeTable attribute in hex, needs to print a table
*/
import java.io.*;
public class T6271787 {
public static void main(String[] args) throws Exception {
new T6271787().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
verify(classFile,
"LocalVariableTypeTable:",
"0 5 0 this LTest<TT;>;" // should consider decoding this in javap
);
if (errors > 0)
throw new Error(errors + " found.");
}
File writeTestFile() throws IOException {
File f = new File("Test.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class Test<T> { }");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", 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");
}
String javap(File f) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
void verify(File classFile, String... expects) {
String output = javap(classFile);
for (String expect: expects) {
if (output.indexOf(expect)< 0)
error(expect + " not found");
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

View File

View File

@ -0,0 +1,95 @@
/*
* 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.
*/
/*
* @test
* @bug 6474890
* @summary javap does not open .zip files in -classpath
*/
import java.io.*;
import java.util.zip.*;
public class T6474890 {
public static void main(String[] args) throws Exception {
new T6474890().run();
}
public void run() throws IOException {
File classDir = new File("classes");
classDir.mkdir();
String className = "Test";
File javaFile = writeTestFile(className);
compileTestFile(classDir, javaFile);
File zipFile = zip(classDir, new File(classDir + ".zip"));
javap("-classpath", zipFile.getPath(), className);
File jarFile = zip(classDir, new File(classDir + ".jar"));
javap("-classpath", zipFile.getPath(), className);
}
File writeTestFile(String name) throws IOException {
File f = new File(name + ".java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class " + name + " { }");
out.close();
return f;
}
void compileTestFile(File classDir, File file) {
int rc = com.sun.tools.javac.Main.compile(
new String[] { "-d", classDir.getPath(), file.getPath() });
if (rc != 0)
throw new Error("compilation failed. rc=" + rc);
}
File zip(File dir, File zipFile) throws IOException {
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
for (File file: dir.listFiles()) {
if (file.isFile()) {
byte[] data = new byte[(int) file.length()];
DataInputStream in = new DataInputStream(new FileInputStream(file));
in.readFully(data);
in.close();
zipOut.putNextEntry(new ZipEntry(file.getName()));
zipOut.write(data, 0, data.length);
zipOut.closeEntry();
}
}
zipOut.close();
return zipFile;
}
String javap(String... args) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
//sun.tools.javap.Main.entry(args);
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
/*
* @test
* @bug 6587786
* @summary Javap throws error : "ERROR:Could not find <classname>" for JRE classes
*/
import java.io.*;
public class T6587786 {
public static void main(String[] args) throws Exception {
new T6587786().run();
}
public void run() throws IOException {
javap("com.sun.javadoc.Doc", "com.sun.crypto.provider.ai");
javap("com.sun.crypto.provider.ai", "com.sun.javadoc.ClassDoc");
}
void javap(String... args) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
//sun.tools.javap.Main.entry(args);
int rc = com.sun.tools.javap.Main.run(args, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
System.out.println(sw.toString());
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.
*/
/*
* @test
* @bug 6622216
* @summary javap names some attributes incorrectly
*/
import java.io.*;
public class T6622216 {
public static void main(String[] args) throws Exception {
new T6622216().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
String output = javap(classFile);
verify(output);
}
File writeTestFile() throws IOException {
File f = new File("Outer.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class Outer {");
out.println(" class Inner { }");
out.println("}");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { 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");
}
String javap(File f) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
void verify(String output) {
System.out.println(output);
if (output.indexOf("InnerClasses") == -1)
throw new Error("InnerClasses not found in output");
}
}

View File

@ -0,0 +1,97 @@
/*
* 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.
*/
/*
* @test
* @bug 6622232
* @summary javap gets whitespace confused
*/
import java.io.*;
public class T6622232 {
public static void main(String[] args) throws Exception {
new T6622232().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
String output = javap(classFile);
// these are all examples of bad whitespace from old javap
verifyNot(output,
"\\Q Constant value: int 3Deprecated: true\\E",
"^Deprecated: true",
"\\Q throws java.lang.Exception, java.lang.Error Deprecated: true\\E"
);
if (errors > 0)
throw new Error(errors + " found.");
}
File writeTestFile() throws IOException {
File f = new File("Test.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("class Test { ");
out.println(" @Deprecated static final int f1 = 3;");
out.println(" @Deprecated int f2;");
out.println(" @Deprecated void m() throws Exception, Error { }");
out.println("}");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", 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");
}
String javap(File f) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
System.out.println(sw.toString());
return sw.toString();
}
void verifyNot(String output, String... unexpects) {
for (String unexpect: unexpects) {
if (output.matches(unexpect))
error(unexpect + " unexpectedly found");
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

View File

@ -0,0 +1,197 @@
/*
* 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.
*/
/*
* @test
* @bug 6622260
* @summary javap prints negative bytes incorrectly in hex
*/
import java.io.*;
public class T6622260 {
public static void main(String[] args) throws Exception {
new T6622260().run();
}
public void run() throws IOException {
File javaFile = writeTestFile();
File classFile = compileTestFile(javaFile);
modifyClassFile(classFile);
String output = javap(classFile);
verify(output);
}
File writeTestFile() throws IOException {
File f = new File("Test.java");
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
out.println("@Deprecated class Test { int f; void m() { } }");
out.close();
return f;
}
File compileTestFile(File f) {
int rc = com.sun.tools.javac.Main.compile(new String[] { 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");
}
void modifyClassFile(File f) throws IOException {
String newAttributeName = "NonstandardAttribute";
byte[] newAttributeData = { 0, 1, 2, 127, (byte)128, (byte)129, (byte)254, (byte)255 };
DataInputStream in = new DataInputStream(new FileInputStream(f));
byte[] data = new byte[(int) f.length()];
in.readFully(data);
in.close();
in = new DataInputStream(new ByteArrayInputStream(data));
in.skipBytes(4); // magic
in.skipBytes(2); // minor
in.skipBytes(2); // minor
int constantPoolPos = data.length - in.available();
int constant_pool_count = skipConstantPool(in);
int flagsPos = data.length - in.available();
in.skipBytes(2); // access_flags
in.skipBytes(2); // this_class
in.skipBytes(2); // super_class
int interfaces_count = in.readUnsignedShort();
in.skipBytes(interfaces_count * 2);
int field_count = in.readUnsignedShort();
for (int i = 0; i < field_count; i++) {
in.skipBytes(6); // access_flags, name_index, descriptor_index
skipAttributes(in);
}
int method_count = in.readUnsignedShort();
for (int i = 0; i < method_count; i++) {
in.skipBytes(6); // access_flags, name_index, descriptor_index
skipAttributes(in);
}
int classAttributesPos = data.length - in.available();
int attributes_count = in.readUnsignedShort();
f.renameTo(new File(f.getPath() + ".BAK"));
DataOutputStream out = new DataOutputStream(new FileOutputStream(f));
// copy head
out.write(data, 0, constantPoolPos);
// copy constant pool, adding in name of new attribute
out.writeShort(constant_pool_count + 1);
out.write(data, constantPoolPos + 2, flagsPos - constantPoolPos - 2);
out.write(1); // CONSTANT_Utf8
out.writeUTF(newAttributeName);
// copy flags, class, superclass, interfaces, fields and methods
out.write(data, flagsPos, classAttributesPos - flagsPos);
// copy class attributes, adding in new attribute
out.writeShort(attributes_count + 1);
out.write(data, classAttributesPos + 2, data.length - classAttributesPos - 2);
out.writeShort(constant_pool_count); // index of new attribute name
out.writeInt(newAttributeData.length);
out.write(newAttributeData);
out.close();
}
int skipConstantPool(DataInputStream in) throws IOException {
int constant_pool_count = in.readUnsignedShort();
for (int i = 1; i < constant_pool_count; i++) {
int tag = in.readUnsignedByte();
switch (tag) {
case 1: // CONSTANT_Utf8
int length = in.readUnsignedShort();
in.skipBytes(length); // bytes
break;
case 3: // CONSTANT_Integer
case 4: // CONSTANT_Float
in.skipBytes(4); // bytes
break;
case 5: // CONSTANT_Long
case 6: // CONSTANT_Double
in.skipBytes(8); // high_bytes, low_bytes
break;
case 7: // CONSTANT_Class
in.skipBytes(2); // name_index
break;
case 8: // CONSTANT_String
in.skipBytes(2); // string_index
break;
case 9: // CONSTANT_FieldRef
case 10: // CONSTANT_Methodref
case 11: // CONSTANT_InterfaceMethodref
in.skipBytes(4); // class_index, name_and_type_index
break;
case 12: // CONSTANT_NameAndType
in.skipBytes(4); // name_index, descriptor_index
break;
default:
throw new Error("constant pool tag: " + tag);
}
}
return constant_pool_count;
}
int skipAttributes(DataInputStream in) throws IOException {
int attributes_count = in.readUnsignedShort();
for (int i = 0; i < attributes_count; i++) {
in.skipBytes(2); // attribute_name_index;
int length = in.readInt();
in.skipBytes(length); // info
}
return attributes_count;
}
String javap(File f) {
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
if (rc != 0)
throw new Error("javap failed. rc=" + rc);
out.close();
return sw.toString();
}
void verify(String output) {
System.out.println(output);
if (output.indexOf("-") >= 0)
throw new Error("- found in output");
if (output.indexOf("FFFFFF") >= 0)
throw new Error("FFFFFF found in output");
}
}