Merge
This commit is contained in:
commit
b88afe3210
langtools
make
src/share/classes
com/sun/tools
apt/main
classfile
javac
code
file
jvm
main
processing
resources
util
javap
sun/tools/javap
test
com/sun/javadoc
testIndex
testInterface
testNavagation
testTagInheritence
tools/javac
5005368.java
6304921
6341866
6464451
6491592
Ambig3.javaArrayCast.javaBadCovar.javaClassLit.javaClassLiterals
ClassToTypeParm.javaClosure1.javaClosure2.javaClosure3.javaClosure4.javaClosure5.javaCompoundBox.javaConditionalArgTypes_1.javaConditionalArgTypes_2.javaDefiniteAssignment
Diagnostics/6722234
T6722234a.javaT6722234a_1.outT6722234a_2.outT6722234b.javaT6722234b_1.outT6722234b_2.outT6722234c.javaT6722234c.outT6722234d.javaT6722234d_1.outT6722234d_2.out
EarlyAssert.javaEnum1.javaExtendArray.javaExtendArray.outGoodCovar.javaHexFloatLiterals.javaHexThree.javaInterfaceAssert.javaInvalidIntfCast.javaNewGeneric.java@ -120,6 +120,14 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef SOURCE_LANGUAGE_VERSION
|
||||
ANT_OPTIONS += -Djavac.source=$(SOURCE_LANGUAGE_VERSION)
|
||||
else
|
||||
ifdef JAVAC_SOURCE_ARG
|
||||
ANT_OPTIONS += -Djavac.source=$(JAVAC_SOURCE_ARG)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef ALT_BOOTDIR
|
||||
ANT_OPTIONS += -Dboot.java.home=$(ALT_BOOTDIR)
|
||||
ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR)
|
||||
|
@ -32,7 +32,8 @@
|
||||
# boot.java.home = /opt/jdk/1.5.0
|
||||
boot.java = ${boot.java.home}/bin/java
|
||||
boot.javac = ${boot.java.home}/bin/javac
|
||||
boot.javac.target = 5
|
||||
boot.javac.source = 6
|
||||
boot.javac.target = 6
|
||||
|
||||
# This is the JDK used to run the product version of the tools,
|
||||
# for example, for testing. If you're building a complete JDK, specify that.
|
||||
@ -59,7 +60,8 @@ full.version = ${release}-${build.number}
|
||||
bootstrap.full.version = ${bootstrap.release}-${build.number}
|
||||
|
||||
# options for the <javac> tasks used to compile the tools
|
||||
javac.target = 6
|
||||
javac.source = 5
|
||||
javac.target = 5
|
||||
javac.debug = true
|
||||
javac.debuglevel = source,lines
|
||||
javac.no.jdk.warnings = -XDignore.symbol.file=true
|
||||
|
@ -315,7 +315,7 @@
|
||||
<target name="build-javap" depends="build-javac">
|
||||
<build-tool name="javap"
|
||||
includes="${javap.includes}"
|
||||
jarmainclass="sun.tools.javap.Main"
|
||||
jarmainclass="com.sun.tools.javap.Main"
|
||||
jarclasspath="javac.jar"/>
|
||||
</target>
|
||||
|
||||
@ -400,6 +400,7 @@
|
||||
<attribute name="java" default="java"/>
|
||||
<attribute name="javac.bootclasspath" default="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
|
||||
<attribute name="javac.java.home" default="${boot.java.home}"/>
|
||||
<attribute name="javac.source" default="${javac.source}"/>
|
||||
<attribute name="javac.target" default="${javac.target}"/>
|
||||
<attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
|
||||
<attribute name="jarclasspath" default=""/>
|
||||
@ -418,6 +419,7 @@
|
||||
release="@{release}"
|
||||
full.version="@{full.version}"
|
||||
javac.bootclasspath="@{javac.bootclasspath}"
|
||||
javac.source="@{javac.source}"
|
||||
javac.target="@{javac.target}"
|
||||
/>
|
||||
<mkdir dir="@{bin.dir}"/>
|
||||
@ -442,6 +444,7 @@
|
||||
<attribute name="lib.dir" default="${dist.lib.dir}"/>
|
||||
<attribute name="javac.bootclasspath" default="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
|
||||
<attribute name="javac.java.home" default="${boot.java.home}"/>
|
||||
<attribute name="javac.source" default="${javac.source}"/>
|
||||
<attribute name="javac.target" default="${javac.target}"/>
|
||||
<attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
|
||||
<attribute name="jarclasspath" default=""/>
|
||||
@ -457,6 +460,7 @@
|
||||
release="@{release}"
|
||||
full.version="@{full.version}"
|
||||
javac.bootclasspath="@{javac.bootclasspath}"
|
||||
javac.source="@{javac.source}"
|
||||
javac.target="@{javac.target}"
|
||||
/>
|
||||
<mkdir dir="@{lib.dir}"/>
|
||||
@ -481,6 +485,7 @@
|
||||
<attribute name="gensrc.dir" default="${build.gensrc.dir}"/>
|
||||
<attribute name="javac.bootclasspath" default="${build.bootstrap.dir}/classes"/>
|
||||
<attribute name="javac.java.home" default="${boot.java.home}"/>
|
||||
<attribute name="javac.source" default="${javac.source}"/>
|
||||
<attribute name="javac.target" default="${javac.target}"/>
|
||||
<attribute name="release" default="${release}"/>
|
||||
<attribute name="full.version" default="${full.version}"/>
|
||||
@ -509,6 +514,7 @@
|
||||
includes="@{includes}"
|
||||
sourcepath=""
|
||||
includeAntRuntime="no"
|
||||
source="@{javac.source}"
|
||||
target="@{javac.target}">
|
||||
<compilerarg value="-J-Xbootclasspath/p:@{javac.bootclasspath}"/>
|
||||
<compilerarg line="${javac.version.opt}"/>
|
||||
@ -522,6 +528,7 @@
|
||||
excludes="@{excludes}"
|
||||
sourcepath=""
|
||||
includeAntRuntime="no"
|
||||
source="@{javac.source}"
|
||||
target="@{javac.target}"
|
||||
debug="${javac.debug}"
|
||||
debuglevel="${javac.debuglevel}">
|
||||
@ -547,6 +554,7 @@
|
||||
<target name="-def-build-bootstrap-tool" depends="-check-boot.java.home,-def-build-tool">
|
||||
<presetdef name="build-bootstrap-tool">
|
||||
<build-tool
|
||||
javac.source="${boot.javac.source}"
|
||||
javac.target="${boot.javac.target}"
|
||||
gensrc.dir="${build.bootstrap.dir}/gensrc"
|
||||
classes.dir="${build.bootstrap.dir}/classes"
|
||||
@ -562,6 +570,7 @@
|
||||
<target name="-def-build-bootstrap-jar" depends="-def-build-jar">
|
||||
<presetdef name="build-bootstrap-jar">
|
||||
<build-jar
|
||||
javac.source="${boot.javac.source}"
|
||||
javac.target="${boot.javac.target}"
|
||||
gensrc.dir="${build.bootstrap.dir}/gensrc"
|
||||
classes.dir="${build.bootstrap.dir}/classes"
|
||||
|
@ -26,7 +26,6 @@
|
||||
package com.sun.tools.apt.main;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
@ -37,14 +36,15 @@ import java.util.StringTokenizer;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URL;
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import com.sun.tools.javac.file.Paths;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
@ -766,6 +766,7 @@ public class Main {
|
||||
providedFactory = factory;
|
||||
|
||||
Context context = new Context();
|
||||
JavacFileManager.preRegister(context);
|
||||
options = Options.instance(context);
|
||||
Bark bark;
|
||||
|
||||
@ -862,14 +863,14 @@ public class Main {
|
||||
}
|
||||
origOptions = Collections.unmodifiableMap(origOptions);
|
||||
|
||||
JavacFileManager fm = (JavacFileManager) context.get(JavaFileManager.class);
|
||||
{
|
||||
// Note: it might be necessary to check for an empty
|
||||
// component ("") of the source path or class path
|
||||
Paths paths = Paths.instance(context);
|
||||
|
||||
String sourceDest = options.get("-s");
|
||||
if (paths.sourcePath() != null) {
|
||||
for(File f: paths.sourcePath())
|
||||
if (fm.hasLocation(StandardLocation.SOURCE_PATH)) {
|
||||
for(File f: fm.getLocation(StandardLocation.SOURCE_PATH))
|
||||
augmentedSourcePath += (f + File.pathSeparator);
|
||||
augmentedSourcePath += (sourceDest == null)?".":sourceDest;
|
||||
} else {
|
||||
@ -880,8 +881,8 @@ public class Main {
|
||||
}
|
||||
|
||||
String classDest = options.get("-d");
|
||||
if (paths.userClassPath() != null) {
|
||||
for(File f: paths.userClassPath())
|
||||
if (fm.hasLocation(StandardLocation.CLASS_PATH)) {
|
||||
for(File f: fm.getLocation(StandardLocation.CLASS_PATH))
|
||||
baseClassPath += (f + File.pathSeparator);
|
||||
// put baseClassPath into map to handle any
|
||||
// value needed for the classloader
|
||||
@ -908,9 +909,8 @@ public class Main {
|
||||
* uses.
|
||||
*/
|
||||
String aptclasspath = "";
|
||||
Paths paths = Paths.instance(context);
|
||||
String bcp = "";
|
||||
Collection<File> bootclasspath = paths.bootClassPath();
|
||||
Iterable<? extends File> bootclasspath = fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
|
||||
|
||||
if (bootclasspath != null) {
|
||||
for(File f: bootclasspath)
|
||||
|
@ -95,7 +95,7 @@ public class ClassTranslator
|
||||
if (cp2 == null) {
|
||||
ConstantPool.CPInfo[] pool2 = new ConstantPool.CPInfo[cp.size()];
|
||||
boolean eq = true;
|
||||
for (int i = 0; i < cp.size(); i++) {
|
||||
for (int i = 0; i < cp.size(); ) {
|
||||
ConstantPool.CPInfo cpInfo;
|
||||
try {
|
||||
cpInfo = cp.get(i);
|
||||
@ -107,11 +107,7 @@ public class ClassTranslator
|
||||
pool2[i] = cpInfo2;
|
||||
if (cpInfo.getTag() != cpInfo2.getTag())
|
||||
throw new IllegalStateException();
|
||||
switch (cpInfo.getTag()) {
|
||||
case ConstantPool.CONSTANT_Double:
|
||||
case ConstantPool.CONSTANT_Long:
|
||||
i += 1;
|
||||
}
|
||||
i += cpInfo.size();
|
||||
}
|
||||
|
||||
if (eq)
|
||||
|
@ -118,13 +118,8 @@ public class ClassWriter {
|
||||
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); // ??
|
||||
}
|
||||
for (CPInfo cpInfo: pool.entries())
|
||||
constantPoolWriter.write(cpInfo, out);
|
||||
}
|
||||
|
||||
protected void writeFields() throws IOException {
|
||||
|
@ -26,6 +26,7 @@
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.5.
|
||||
@ -223,6 +224,40 @@ public class ConstantPool {
|
||||
throw new EntryNotFound(value);
|
||||
}
|
||||
|
||||
public Iterable<CPInfo> entries() {
|
||||
return new Iterable<CPInfo>() {
|
||||
public Iterator<CPInfo> iterator() {
|
||||
return new Iterator<CPInfo>() {
|
||||
|
||||
public boolean hasNext() {
|
||||
return next < pool.length;
|
||||
}
|
||||
|
||||
public CPInfo next() {
|
||||
current = pool[next];
|
||||
switch (current.getTag()) {
|
||||
case CONSTANT_Double:
|
||||
case CONSTANT_Long:
|
||||
next += 2;
|
||||
break;
|
||||
default:
|
||||
next += 1;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private CPInfo current;
|
||||
private int next = 1;
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private CPInfo[] pool;
|
||||
|
||||
public interface Visitor<R,P> {
|
||||
@ -250,6 +285,12 @@ public class ConstantPool {
|
||||
|
||||
public abstract int getTag();
|
||||
|
||||
/** The number of slots in the constant pool used by this entry.
|
||||
* 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
|
||||
public int size() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
protected final ConstantPool cp;
|
||||
@ -310,6 +351,20 @@ public class ConstantPool {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
public String getBaseName() throws ConstantPoolException {
|
||||
String name = getName();
|
||||
int index = name.indexOf("[L") + 1;
|
||||
return name.substring(index);
|
||||
}
|
||||
|
||||
public int getDimensionCount() throws ConstantPoolException {
|
||||
String name = getName();
|
||||
int count = 0;
|
||||
while (name.charAt(count) == '[')
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Class_info[name_index: " + name_index + "]";
|
||||
@ -335,6 +390,11 @@ public class ConstantPool {
|
||||
return CONSTANT_Double;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Double_info[value: " + value + "]";
|
||||
@ -448,6 +508,11 @@ public class ConstantPool {
|
||||
return CONSTANT_Long;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Long_info[value: " + value + "]";
|
||||
|
@ -107,6 +107,8 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public abstract int getOffsetDelta();
|
||||
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
public final int frame_type;
|
||||
@ -130,6 +132,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_same_frame(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return frame_type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class same_locals_1_stack_item_frame extends stack_map_frame {
|
||||
@ -149,6 +155,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_same_locals_1_stack_item_frame(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return frame_type - 64;
|
||||
}
|
||||
|
||||
public final verification_type_info[] stack;
|
||||
}
|
||||
|
||||
@ -170,6 +180,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_same_locals_1_stack_item_frame_extended(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return offset_delta;
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final verification_type_info[] stack;
|
||||
}
|
||||
@ -189,6 +203,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_chop_frame(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return offset_delta;
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
}
|
||||
|
||||
@ -207,6 +225,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_same_frame_extended(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return offset_delta;
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
}
|
||||
|
||||
@ -232,6 +254,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_append_frame(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return offset_delta;
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final verification_type_info[] locals;
|
||||
}
|
||||
@ -266,6 +292,10 @@ public class StackMapTable_attribute extends Attribute {
|
||||
return visitor.visit_full_frame(this, data);
|
||||
}
|
||||
|
||||
public int getOffsetDelta() {
|
||||
return offset_delta;
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final int number_of_locals;
|
||||
public final verification_type_info[] locals;
|
||||
@ -308,7 +338,7 @@ public class StackMapTable_attribute extends Attribute {
|
||||
}
|
||||
}
|
||||
|
||||
verification_type_info(int tag) {
|
||||
protected verification_type_info(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,10 @@
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
@ -33,8 +36,9 @@ import java.util.List;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Type {
|
||||
public abstract class Type {
|
||||
protected Type() { }
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
|
||||
sb.append(prefix);
|
||||
@ -52,11 +56,33 @@ public class Type {
|
||||
append(sb, prefix, types, suffix);
|
||||
}
|
||||
|
||||
public interface Visitor<R,P> {
|
||||
R visitSimpleType(SimpleType type, P p);
|
||||
R visitArrayType(ArrayType type, P p);
|
||||
R visitMethodType(MethodType type, P p);
|
||||
R visitClassSigType(ClassSigType type, P p);
|
||||
R visitClassType(ClassType type, P p);
|
||||
R visitInnerClassType(InnerClassType type, P p);
|
||||
R visitTypeArgType(TypeArgType type, P p);
|
||||
R visitWildcardType(WildcardType type, P p);
|
||||
}
|
||||
|
||||
public static class SimpleType extends Type {
|
||||
public SimpleType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitSimpleType(this, data);
|
||||
}
|
||||
|
||||
public boolean isPrimitiveType() {
|
||||
return primitiveTypes.contains(name);
|
||||
}
|
||||
// where
|
||||
private static final Set<String> primitiveTypes = new HashSet<String>(Arrays.asList(
|
||||
"boolean", "byte", "char", "double", "float", "int", "long", "short", "void"));
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
@ -70,6 +96,10 @@ public class Type {
|
||||
this.elemType = elemType;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitArrayType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return elemType + "[]";
|
||||
@ -93,6 +123,10 @@ public class Type {
|
||||
this.throwsTypes = throwsTypes;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitMethodType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -116,6 +150,10 @@ public class Type {
|
||||
this.superinterfaceTypes = superinterfaceTypes;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitClassSigType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -139,6 +177,10 @@ public class Type {
|
||||
this.typeArgs = typeArgs;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitClassType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -158,6 +200,10 @@ public class Type {
|
||||
this.innerType = innerType;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitInnerClassType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return outerType + "." + innerType;
|
||||
@ -174,6 +220,10 @@ public class Type {
|
||||
this.interfaceBounds = interfaceBounds;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitTypeArgType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -209,6 +259,10 @@ public class Type {
|
||||
this.boundType = boundType;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitWildcardType(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (kind == null)
|
||||
|
@ -43,6 +43,9 @@ import static com.sun.tools.javac.code.Flags.*;
|
||||
*/
|
||||
public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Visitor<String, Locale> {
|
||||
|
||||
List<Type> seenCaptured = List.nil();
|
||||
static final int PRIME = 997; // largest prime less than 1000
|
||||
|
||||
/**
|
||||
* This method should be overriden in order to provide proper i18n support.
|
||||
*
|
||||
@ -54,7 +57,18 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
protected abstract String localize(Locale locale, String key, Object... args);
|
||||
|
||||
/**
|
||||
* Create a printer with default i18n support provided my Messages.
|
||||
* Maps a captured type into an unique identifier.
|
||||
*
|
||||
* @param t the captured type for which an id is to be retrieved
|
||||
* @param locale locale settings
|
||||
* @return unique id representing this captured type
|
||||
*/
|
||||
protected abstract String capturedVarId(CapturedType t, Locale locale);
|
||||
|
||||
/**
|
||||
* Create a printer with default i18n support provided by Messages. By default,
|
||||
* captured types ids are generated using hashcode.
|
||||
*
|
||||
* @param messages Messages class to be used for i18n
|
||||
* @return printer visitor instance
|
||||
*/
|
||||
@ -63,6 +77,11 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
@Override
|
||||
protected String localize(Locale locale, String key, Object... args) {
|
||||
return messages.getLocalizedString(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String capturedVarId(CapturedType t, Locale locale) {
|
||||
return (t.hashCode() & 0xFFFFFFFFL) % PRIME + "";
|
||||
}};
|
||||
}
|
||||
|
||||
@ -120,9 +139,20 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
return localize(locale, "compiler.misc.type.captureof",
|
||||
(t.hashCode() & 0xFFFFFFFFL) % Type.CapturedType.PRIME,
|
||||
visit(t.wildcard, locale));
|
||||
if (seenCaptured.contains(t))
|
||||
return localize(locale, "compiler.misc.type.captureof.1",
|
||||
capturedVarId(t, locale));
|
||||
else {
|
||||
try {
|
||||
seenCaptured = seenCaptured.prepend(t);
|
||||
return localize(locale, "compiler.misc.type.captureof",
|
||||
capturedVarId(t, locale),
|
||||
visit(t.wildcard, locale));
|
||||
}
|
||||
finally {
|
||||
seenCaptured = seenCaptured.tail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,7 +95,7 @@ public enum Source {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static final Source DEFAULT = JDK1_5;
|
||||
public static final Source DEFAULT = JDK1_7;
|
||||
|
||||
public static Source lookup(String name) {
|
||||
return tab.get(name);
|
||||
|
@ -1008,11 +1008,10 @@ public class Type implements PrimitiveType {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "capture#"
|
||||
+ (hashCode() & 0xFFFFFFFFL) % PRIME
|
||||
+ (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
|
||||
+ " of "
|
||||
+ wildcard;
|
||||
}
|
||||
static final int PRIME = 997; // largest prime less than 1000
|
||||
}
|
||||
|
||||
public static abstract class DelegatedType extends Type {
|
||||
|
@ -66,7 +66,7 @@ public class Paths {
|
||||
* @param context the context
|
||||
* @return the Paths instance for this context
|
||||
*/
|
||||
public static Paths instance(Context context) {
|
||||
static Paths instance(Context context) {
|
||||
Paths instance = context.get(pathsKey);
|
||||
if (instance == null)
|
||||
instance = new Paths(context);
|
||||
|
@ -108,7 +108,7 @@ public enum Target {
|
||||
this.minorVersion = minorVersion;
|
||||
}
|
||||
|
||||
public static final Target DEFAULT = JDK1_6;
|
||||
public static final Target DEFAULT = JDK1_7;
|
||||
|
||||
public static Target lookup(String name) {
|
||||
return tab.get(name);
|
||||
|
@ -391,6 +391,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
|
||||
(options.get("shouldStopPolicy") != null)
|
||||
? CompileState.valueOf(options.get("shouldStopPolicy"))
|
||||
: null;
|
||||
if (options.get("oldDiags") == null)
|
||||
log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
|
||||
}
|
||||
|
||||
/* Switches:
|
||||
|
@ -55,7 +55,6 @@ import com.sun.source.util.TaskListener;
|
||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.file.Paths;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
@ -180,7 +179,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
|
||||
private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) {
|
||||
Paths paths = Paths.instance(context);
|
||||
Log log = Log.instance(context);
|
||||
Iterator<? extends Processor> processorIterator;
|
||||
|
||||
|
@ -1165,3 +1165,64 @@ compiler.err.static.import.not.supported.in.source=\
|
||||
compiler.err.enums.not.supported.in.source=\
|
||||
enums are not supported in -source {0}\n\
|
||||
(use -source 5 or higher to enable enums)
|
||||
|
||||
########################################
|
||||
# Diagnostics for where clause implementation
|
||||
# used by the RichDiagnosticFormatter.
|
||||
########################################
|
||||
|
||||
compiler.misc.type.null=\
|
||||
<null>
|
||||
|
||||
# X#n (where n is an int id) is disambiguated tvar name
|
||||
compiler.misc.type.var=\
|
||||
{0}#{1}
|
||||
|
||||
# CAP#n (where n is an int id) is an abbreviation for 'captured type'
|
||||
compiler.misc.captured.type=\
|
||||
CAP#{0}
|
||||
|
||||
# <INT#n> (where n is an int id) is an abbreviation for 'intersection type'
|
||||
compiler.misc.intersection.type=\
|
||||
INT#{0}
|
||||
|
||||
# where clause for captured type: contains upper ('extends {1}') and lower
|
||||
# ('super {2}') bound along with the wildcard that generated this captured type ({3})
|
||||
compiler.misc.where.captured=\
|
||||
{0} extends {1} super: {2} from capture of {3}
|
||||
|
||||
# compact where clause for captured type: contains upper ('extends {1}') along
|
||||
# with the wildcard that generated this captured type ({3})
|
||||
compiler.misc.where.captured.1=\
|
||||
{0} extends {1} from capture of {3}
|
||||
|
||||
# where clause for type variable: contains upper bound(s) ('extends {1}') along with
|
||||
# the kindname ({2}) and location ({3}) in which the typevar has been declared
|
||||
compiler.misc.where.typevar=\
|
||||
{0} extends {1} declared in {2} {3}
|
||||
|
||||
# compact where clause for type variable: contains the kindname ({2}) and location ({3})
|
||||
# in which the typevar has been declared
|
||||
compiler.misc.where.typevar.1=\
|
||||
{0} declared in {2} {3}
|
||||
|
||||
# where clause for type variable: contains all the upper bound(s) ('extends {1}')
|
||||
# of this intersection type
|
||||
compiler.misc.where.intersection=\
|
||||
{0} extends {1}
|
||||
|
||||
### Where clause headers ###
|
||||
compiler.misc.where.description.captured=\
|
||||
where {0} is a fresh type-variable:
|
||||
compiler.misc.where.description.typevar=\
|
||||
where {0} is a type-variable:
|
||||
compiler.misc.where.description.intersection=\
|
||||
where {0} is an intersection type:
|
||||
compiler.misc.where.description.captured.1=\
|
||||
where {0} are fresh type-variables:
|
||||
compiler.misc.where.description.typevar.1=\
|
||||
where {0} are type-variables:
|
||||
compiler.misc.where.description.intersection.1=\
|
||||
where {0} are intersection types:
|
||||
|
||||
|
||||
|
@ -77,9 +77,11 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
protected int depth = 0;
|
||||
|
||||
/**
|
||||
* Printer instance to be used for formatting types/symbol
|
||||
* All captured types that have been encountered during diagnostic formatting.
|
||||
* This info is used by the FormatterPrinter in order to print friendly unique
|
||||
* ids for captured types
|
||||
*/
|
||||
protected Printer printer;
|
||||
private List<Type> allCaptured = List.nil();
|
||||
|
||||
/**
|
||||
* Initialize an AbstractDiagnosticFormatter by setting its JavacMessages object.
|
||||
@ -88,7 +90,6 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
protected AbstractDiagnosticFormatter(JavacMessages messages, SimpleConfiguration config) {
|
||||
this.messages = messages;
|
||||
this.config = config;
|
||||
this.printer = new FormatterPrinter();
|
||||
}
|
||||
|
||||
public String formatKind(JCDiagnostic d, Locale l) {
|
||||
@ -104,7 +105,7 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
|
||||
@Override
|
||||
public String format(JCDiagnostic d, Locale locale) {
|
||||
printer = new FormatterPrinter();
|
||||
allCaptured = List.nil();
|
||||
return formatDiagnostic(d, locale);
|
||||
}
|
||||
|
||||
@ -171,6 +172,9 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
return formatIterable(d, (Iterable<?>)arg, l);
|
||||
}
|
||||
else if (arg instanceof Type) {
|
||||
if (!allCaptured.contains(arg)) {
|
||||
allCaptured = allCaptured.append((Type)arg);
|
||||
}
|
||||
return printer.visit((Type)arg, l);
|
||||
}
|
||||
else if (arg instanceof Symbol) {
|
||||
@ -291,6 +295,10 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
d.getIntPosition() != Position.NOPOS;
|
||||
}
|
||||
|
||||
public boolean isRaw() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string with a given amount of empty spaces. Useful for
|
||||
* indenting the text of a diagnostic message.
|
||||
@ -355,26 +363,26 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
String showSource = null;
|
||||
if ((showSource = options.get("showSource")) != null) {
|
||||
if (showSource.equals("true"))
|
||||
visibleParts.add(DiagnosticPart.SOURCE);
|
||||
setVisiblePart(DiagnosticPart.SOURCE, true);
|
||||
else if (showSource.equals("false"))
|
||||
visibleParts.remove(DiagnosticPart.SOURCE);
|
||||
setVisiblePart(DiagnosticPart.SOURCE, false);
|
||||
}
|
||||
String diagOpts = options.get("diags");
|
||||
if (diagOpts != null) {//override -XDshowSource
|
||||
Collection<String> args = Arrays.asList(diagOpts.split(","));
|
||||
if (args.contains("short")) {
|
||||
visibleParts.remove(DiagnosticPart.DETAILS);
|
||||
visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
|
||||
setVisiblePart(DiagnosticPart.DETAILS, false);
|
||||
setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
|
||||
}
|
||||
if (args.contains("source"))
|
||||
visibleParts.add(DiagnosticPart.SOURCE);
|
||||
setVisiblePart(DiagnosticPart.SOURCE, true);
|
||||
if (args.contains("-source"))
|
||||
visibleParts.remove(DiagnosticPart.SOURCE);
|
||||
setVisiblePart(DiagnosticPart.SOURCE, false);
|
||||
}
|
||||
String multiPolicy = null;
|
||||
if ((multiPolicy = options.get("multilinePolicy")) != null) {
|
||||
if (multiPolicy.equals("disabled"))
|
||||
visibleParts.remove(DiagnosticPart.SUBDIAGNOSTICS);
|
||||
setVisiblePart(DiagnosticPart.SUBDIAGNOSTICS, false);
|
||||
else if (multiPolicy.startsWith("limit:")) {
|
||||
String limitString = multiPolicy.substring("limit:".length());
|
||||
String[] limits = limitString.split(":");
|
||||
@ -421,6 +429,13 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
visibleParts = EnumSet.copyOf(diagParts);
|
||||
}
|
||||
|
||||
public void setVisiblePart(DiagnosticPart diagParts, boolean enabled) {
|
||||
if (enabled)
|
||||
visibleParts.add(diagParts);
|
||||
else
|
||||
visibleParts.remove(diagParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a '^' sign under the source line displayed by the formatter
|
||||
* (if applicable).
|
||||
@ -441,6 +456,14 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
}
|
||||
}
|
||||
|
||||
public Printer getPrinter() {
|
||||
return printer;
|
||||
}
|
||||
|
||||
public void setPrinter(Printer printer) {
|
||||
this.printer = printer;
|
||||
}
|
||||
|
||||
/**
|
||||
* An enhanced printer for formatting types/symbols used by
|
||||
* AbstractDiagnosticFormatter. Provides alternate numbering of captured
|
||||
@ -450,33 +473,14 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
||||
* type referred by a given captured type C contains C itself) which might
|
||||
* lead to infinite loops.
|
||||
*/
|
||||
protected class FormatterPrinter extends Printer {
|
||||
|
||||
List<Type> allCaptured = List.nil();
|
||||
List<Type> seenCaptured = List.nil();
|
||||
|
||||
protected Printer printer = new Printer() {
|
||||
@Override
|
||||
protected String localize(Locale locale, String key, Object... args) {
|
||||
return AbstractDiagnosticFormatter.this.localize(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
if (seenCaptured.contains(t))
|
||||
return localize(locale, "compiler.misc.type.captureof.1",
|
||||
allCaptured.indexOf(t) + 1);
|
||||
else {
|
||||
try {
|
||||
seenCaptured = seenCaptured.prepend(t);
|
||||
allCaptured = allCaptured.append(t);
|
||||
return localize(locale, "compiler.misc.type.captureof",
|
||||
allCaptured.indexOf(t) + 1,
|
||||
visit(t.wildcard, locale));
|
||||
}
|
||||
finally {
|
||||
seenCaptured = seenCaptured.tail;
|
||||
}
|
||||
}
|
||||
protected String capturedVarId(CapturedType t, Locale locale) {
|
||||
return "" + (allCaptured.indexOf(t) + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -209,6 +209,7 @@ public class BasicDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
|
||||
@Override
|
||||
public BasicConfiguration getConfiguration() {
|
||||
//the following cast is always safe - see init
|
||||
return (BasicConfiguration)super.getConfiguration();
|
||||
}
|
||||
|
||||
|
132
langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java
Normal file
132
langtools/src/share/classes/com/sun/tools/javac/util/ForwardingDiagnosticFormatter.java
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Locale;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.DiagnosticPart;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.MultilineLimit;
|
||||
import com.sun.tools.javac.api.DiagnosticFormatter.PositionKind;
|
||||
|
||||
/**
|
||||
* A delegated diagnostic formatter delegates all formatting
|
||||
* actions to an underlying formatter (aka the delegated formatter).
|
||||
*/
|
||||
public class ForwardingDiagnosticFormatter<D extends Diagnostic<?>, F extends DiagnosticFormatter<D>>
|
||||
implements DiagnosticFormatter<D> {
|
||||
|
||||
/**
|
||||
* The delegated formatter
|
||||
*/
|
||||
protected F formatter;
|
||||
|
||||
/*
|
||||
* configuration object used by this formatter
|
||||
*/
|
||||
protected ForwardingConfiguration configuration;
|
||||
|
||||
public ForwardingDiagnosticFormatter(F formatter) {
|
||||
this.formatter = formatter;
|
||||
this.configuration = new ForwardingConfiguration(formatter.getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying delegated formatter
|
||||
* @return delegate formatter
|
||||
*/
|
||||
public F getDelegatedFormatter() {
|
||||
return formatter;
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public boolean displaySource(D diag) {
|
||||
return formatter.displaySource(diag);
|
||||
}
|
||||
|
||||
public String format(D diag, Locale l) {
|
||||
return formatter.format(diag, l);
|
||||
}
|
||||
|
||||
public String formatKind(D diag, Locale l) {
|
||||
return formatter.formatKind(diag, l);
|
||||
}
|
||||
|
||||
public String formatMessage(D diag, Locale l) {
|
||||
return formatter.formatMessage(diag, l);
|
||||
}
|
||||
|
||||
public String formatPosition(D diag, PositionKind pk, Locale l) {
|
||||
return formatter.formatPosition(diag, pk, l);
|
||||
}
|
||||
|
||||
public String formatSource(D diag, boolean fullname, Locale l) {
|
||||
return formatter.formatSource(diag, fullname, l);
|
||||
}
|
||||
|
||||
/**
|
||||
* A delegated formatter configuration delegates all configurations settings
|
||||
* to an underlying configuration object (aka the delegated configuration).
|
||||
*/
|
||||
public static class ForwardingConfiguration implements DiagnosticFormatter.Configuration {
|
||||
|
||||
/** The configurationr object to which the forwarding configuration delegates some settings */
|
||||
protected Configuration configuration;
|
||||
|
||||
public ForwardingConfiguration(Configuration configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying delegated configuration.
|
||||
* @return delegated configuration
|
||||
*/
|
||||
public Configuration getDelegatedConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public int getMultilineLimit(MultilineLimit limit) {
|
||||
return configuration.getMultilineLimit(limit);
|
||||
}
|
||||
|
||||
public Set<DiagnosticPart> getVisible() {
|
||||
return configuration.getVisible();
|
||||
}
|
||||
|
||||
public void setMultilineLimit(MultilineLimit limit, int value) {
|
||||
configuration.setMultilineLimit(limit, value);
|
||||
}
|
||||
|
||||
public void setVisible(Set<DiagnosticPart> diagParts) {
|
||||
configuration.setVisible(diagParts);
|
||||
}
|
||||
}
|
||||
}
|
@ -124,4 +124,9 @@ public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRaw() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,648 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Printer;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.*;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTags.*;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.util.LayoutCharacters.*;
|
||||
import static com.sun.tools.javac.util.RichDiagnosticFormatter.RichConfiguration.*;
|
||||
|
||||
/**
|
||||
* A rich diagnostic formatter is a formatter that provides better integration
|
||||
* with javac's type system. A diagostic is first preprocessed in order to keep
|
||||
* track of each types/symbols in it; after these informations are collected,
|
||||
* the diagnostic is rendered using a standard formatter, whose type/symbol printer
|
||||
* has been replaced by a more refined version provided by this rich formatter.
|
||||
* The rich formatter currently enables three different features: (i) simple class
|
||||
* names - that is class names are displayed used a non qualified name (thus
|
||||
* omitting package info) whenever possible - (ii) where clause list - a list of
|
||||
* additional subdiagnostics that provide specific info about type-variables,
|
||||
* captured types, intersection types that occur in the diagnostic that is to be
|
||||
* formatted and (iii) type-variable disambiguation - when the diagnostic refers
|
||||
* to two different type-variables with the same name, their representation is
|
||||
* disambiguated by appending an index to the type variable name.
|
||||
*/
|
||||
public class RichDiagnosticFormatter extends
|
||||
ForwardingDiagnosticFormatter<JCDiagnostic, AbstractDiagnosticFormatter> {
|
||||
|
||||
final Symtab syms;
|
||||
final Types types;
|
||||
final JCDiagnostic.Factory diags;
|
||||
final JavacMessages messages;
|
||||
|
||||
/* name simplifier used by this formatter */
|
||||
ClassNameSimplifier nameSimplifier;
|
||||
|
||||
/* map for keeping track of a where clause associated to a given type */
|
||||
Map<WhereClauseKind, Map<Type, JCDiagnostic>> whereClauses;
|
||||
|
||||
/** Get the DiagnosticFormatter instance for this context. */
|
||||
public static RichDiagnosticFormatter instance(Context context) {
|
||||
RichDiagnosticFormatter instance = context.get(RichDiagnosticFormatter.class);
|
||||
if (instance == null)
|
||||
instance = new RichDiagnosticFormatter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected RichDiagnosticFormatter(Context context) {
|
||||
super((AbstractDiagnosticFormatter)Log.instance(context).getDiagnosticFormatter());
|
||||
this.formatter.setPrinter(printer);
|
||||
this.syms = Symtab.instance(context);
|
||||
this.diags = JCDiagnostic.Factory.instance(context);
|
||||
this.types = Types.instance(context);
|
||||
this.messages = JavacMessages.instance(context);
|
||||
whereClauses = new LinkedHashMap<WhereClauseKind, Map<Type, JCDiagnostic>>();
|
||||
configuration = new RichConfiguration(Options.instance(context), formatter);
|
||||
for (WhereClauseKind kind : WhereClauseKind.values())
|
||||
whereClauses.put(kind, new LinkedHashMap<Type, JCDiagnostic>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(JCDiagnostic diag, Locale l) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
nameSimplifier = new ClassNameSimplifier();
|
||||
for (WhereClauseKind kind : WhereClauseKind.values())
|
||||
whereClauses.get(kind).clear();
|
||||
preprocessDiagnostic(diag);
|
||||
sb.append(formatter.format(diag, l));
|
||||
if (getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
List<JCDiagnostic> clauses = getWhereClauses();
|
||||
String indent = formatter.isRaw() ? "" :
|
||||
formatter.indentString(DetailsInc);
|
||||
for (JCDiagnostic d : clauses) {
|
||||
String whereClause = formatter.format(d, l);
|
||||
if (whereClause.length() > 0) {
|
||||
sb.append('\n' + indent + whereClause);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess a given diagnostic by looking both into its arguments and into
|
||||
* its subdiagnostics (if any). This preprocessing is responsible for
|
||||
* generating info corresponding to features like where clauses, name
|
||||
* simplification, etc.
|
||||
*
|
||||
* @param diag the diagnostic to be preprocessed
|
||||
*/
|
||||
protected void preprocessDiagnostic(JCDiagnostic diag) {
|
||||
for (Object o : diag.getArgs()) {
|
||||
if (o != null) {
|
||||
preprocessArgument(o);
|
||||
}
|
||||
}
|
||||
if (diag.isMultiline()) {
|
||||
for (JCDiagnostic d : diag.getSubdiagnostics())
|
||||
preprocessDiagnostic(d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess a diagnostic argument. A type/symbol argument is
|
||||
* preprocessed by specialized type/symbol preprocessors.
|
||||
*
|
||||
* @param arg the argument to be translated
|
||||
*/
|
||||
protected void preprocessArgument(Object arg) {
|
||||
if (arg instanceof Type) {
|
||||
preprocessType((Type)arg);
|
||||
}
|
||||
else if (arg instanceof Symbol) {
|
||||
preprocessSymbol((Symbol)arg);
|
||||
}
|
||||
else if (arg instanceof JCDiagnostic) {
|
||||
preprocessDiagnostic((JCDiagnostic)arg);
|
||||
}
|
||||
else if (arg instanceof Iterable<?>) {
|
||||
for (Object o : (Iterable<?>)arg) {
|
||||
preprocessArgument(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of multiline diagnostics containing detailed info about
|
||||
* type-variables, captured types, and intersection types
|
||||
*
|
||||
* @return where clause list
|
||||
*/
|
||||
protected List<JCDiagnostic> getWhereClauses() {
|
||||
List<JCDiagnostic> clauses = List.nil();
|
||||
for (WhereClauseKind kind : WhereClauseKind.values()) {
|
||||
List<JCDiagnostic> lines = List.nil();
|
||||
for (Map.Entry<Type, JCDiagnostic> entry : whereClauses.get(kind).entrySet()) {
|
||||
lines = lines.prepend(entry.getValue());
|
||||
}
|
||||
if (!lines.isEmpty()) {
|
||||
String key = kind.key();
|
||||
if (lines.size() > 1)
|
||||
key += ".1";
|
||||
JCDiagnostic d = diags.fragment(key, whereClauses.get(kind).keySet());
|
||||
d = new JCDiagnostic.MultilineDiagnostic(d, lines.reverse());
|
||||
clauses = clauses.prepend(d);
|
||||
}
|
||||
}
|
||||
return clauses.reverse();
|
||||
}
|
||||
//where
|
||||
/**
|
||||
* This enum defines all posssible kinds of where clauses that can be
|
||||
* attached by a rich diagnostic formatter to a given diagnostic
|
||||
*/
|
||||
enum WhereClauseKind {
|
||||
|
||||
/** where clause regarding a type variable */
|
||||
TYPEVAR("where.description.typevar"),
|
||||
/** where clause regarding a captured type */
|
||||
CAPTURED("where.description.captured"),
|
||||
/** where clause regarding an intersection type */
|
||||
INTERSECTION("where.description.intersection");
|
||||
|
||||
/** resource key for this where clause kind */
|
||||
private String key;
|
||||
|
||||
WhereClauseKind(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
String key() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="name simplifier">
|
||||
/**
|
||||
* A name simplifier keeps track of class names usages in order to determine
|
||||
* whether a class name can be compacted or not. Short names are not used
|
||||
* if a conflict is detected, e.g. when two classes with the same simple
|
||||
* name belong to different packages - in this case the formatter reverts
|
||||
* to fullnames as compact names might lead to a confusing diagnostic.
|
||||
*/
|
||||
class ClassNameSimplifier {
|
||||
|
||||
/* table for keeping track of all short name usages */
|
||||
Map<Name, List<Symbol>> nameClashes = new HashMap<Name, List<Symbol>>();
|
||||
|
||||
/**
|
||||
* Add a name usage to the simplifier's internal cache
|
||||
*/
|
||||
protected void addUsage(Symbol sym) {
|
||||
Name n = sym.getSimpleName();
|
||||
List<Symbol> conflicts = nameClashes.get(n);
|
||||
if (conflicts == null) {
|
||||
conflicts = List.nil();
|
||||
}
|
||||
if (!conflicts.contains(sym))
|
||||
nameClashes.put(n, conflicts.append(sym));
|
||||
}
|
||||
|
||||
public String simplify(Symbol s) {
|
||||
String name = s.getQualifiedName().toString();
|
||||
if (!s.type.isCompound()) {
|
||||
List<Symbol> conflicts = nameClashes.get(s.getSimpleName());
|
||||
if (conflicts == null ||
|
||||
(conflicts.size() == 1 &&
|
||||
conflicts.contains(s))) {
|
||||
List<Name> l = List.nil();
|
||||
Symbol s2 = s;
|
||||
while (s2.type.getEnclosingType().tag == CLASS
|
||||
&& s2.owner.kind == Kinds.TYP) {
|
||||
l = l.prepend(s2.getSimpleName());
|
||||
s2 = s2.owner;
|
||||
}
|
||||
l = l.prepend(s2.getSimpleName());
|
||||
StringBuilder buf = new StringBuilder();
|
||||
String sep = "";
|
||||
for (Name n2 : l) {
|
||||
buf.append(sep);
|
||||
buf.append(n2);
|
||||
sep = ".";
|
||||
}
|
||||
name = buf.toString();
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="rich printer">
|
||||
/**
|
||||
* Enhanced type/symbol printer that provides support for features like simple names
|
||||
* and type variable disambiguation. This enriched printer exploits the info
|
||||
* discovered during type/symbol preprocessing. This printer is set on the delegate
|
||||
* formatter so that rich type/symbol info can be properly rendered.
|
||||
*/
|
||||
protected Printer printer = new Printer() {
|
||||
|
||||
@Override
|
||||
public String localize(Locale locale, String key, Object... args) {
|
||||
return formatter.localize(locale, key, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String capturedVarId(CapturedType t, Locale locale) {
|
||||
return indexOf(t, WhereClauseKind.CAPTURED) + "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitType(Type t, Locale locale) {
|
||||
String s = super.visitType(t, locale);
|
||||
if (t == syms.botType)
|
||||
s = localize(locale, "compiler.misc.type.null");
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
||||
if (getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
return localize(locale,
|
||||
"compiler.misc.captured.type",
|
||||
indexOf(t, WhereClauseKind.CAPTURED));
|
||||
}
|
||||
else
|
||||
return super.visitCapturedType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassType(ClassType t, Locale locale) {
|
||||
if (t.isCompound() &&
|
||||
getConfiguration().isEnabled(RichFormatterFeature.WHERE_CLAUSES)) {
|
||||
return localize(locale,
|
||||
"compiler.misc.intersection.type",
|
||||
indexOf(t, WhereClauseKind.INTERSECTION));
|
||||
}
|
||||
else
|
||||
return super.visitClassType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String className(ClassType t, boolean longform, Locale locale) {
|
||||
Symbol sym = t.tsym;
|
||||
if (sym.name.length() == 0 ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) {
|
||||
return super.className(t, longform, locale);
|
||||
}
|
||||
else if (longform)
|
||||
return nameSimplifier.simplify(sym).toString();
|
||||
else
|
||||
return sym.name.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeVar(TypeVar t, Locale locale) {
|
||||
if (unique(t) ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES)) {
|
||||
return t.toString();
|
||||
}
|
||||
else {
|
||||
return localize(locale,
|
||||
"compiler.misc.type.var",
|
||||
t.toString(), indexOf(t, WhereClauseKind.TYPEVAR));
|
||||
}
|
||||
}
|
||||
|
||||
private int indexOf(Type type, WhereClauseKind kind) {
|
||||
int index = 0;
|
||||
boolean found = false;
|
||||
for (Type t : whereClauses.get(kind).keySet()) {
|
||||
if (t == type) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (!found)
|
||||
throw new AssertionError("Missing symbol in where clause " + type);
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
private boolean unique(TypeVar typevar) {
|
||||
int found = 0;
|
||||
for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
|
||||
if (t.toString().equals(typevar.toString())) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found < 1)
|
||||
throw new AssertionError("Missing type variable in where clause " + typevar);
|
||||
return found == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
|
||||
return super.printMethodArgs(args, varArgs, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitClassSymbol(ClassSymbol s, Locale locale) {
|
||||
String name = nameSimplifier.simplify(s);
|
||||
if (name.length() == 0 ||
|
||||
!getConfiguration().isEnabled(RichFormatterFeature.SIMPLE_NAMES)) {
|
||||
return super.visitClassSymbol(s, locale);
|
||||
}
|
||||
else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitMethodSymbol(MethodSymbol s, Locale locale) {
|
||||
String ownerName = visit(s.owner, locale);
|
||||
if ((s.flags() & BLOCK) != 0) {
|
||||
return ownerName;
|
||||
} else {
|
||||
String ms = (s.name == s.name.table.names.init)
|
||||
? ownerName
|
||||
: s.name.toString();
|
||||
if (s.type != null) {
|
||||
if (s.type.tag == FORALL) {
|
||||
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
|
||||
}
|
||||
ms += "(" + printMethodArgs(
|
||||
s.type.getParameterTypes(),
|
||||
(s.flags() & VARARGS) != 0,
|
||||
locale) + ")";
|
||||
}
|
||||
return ms;
|
||||
}
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="type scanner">
|
||||
/**
|
||||
* Preprocess a given type looking for (i) additional info (where clauses) to be
|
||||
* added to the main diagnostic (ii) names to be compacted.
|
||||
*/
|
||||
protected void preprocessType(Type t) {
|
||||
typePreprocessor.visit(t);
|
||||
}
|
||||
//where
|
||||
protected Types.UnaryVisitor<Void> typePreprocessor =
|
||||
new Types.UnaryVisitor<Void>() {
|
||||
|
||||
public Void visit(List<Type> ts) {
|
||||
for (Type t : ts)
|
||||
visit(t);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitForAll(ForAll t, Void ignored) {
|
||||
visit(t.tvars);
|
||||
visit(t.qtype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodType(MethodType t, Void ignored) {
|
||||
visit(t.argtypes);
|
||||
visit(t.restype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitErrorType(ErrorType t, Void ignored) {
|
||||
Type ot = t.getOriginalType();
|
||||
if (ot != null)
|
||||
visit(ot);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitArrayType(ArrayType t, Void ignored) {
|
||||
visit(t.elemtype);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitWildcardType(WildcardType t, Void ignored) {
|
||||
visit(t.type);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitType(Type t, Void ignored) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCapturedType(CapturedType t, Void ignored) {
|
||||
if (!whereClauses.get(WhereClauseKind.CAPTURED).containsKey(t)) {
|
||||
String suffix = t.lower == syms.botType ? ".1" : "";
|
||||
JCDiagnostic d = diags.fragment("where.captured"+ suffix, t, t.bound, t.lower, t.wildcard);
|
||||
whereClauses.get(WhereClauseKind.CAPTURED).put(t, d);
|
||||
visit(t.wildcard);
|
||||
visit(t.lower);
|
||||
visit(t.bound);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitClassType(ClassType t, Void ignored) {
|
||||
if (t.isCompound()) {
|
||||
if (!whereClauses.get(WhereClauseKind.INTERSECTION).containsKey(t)) {
|
||||
Type supertype = types.supertype(t);
|
||||
List<Type> interfaces = types.interfaces(t);
|
||||
JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype));
|
||||
whereClauses.get(WhereClauseKind.INTERSECTION).put(t, d);
|
||||
visit(supertype);
|
||||
visit(interfaces);
|
||||
}
|
||||
}
|
||||
nameSimplifier.addUsage(t.tsym);
|
||||
visit(t.getTypeArguments());
|
||||
if (t.getEnclosingType() != Type.noType)
|
||||
visit(t.getEnclosingType());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitTypeVar(TypeVar t, Void ignored) {
|
||||
if (!whereClauses.get(WhereClauseKind.TYPEVAR).containsKey(t)) {
|
||||
Type bound = t.bound;
|
||||
while ((bound instanceof ErrorType))
|
||||
bound = ((ErrorType)bound).getOriginalType();
|
||||
List<Type> bounds = types.getBounds(t);
|
||||
nameSimplifier.addUsage(t.tsym);
|
||||
|
||||
boolean boundErroneous = bounds.head == null ||
|
||||
bounds.head.tag == NONE ||
|
||||
bounds.head.tag == ERROR;
|
||||
|
||||
|
||||
JCDiagnostic d = diags.fragment("where.typevar" +
|
||||
(boundErroneous ? ".1" : ""), t, bounds,
|
||||
Kinds.kindName(t.tsym.location()), t.tsym.location());
|
||||
whereClauses.get(WhereClauseKind.TYPEVAR).put(t, d);
|
||||
symbolPreprocessor.visit(t.tsym.location(), null);
|
||||
visit(bounds);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="symbol scanner">
|
||||
/**
|
||||
* Preprocess a given symbol looking for (i) additional info (where clauses) to be
|
||||
* asdded to the main diagnostic (ii) names to be compacted
|
||||
*/
|
||||
protected void preprocessSymbol(Symbol s) {
|
||||
symbolPreprocessor.visit(s, null);
|
||||
}
|
||||
//where
|
||||
protected Types.DefaultSymbolVisitor<Void, Void> symbolPreprocessor =
|
||||
new Types.DefaultSymbolVisitor<Void, Void>() {
|
||||
|
||||
@Override
|
||||
public Void visitClassSymbol(ClassSymbol s, Void ignored) {
|
||||
nameSimplifier.addUsage(s);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitSymbol(Symbol s, Void ignored) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitMethodSymbol(MethodSymbol s, Void ignored) {
|
||||
visit(s.owner, null);
|
||||
typePreprocessor.visit(s.type);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// </editor-fold>
|
||||
|
||||
@Override
|
||||
public RichConfiguration getConfiguration() {
|
||||
//the following cast is always safe - see init
|
||||
return (RichConfiguration)configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration object provided by the rich formatter.
|
||||
*/
|
||||
public static class RichConfiguration extends ForwardingDiagnosticFormatter.ForwardingConfiguration {
|
||||
|
||||
/** set of enabled rich formatter's features */
|
||||
protected java.util.EnumSet<RichFormatterFeature> features;
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
public RichConfiguration(Options options, AbstractDiagnosticFormatter formatter) {
|
||||
super(formatter.getConfiguration());
|
||||
features = formatter.isRaw() ? EnumSet.noneOf(RichFormatterFeature.class) :
|
||||
EnumSet.of(RichFormatterFeature.SIMPLE_NAMES,
|
||||
RichFormatterFeature.WHERE_CLAUSES,
|
||||
RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
String diagOpts = options.get("diags");
|
||||
if (diagOpts != null) {
|
||||
for (String args: diagOpts.split(",")) {
|
||||
if (args.equals("-where")) {
|
||||
features.remove(RichFormatterFeature.WHERE_CLAUSES);
|
||||
}
|
||||
else if (args.equals("where")) {
|
||||
features.add(RichFormatterFeature.WHERE_CLAUSES);
|
||||
}
|
||||
if (args.equals("-simpleNames")) {
|
||||
features.remove(RichFormatterFeature.SIMPLE_NAMES);
|
||||
}
|
||||
else if (args.equals("simpleNames")) {
|
||||
features.add(RichFormatterFeature.SIMPLE_NAMES);
|
||||
}
|
||||
if (args.equals("-disambiguateTvars")) {
|
||||
features.remove(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
}
|
||||
else if (args.equals("disambiguateTvars")) {
|
||||
features.add(RichFormatterFeature.UNIQUE_TYPEVAR_NAMES);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the features supported by the rich formatter.
|
||||
* @return list of supported features
|
||||
*/
|
||||
public RichFormatterFeature[] getAvailableFeatures() {
|
||||
return RichFormatterFeature.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a specific feature on this rich formatter.
|
||||
* @param feature feature to be enabled
|
||||
*/
|
||||
public void enable(RichFormatterFeature feature) {
|
||||
features.add(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a specific feature on this rich formatter.
|
||||
* @param feature feature to be disabled
|
||||
*/
|
||||
public void disable(RichFormatterFeature feature) {
|
||||
features.remove(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a given feature enabled on this formatter?
|
||||
* @param feature feature to be tested
|
||||
*/
|
||||
public boolean isEnabled(RichFormatterFeature feature) {
|
||||
return features.contains(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* The advanced formatting features provided by the rich formatter
|
||||
*/
|
||||
public enum RichFormatterFeature {
|
||||
/** a list of additional info regarding a given type/symbol */
|
||||
WHERE_CLAUSES,
|
||||
/** full class names simplification (where possible) */
|
||||
SIMPLE_NAMES,
|
||||
/** type-variable names disambiguation */
|
||||
UNIQUE_TYPEVAR_NAMES;
|
||||
}
|
||||
}
|
||||
}
|
@ -44,6 +44,9 @@ public class BasicWriter {
|
||||
protected BasicWriter(Context context) {
|
||||
lineWriter = LineWriter.instance(context);
|
||||
out = context.get(PrintWriter.class);
|
||||
messages = context.get(Messages.class);
|
||||
if (messages == null)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
protected void print(String s) {
|
||||
@ -88,8 +91,26 @@ public class BasicWriter {
|
||||
return "???";
|
||||
}
|
||||
|
||||
protected String space(int w) {
|
||||
if (w < spaces.length && spaces[w] != null)
|
||||
return spaces[w];
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < w; i++)
|
||||
sb.append(" ");
|
||||
|
||||
String s = sb.toString();
|
||||
if (w < spaces.length)
|
||||
spaces[w] = s;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String[] spaces = new String[80];
|
||||
|
||||
private LineWriter lineWriter;
|
||||
private PrintWriter out;
|
||||
protected Messages messages;
|
||||
|
||||
private static class LineWriter {
|
||||
static LineWriter instance(Context context) {
|
||||
|
@ -26,7 +26,9 @@
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import java.net.URI;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
@ -47,8 +49,6 @@ import com.sun.tools.classfile.Signature_attribute;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
import com.sun.tools.classfile.Type;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import static com.sun.tools.classfile.AccessFlags.*;
|
||||
|
||||
/*
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
@ -33,9 +36,6 @@ import com.sun.tools.classfile.DescriptorException;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.Instruction.TypeKind;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.Opcode;
|
||||
|
||||
//import static com.sun.tools.classfile.OpCodes.*;
|
||||
|
||||
/*
|
||||
* Write the contents of a Code attribute.
|
||||
@ -59,6 +59,12 @@ class CodeWriter extends BasicWriter {
|
||||
attrWriter = AttributeWriter.instance(context);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
sourceWriter = SourceWriter.instance(context);
|
||||
tryBlockWriter = TryBlockWriter.instance(context);
|
||||
stackMapWriter = StackMapWriter.instance(context);
|
||||
localVariableTableWriter = LocalVariableTableWriter.instance(context);
|
||||
localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
void write(Code_attribute attr, ConstantPool constant_pool) {
|
||||
@ -90,14 +96,21 @@ class CodeWriter extends BasicWriter {
|
||||
}
|
||||
|
||||
public void writeInstrs(Code_attribute attr) {
|
||||
List<InstructionDetailWriter> detailWriters = getDetailWriters(attr);
|
||||
|
||||
for (Instruction instr: attr.getInstructions()) {
|
||||
try {
|
||||
for (InstructionDetailWriter w: detailWriters)
|
||||
w.writeDetails(instr);
|
||||
writeInstr(instr);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
println(report("error at or after byte " + instr.getPC()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (InstructionDetailWriter w: detailWriters)
|
||||
w.flush();
|
||||
}
|
||||
|
||||
public void writeInstr(Instruction instr) {
|
||||
@ -211,11 +224,45 @@ class CodeWriter extends BasicWriter {
|
||||
print(s);
|
||||
}
|
||||
|
||||
private static int align(int n) {
|
||||
return (n + 3) & ~3;
|
||||
private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
|
||||
List<InstructionDetailWriter> detailWriters =
|
||||
new ArrayList<InstructionDetailWriter>();
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.SOURCE)) {
|
||||
sourceWriter.reset(classWriter.getClassFile(), attr);
|
||||
detailWriters.add(sourceWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VARS)) {
|
||||
localVariableTableWriter.reset(attr);
|
||||
detailWriters.add(localVariableTableWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.LOCAL_VAR_TYPES)) {
|
||||
localVariableTypeTableWriter.reset(attr);
|
||||
detailWriters.add(localVariableTypeTableWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.STACKMAPS)) {
|
||||
stackMapWriter.reset(attr);
|
||||
stackMapWriter.writeInitialDetails();
|
||||
detailWriters.add(stackMapWriter);
|
||||
}
|
||||
|
||||
if (options.details.contains(InstructionDetailWriter.Kind.TRY_BLOCKS)) {
|
||||
tryBlockWriter.reset(attr);
|
||||
detailWriters.add(tryBlockWriter);
|
||||
}
|
||||
|
||||
return detailWriters;
|
||||
}
|
||||
|
||||
private AttributeWriter attrWriter;
|
||||
private ClassWriter classWriter;
|
||||
private ConstantWriter constantWriter;
|
||||
private LocalVariableTableWriter localVariableTableWriter;
|
||||
private LocalVariableTypeTableWriter localVariableTypeTableWriter;
|
||||
private SourceWriter sourceWriter;
|
||||
private StackMapWriter stackMapWriter;
|
||||
private TryBlockWriter tryBlockWriter;
|
||||
private Options options;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,32 +23,35 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
package sun.tools.javap;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Strores LocalVariableTable data information.
|
||||
/*
|
||||
* Write additional details for an instruction.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
* <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 LocVarData {
|
||||
short start_pc, length, name_cpx, sig_cpx, slot;
|
||||
|
||||
public LocVarData() {
|
||||
public abstract class InstructionDetailWriter extends BasicWriter {
|
||||
public enum Kind {
|
||||
LOCAL_VARS("localVariables"),
|
||||
LOCAL_VAR_TYPES("localVariableTypes"),
|
||||
SOURCE("source"),
|
||||
STACKMAPS("stackMaps"),
|
||||
TRY_BLOCKS("tryBlocks");
|
||||
Kind(String option) {
|
||||
this.option = option;
|
||||
}
|
||||
final String option;
|
||||
}
|
||||
InstructionDetailWriter(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read LocalVariableTable attribute.
|
||||
*/
|
||||
public LocVarData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
length=in.readShort();
|
||||
name_cpx=in.readShort();
|
||||
sig_cpx=in.readShort();
|
||||
slot=in.readShort();
|
||||
|
||||
}
|
||||
abstract void writeDetails(Instruction instr);
|
||||
void flush() { }
|
||||
}
|
@ -39,6 +39,7 @@ import java.security.MessageDigest;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -65,7 +66,7 @@ import com.sun.tools.classfile.*;
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
||||
public class BadArgs extends Exception {
|
||||
static final long serialVersionUID = 8765093759964640721L;
|
||||
BadArgs(String key, Object... args) {
|
||||
@ -211,9 +212,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
|
||||
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");
|
||||
task.log.println(task.getMessage("warn.Xold.not.supported"));
|
||||
}
|
||||
},
|
||||
|
||||
@ -241,6 +240,56 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDdetails") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
new Option(false, "-XDdetails:") {
|
||||
@Override
|
||||
boolean matches(String opt) {
|
||||
int sep = opt.indexOf(":");
|
||||
return sep != -1 && super.matches(opt.substring(0, sep + 1));
|
||||
}
|
||||
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
int sep = opt.indexOf(":");
|
||||
for (String v: opt.substring(sep + 1).split("[,: ]+")) {
|
||||
if (!handleArg(task, v))
|
||||
throw task.new BadArgs("err.invalid.arg.for.option", v);
|
||||
}
|
||||
}
|
||||
|
||||
boolean handleArg(JavapTask task, String arg) {
|
||||
if (arg.length() == 0)
|
||||
return true;
|
||||
|
||||
if (arg.equals("all")) {
|
||||
task.options.details = EnumSet.allOf(InstructionDetailWriter.Kind.class);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean on = true;
|
||||
if (arg.startsWith("-")) {
|
||||
on = false;
|
||||
arg = arg.substring(1);
|
||||
}
|
||||
|
||||
for (InstructionDetailWriter.Kind k: InstructionDetailWriter.Kind.values()) {
|
||||
if (arg.equalsIgnoreCase(k.option)) {
|
||||
if (on)
|
||||
task.options.details.add(k);
|
||||
else
|
||||
task.options.details.remove(k);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-constants") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showConstants = true;
|
||||
@ -251,6 +300,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
|
||||
JavapTask() {
|
||||
context = new Context();
|
||||
context.put(Messages.class, this);
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
@ -469,6 +519,8 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
|
||||
context.put(PrintWriter.class, log);
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
SourceWriter sourceWriter = SourceWriter.instance(context);
|
||||
sourceWriter.setFileManager(fileManager);
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
@ -651,11 +703,11 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
|
||||
}
|
||||
|
||||
private String getMessage(String key, Object... args) {
|
||||
public String getMessage(String key, Object... args) {
|
||||
return getMessage(task_locale, key, args);
|
||||
}
|
||||
|
||||
private String getMessage(Locale locale, String key, Object... args) {
|
||||
public 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
|
||||
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.LocalVariableTable_attribute;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Annotate instructions with details about local variables.
|
||||
*
|
||||
* <p><b>This is NOT part of any 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 LocalVariableTableWriter extends InstructionDetailWriter {
|
||||
public enum NoteKind {
|
||||
START("start") {
|
||||
public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
|
||||
return (pc == entry.start_pc);
|
||||
}
|
||||
},
|
||||
END("end") {
|
||||
public boolean match(LocalVariableTable_attribute.Entry entry, int pc) {
|
||||
return (pc == entry.start_pc + entry.length);
|
||||
}
|
||||
};
|
||||
NoteKind(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
public abstract boolean match(LocalVariableTable_attribute.Entry entry, int pc);
|
||||
public final String text;
|
||||
};
|
||||
|
||||
static LocalVariableTableWriter instance(Context context) {
|
||||
LocalVariableTableWriter instance = context.get(LocalVariableTableWriter.class);
|
||||
if (instance == null)
|
||||
instance = new LocalVariableTableWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected LocalVariableTableWriter(Context context) {
|
||||
super(context);
|
||||
context.put(LocalVariableTableWriter.class, this);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
}
|
||||
|
||||
public void reset(Code_attribute attr) {
|
||||
codeAttr = attr;
|
||||
pcMap = new HashMap<Integer, List<LocalVariableTable_attribute.Entry>>();
|
||||
LocalVariableTable_attribute lvt =
|
||||
(LocalVariableTable_attribute) (attr.attributes.get(Attribute.LocalVariableTable));
|
||||
if (lvt == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < lvt.local_variable_table.length; i++) {
|
||||
LocalVariableTable_attribute.Entry entry = lvt.local_variable_table[i];
|
||||
put(entry.start_pc, entry);
|
||||
put(entry.start_pc + entry.length, entry);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDetails(Instruction instr) {
|
||||
int pc = instr.getPC();
|
||||
writeLocalVariables(pc, NoteKind.END);
|
||||
writeLocalVariables(pc, NoteKind.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
int pc = codeAttr.code_length;
|
||||
writeLocalVariables(pc, NoteKind.END);
|
||||
}
|
||||
|
||||
public void writeLocalVariables(int pc, NoteKind kind) {
|
||||
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
|
||||
String indent = space(2); // get from Options?
|
||||
List<LocalVariableTable_attribute.Entry> entries = pcMap.get(pc);
|
||||
if (entries != null) {
|
||||
for (ListIterator<LocalVariableTable_attribute.Entry> iter =
|
||||
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
|
||||
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
|
||||
LocalVariableTable_attribute.Entry entry =
|
||||
kind == NoteKind.END ? iter.previous() : iter.next();
|
||||
if (kind.match(entry, pc)) {
|
||||
print(indent);
|
||||
print(kind.text);
|
||||
print(" local ");
|
||||
print(entry.index);
|
||||
print(" // ");
|
||||
Descriptor d = new Descriptor(entry.descriptor_index);
|
||||
try {
|
||||
print(d.getFieldType(constant_pool));
|
||||
} catch (InvalidDescriptor e) {
|
||||
print(report(e));
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
}
|
||||
print(" ");
|
||||
try {
|
||||
print(constant_pool.getUTF8Value(entry.name_index));
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
}
|
||||
println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void put(int pc, LocalVariableTable_attribute.Entry entry) {
|
||||
List<LocalVariableTable_attribute.Entry> list = pcMap.get(pc);
|
||||
if (list == null) {
|
||||
list = new ArrayList<LocalVariableTable_attribute.Entry>();
|
||||
pcMap.put(pc, list);
|
||||
}
|
||||
if (!list.contains(entry))
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
private ClassWriter classWriter;
|
||||
private Code_attribute codeAttr;
|
||||
private Map<Integer, List<LocalVariableTable_attribute.Entry>> pcMap;
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
|
||||
import com.sun.tools.classfile.Signature;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Annotate instructions with details about local variables.
|
||||
*
|
||||
* <p><b>This is NOT part of any 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 LocalVariableTypeTableWriter extends InstructionDetailWriter {
|
||||
public enum NoteKind {
|
||||
START("start") {
|
||||
public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
|
||||
return (pc == entry.start_pc);
|
||||
}
|
||||
},
|
||||
END("end") {
|
||||
public boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc) {
|
||||
return (pc == entry.start_pc + entry.length);
|
||||
}
|
||||
};
|
||||
NoteKind(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
public abstract boolean match(LocalVariableTypeTable_attribute.Entry entry, int pc);
|
||||
public final String text;
|
||||
};
|
||||
|
||||
static LocalVariableTypeTableWriter instance(Context context) {
|
||||
LocalVariableTypeTableWriter instance = context.get(LocalVariableTypeTableWriter.class);
|
||||
if (instance == null)
|
||||
instance = new LocalVariableTypeTableWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected LocalVariableTypeTableWriter(Context context) {
|
||||
super(context);
|
||||
context.put(LocalVariableTypeTableWriter.class, this);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
}
|
||||
|
||||
public void reset(Code_attribute attr) {
|
||||
codeAttr = attr;
|
||||
pcMap = new HashMap<Integer, List<LocalVariableTypeTable_attribute.Entry>>();
|
||||
LocalVariableTypeTable_attribute lvt =
|
||||
(LocalVariableTypeTable_attribute) (attr.attributes.get(Attribute.LocalVariableTypeTable));
|
||||
if (lvt == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < lvt.local_variable_table.length; i++) {
|
||||
LocalVariableTypeTable_attribute.Entry entry = lvt.local_variable_table[i];
|
||||
put(entry.start_pc, entry);
|
||||
put(entry.start_pc + entry.length, entry);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDetails(Instruction instr) {
|
||||
int pc = instr.getPC();
|
||||
writeLocalVariables(pc, NoteKind.END);
|
||||
writeLocalVariables(pc, NoteKind.START);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
int pc = codeAttr.code_length;
|
||||
writeLocalVariables(pc, NoteKind.END);
|
||||
}
|
||||
|
||||
public void writeLocalVariables(int pc, NoteKind kind) {
|
||||
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
|
||||
String indent = space(2); // get from Options?
|
||||
List<LocalVariableTypeTable_attribute.Entry> entries = pcMap.get(pc);
|
||||
if (entries != null) {
|
||||
for (ListIterator<LocalVariableTypeTable_attribute.Entry> iter =
|
||||
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
|
||||
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
|
||||
LocalVariableTypeTable_attribute.Entry entry =
|
||||
kind == NoteKind.END ? iter.previous() : iter.next();
|
||||
if (kind.match(entry, pc)) {
|
||||
print(indent);
|
||||
print(kind.text);
|
||||
print(" generic local ");
|
||||
print(entry.index);
|
||||
print(" // ");
|
||||
Descriptor d = new Signature(entry.signature_index);
|
||||
try {
|
||||
print(d.getFieldType(constant_pool));
|
||||
} catch (InvalidDescriptor e) {
|
||||
print(report(e));
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
}
|
||||
print(" ");
|
||||
try {
|
||||
print(constant_pool.getUTF8Value(entry.name_index));
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
}
|
||||
println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void put(int pc, LocalVariableTypeTable_attribute.Entry entry) {
|
||||
List<LocalVariableTypeTable_attribute.Entry> list = pcMap.get(pc);
|
||||
if (list == null) {
|
||||
list = new ArrayList<LocalVariableTypeTable_attribute.Entry>();
|
||||
pcMap.put(pc, list);
|
||||
}
|
||||
if (!list.contains(entry))
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
private ClassWriter classWriter;
|
||||
private Code_attribute codeAttr;
|
||||
private Map<Integer, List<LocalVariableTypeTable_attribute.Entry>> pcMap;
|
||||
}
|
@ -42,13 +42,6 @@ public class Main {
|
||||
* @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);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,18 +23,20 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
package sun.tools.javap;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Stores constant pool entry information with one field.
|
||||
* Access to javap messages.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
* <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 CPX {
|
||||
int cpx;
|
||||
public interface Messages {
|
||||
String getMessage(String key, Object... args);
|
||||
|
||||
CPX (int cpx) {
|
||||
this.cpx=cpx;
|
||||
}
|
||||
String getMessage(Locale locale, String key, Object... args);
|
||||
}
|
@ -25,8 +25,10 @@
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
|
||||
/*
|
||||
@ -77,6 +79,7 @@ public class Options {
|
||||
public boolean showLineAndLocalVariableTables;
|
||||
public int showAccess;
|
||||
public Set<String> accessOptions = new HashSet<String>();
|
||||
public Set<InstructionDetailWriter.Kind> details = EnumSet.noneOf(InstructionDetailWriter.Kind.class);
|
||||
public boolean showDisassembled;
|
||||
public boolean showInternalSignatures;
|
||||
public boolean showAllAttrs;
|
||||
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.LineNumberTable_attribute;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
|
||||
|
||||
/**
|
||||
* Annotate instructions with source code.
|
||||
*
|
||||
* <p><b>This is NOT part of any 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 SourceWriter extends InstructionDetailWriter {
|
||||
static SourceWriter instance(Context context) {
|
||||
SourceWriter instance = context.get(SourceWriter.class);
|
||||
if (instance == null)
|
||||
instance = new SourceWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected SourceWriter(Context context) {
|
||||
super(context);
|
||||
context.put(SourceWriter.class, this);
|
||||
}
|
||||
|
||||
void setFileManager(JavaFileManager fileManager) {
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
public void reset(ClassFile cf, Code_attribute attr) {
|
||||
setSource(cf);
|
||||
setLineMap(attr);
|
||||
}
|
||||
|
||||
public void writeDetails(Instruction instr) {
|
||||
String indent = space(40); // could get from Options?
|
||||
Set<Integer> lines = lineMap.get(instr.getPC());
|
||||
if (lines != null) {
|
||||
for (int line: lines) {
|
||||
print(indent);
|
||||
print(String.format(" %4d ", line));
|
||||
if (line < sourceLines.length)
|
||||
print(sourceLines[line]);
|
||||
println();
|
||||
int nextLine = nextLine(line);
|
||||
for (int i = line + 1; i < nextLine; i++) {
|
||||
print(indent);
|
||||
print(String.format("(%4d)", i));
|
||||
if (i < sourceLines.length)
|
||||
print(sourceLines[i]);
|
||||
println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setLineMap(Code_attribute attr) {
|
||||
SortedMap<Integer, SortedSet<Integer>> map =
|
||||
new TreeMap<Integer, SortedSet<Integer>>();
|
||||
SortedSet<Integer> allLines = new TreeSet<Integer>();
|
||||
for (Attribute a: attr.attributes) {
|
||||
if (a instanceof LineNumberTable_attribute) {
|
||||
LineNumberTable_attribute t = (LineNumberTable_attribute) a;
|
||||
for (LineNumberTable_attribute.Entry e: t.line_number_table) {
|
||||
int start_pc = e.start_pc;
|
||||
int line = e.line_number;
|
||||
SortedSet<Integer> pcLines = map.get(start_pc);
|
||||
if (pcLines == null) {
|
||||
pcLines = new TreeSet<Integer>();
|
||||
map.put(start_pc, pcLines);
|
||||
}
|
||||
pcLines.add(line);
|
||||
allLines.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
lineMap = map;
|
||||
lineList = new ArrayList<Integer>(allLines);
|
||||
}
|
||||
|
||||
private void setSource(ClassFile cf) {
|
||||
if (cf != classFile) {
|
||||
classFile = cf;
|
||||
sourceLines = splitLines(readSource(cf));
|
||||
}
|
||||
}
|
||||
|
||||
private String readSource(ClassFile cf) {
|
||||
Location location;
|
||||
if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
|
||||
location = StandardLocation.SOURCE_PATH;
|
||||
else
|
||||
location = StandardLocation.CLASS_PATH;
|
||||
|
||||
// Guess the source file for a class from the package name for this
|
||||
// class and the base of the source file. This avoids having to read
|
||||
// additional classes to determine the outmost class from any
|
||||
// InnerClasses and EnclosingMethod attributes.
|
||||
try {
|
||||
String className = cf.getName();
|
||||
SourceFile_attribute sf =
|
||||
(SourceFile_attribute) cf.attributes.get(Attribute.SourceFile);
|
||||
if (sf == null) {
|
||||
report(messages.getMessage("err.no.SourceFile.attribute"));
|
||||
return null;
|
||||
}
|
||||
String sourceFile = sf.getSourceFile(cf.constant_pool);
|
||||
String fileBase = sourceFile.endsWith(".java")
|
||||
? sourceFile.substring(0, sourceFile.length() - 5) : sourceFile;
|
||||
int sep = className.lastIndexOf("/");
|
||||
String pkgName = (sep == -1 ? "" : className.substring(0, sep+1));
|
||||
String topClassName = (pkgName + fileBase).replace('/', '.');
|
||||
JavaFileObject fo =
|
||||
fileManager.getJavaFileForInput(location,
|
||||
topClassName,
|
||||
JavaFileObject.Kind.SOURCE);
|
||||
if (fo == null) {
|
||||
report(messages.getMessage("err.source.file.not.found"));
|
||||
return null;
|
||||
}
|
||||
return fo.getCharContent(true).toString();
|
||||
} catch (ConstantPoolException e) {
|
||||
report(e);
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
report(e.getLocalizedMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] splitLines(String text) {
|
||||
if (text == null)
|
||||
return new String[0];
|
||||
|
||||
List<String> lines = new ArrayList<String>();
|
||||
lines.add(""); // dummy line 0
|
||||
try {
|
||||
BufferedReader r = new BufferedReader(new StringReader(text));
|
||||
String line;
|
||||
while ((line = r.readLine()) != null)
|
||||
lines.add(line);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
return lines.toArray(new String[lines.size()]);
|
||||
}
|
||||
|
||||
private int nextLine(int line) {
|
||||
int i = lineList.indexOf(line);
|
||||
if (i == -1 || i == lineList.size() - 1)
|
||||
return - 1;
|
||||
return lineList.get(i + 1);
|
||||
}
|
||||
|
||||
private JavaFileManager fileManager;
|
||||
private ClassFile classFile;
|
||||
private SortedMap<Integer, SortedSet<Integer>> lineMap;
|
||||
private List<Integer> lineList;
|
||||
private String[] sourceLines;
|
||||
}
|
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.StackMapTable_attribute;
|
||||
import com.sun.tools.classfile.StackMapTable_attribute.*;
|
||||
|
||||
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
|
||||
|
||||
/**
|
||||
* Annotate instructions with stack map.
|
||||
*
|
||||
* <p><b>This is NOT part of any 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 StackMapWriter extends InstructionDetailWriter {
|
||||
static StackMapWriter instance(Context context) {
|
||||
StackMapWriter instance = context.get(StackMapWriter.class);
|
||||
if (instance == null)
|
||||
instance = new StackMapWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected StackMapWriter(Context context) {
|
||||
super(context);
|
||||
context.put(StackMapWriter.class, this);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
}
|
||||
|
||||
public void reset(Code_attribute attr) {
|
||||
setStackMap((StackMapTable_attribute) attr.attributes.get(Attribute.StackMapTable));
|
||||
}
|
||||
|
||||
void setStackMap(StackMapTable_attribute attr) {
|
||||
if (attr == null) {
|
||||
map = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Method m = classWriter.getMethod();
|
||||
Descriptor d = m.descriptor;
|
||||
String[] args;
|
||||
try {
|
||||
ConstantPool cp = classWriter.getClassFile().constant_pool;
|
||||
String argString = d.getParameterTypes(cp);
|
||||
args = argString.substring(1, argString.length() - 1).split("[, ]+");
|
||||
} catch (ConstantPoolException e) {
|
||||
return;
|
||||
} catch (InvalidDescriptor e) {
|
||||
return;
|
||||
}
|
||||
boolean isStatic = m.access_flags.is(AccessFlags.ACC_STATIC);
|
||||
|
||||
verification_type_info[] initialLocals = new verification_type_info[(isStatic ? 0 : 1) + args.length];
|
||||
if (!isStatic)
|
||||
initialLocals[0] = new CustomVerificationTypeInfo("this");
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
initialLocals[(isStatic ? 0 : 1) + i] =
|
||||
new CustomVerificationTypeInfo(args[i].replace(".", "/"));
|
||||
}
|
||||
|
||||
map = new HashMap<Integer, StackMap>();
|
||||
StackMapBuilder builder = new StackMapBuilder();
|
||||
|
||||
// using -1 as the pc for the initial frame effectively compensates for
|
||||
// the difference in behavior for the first stack map frame (where the
|
||||
// pc offset is just offset_delta) compared to subsequent frames (where
|
||||
// the pc offset is always offset_delta+1).
|
||||
int pc = -1;
|
||||
|
||||
map.put(pc, new StackMap(initialLocals, empty));
|
||||
|
||||
for (int i = 0; i < attr.entries.length; i++)
|
||||
pc = attr.entries[i].accept(builder, pc);
|
||||
}
|
||||
|
||||
public void writeInitialDetails() {
|
||||
writeDetails(-1);
|
||||
}
|
||||
|
||||
public void writeDetails(Instruction instr) {
|
||||
writeDetails(instr.getPC());
|
||||
}
|
||||
|
||||
private void writeDetails(int pc) {
|
||||
if (map == null)
|
||||
return;
|
||||
|
||||
StackMap m = map.get(pc);
|
||||
if (m != null) {
|
||||
print("StackMap locals: ", m.locals);
|
||||
print("StackMap stack: ", m.stack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void print(String label, verification_type_info[] entries) {
|
||||
print(label);
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
print(" ");
|
||||
print(entries[i]);
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
void print(verification_type_info entry) {
|
||||
if (entry == null) {
|
||||
print("ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (entry.tag) {
|
||||
case -1:
|
||||
print(((CustomVerificationTypeInfo) entry).text);
|
||||
break;
|
||||
|
||||
case ITEM_Top:
|
||||
print("top");
|
||||
break;
|
||||
|
||||
case ITEM_Integer:
|
||||
print("int");
|
||||
break;
|
||||
|
||||
case ITEM_Float:
|
||||
print("float");
|
||||
break;
|
||||
|
||||
case ITEM_Long:
|
||||
print("long");
|
||||
break;
|
||||
|
||||
case ITEM_Double:
|
||||
print("double");
|
||||
break;
|
||||
|
||||
case ITEM_Null:
|
||||
print("null");
|
||||
break;
|
||||
|
||||
case ITEM_UninitializedThis:
|
||||
print("uninit_this");
|
||||
break;
|
||||
|
||||
case ITEM_Object:
|
||||
try {
|
||||
ConstantPool cp = classWriter.getClassFile().constant_pool;
|
||||
ConstantPool.CONSTANT_Class_info class_info = cp.getClassInfo(((Object_variable_info) entry).cpool_index);
|
||||
print(cp.getUTF8Value(class_info.name_index));
|
||||
} catch (ConstantPoolException e) {
|
||||
print("??");
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_Uninitialized:
|
||||
print(((Uninitialized_variable_info) entry).offset);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<Integer, StackMap> map;
|
||||
private ClassWriter classWriter;
|
||||
|
||||
class StackMapBuilder
|
||||
implements StackMapTable_attribute.stack_map_frame.Visitor<Integer, Integer> {
|
||||
|
||||
public Integer visit_same_frame(same_frame frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap m = map.get(pc);
|
||||
assert (m != null);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap prev = map.get(pc);
|
||||
assert (prev != null);
|
||||
StackMap m = new StackMap(prev.locals, frame.stack);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap prev = map.get(pc);
|
||||
assert (prev != null);
|
||||
StackMap m = new StackMap(prev.locals, frame.stack);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_chop_frame(chop_frame frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap prev = map.get(pc);
|
||||
assert (prev != null);
|
||||
int k = 251 - frame.frame_type;
|
||||
verification_type_info[] new_locals = new verification_type_info[prev.locals.length - k];
|
||||
System.arraycopy(prev.locals, 0, new_locals, 0, new_locals.length);
|
||||
StackMap m = new StackMap(new_locals, empty);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_same_frame_extended(same_frame_extended frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta();
|
||||
StackMap m = map.get(pc);
|
||||
assert (m != null);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_append_frame(append_frame frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap prev = map.get(pc);
|
||||
assert (prev != null);
|
||||
verification_type_info[] new_locals = new verification_type_info[prev.locals.length + frame.locals.length];
|
||||
System.arraycopy(prev.locals, 0, new_locals, 0, prev.locals.length);
|
||||
System.arraycopy(frame.locals, 0, new_locals, prev.locals.length, frame.locals.length);
|
||||
StackMap m = new StackMap(new_locals, empty);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
public Integer visit_full_frame(full_frame frame, Integer pc) {
|
||||
int new_pc = pc + frame.getOffsetDelta() + 1;
|
||||
StackMap m = new StackMap(frame.locals, frame.stack);
|
||||
map.put(new_pc, m);
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class StackMap {
|
||||
StackMap(verification_type_info[] locals, verification_type_info[] stack) {
|
||||
this.locals = locals;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
private final verification_type_info[] locals;
|
||||
private final verification_type_info[] stack;
|
||||
}
|
||||
|
||||
class CustomVerificationTypeInfo extends verification_type_info {
|
||||
public CustomVerificationTypeInfo(String text) {
|
||||
super(-1);
|
||||
this.text = text;
|
||||
}
|
||||
private String text;
|
||||
}
|
||||
|
||||
private final verification_type_info[] empty = { };
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.Code_attribute.Exception_data;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Annotate instructions with details about try blocks.
|
||||
*
|
||||
* <p><b>This is NOT part of any 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 TryBlockWriter extends InstructionDetailWriter {
|
||||
public enum NoteKind {
|
||||
START("try") {
|
||||
public boolean match(Exception_data entry, int pc) {
|
||||
return (pc == entry.start_pc);
|
||||
}
|
||||
},
|
||||
END("end try") {
|
||||
public boolean match(Exception_data entry, int pc) {
|
||||
return (pc == entry.end_pc);
|
||||
}
|
||||
},
|
||||
HANDLER("catch") {
|
||||
public boolean match(Exception_data entry, int pc) {
|
||||
return (pc == entry.handler_pc);
|
||||
}
|
||||
};
|
||||
NoteKind(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
public abstract boolean match(Exception_data entry, int pc);
|
||||
public final String text;
|
||||
};
|
||||
|
||||
static TryBlockWriter instance(Context context) {
|
||||
TryBlockWriter instance = context.get(TryBlockWriter.class);
|
||||
if (instance == null)
|
||||
instance = new TryBlockWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected TryBlockWriter(Context context) {
|
||||
super(context);
|
||||
context.put(TryBlockWriter.class, this);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
}
|
||||
|
||||
public void reset(Code_attribute attr) {
|
||||
indexMap = new HashMap<Exception_data, Integer>();
|
||||
pcMap = new HashMap<Integer, List<Exception_data>>();
|
||||
for (int i = 0; i < attr.exception_table.length; i++) {
|
||||
Exception_data entry = attr.exception_table[i];
|
||||
indexMap.put(entry, i);
|
||||
put(entry.start_pc, entry);
|
||||
put(entry.end_pc, entry);
|
||||
put(entry.handler_pc, entry);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDetails(Instruction instr) {
|
||||
writeTrys(instr, NoteKind.END);
|
||||
writeTrys(instr, NoteKind.START);
|
||||
writeTrys(instr, NoteKind.HANDLER);
|
||||
}
|
||||
|
||||
public void writeTrys(Instruction instr, NoteKind kind) {
|
||||
String indent = space(2); // get from Options?
|
||||
int pc = instr.getPC();
|
||||
List<Exception_data> entries = pcMap.get(pc);
|
||||
if (entries != null) {
|
||||
for (ListIterator<Exception_data> iter =
|
||||
entries.listIterator(kind == NoteKind.END ? entries.size() : 0);
|
||||
kind == NoteKind.END ? iter.hasPrevious() : iter.hasNext() ; ) {
|
||||
Exception_data entry =
|
||||
kind == NoteKind.END ? iter.previous() : iter.next();
|
||||
if (kind.match(entry, pc)) {
|
||||
print(indent);
|
||||
print(kind.text);
|
||||
print("[");
|
||||
print(indexMap.get(entry));
|
||||
print("] ");
|
||||
if (entry.catch_type == 0)
|
||||
print("finally");
|
||||
else {
|
||||
print("#" + entry.catch_type);
|
||||
print(" // ");
|
||||
constantWriter.write(entry.catch_type);
|
||||
}
|
||||
println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void put(int pc, Exception_data entry) {
|
||||
List<Exception_data> list = pcMap.get(pc);
|
||||
if (list == null) {
|
||||
list = new ArrayList<Exception_data>();
|
||||
pcMap.put(pc, list);
|
||||
}
|
||||
if (!list.contains(entry))
|
||||
list.add(entry);
|
||||
}
|
||||
|
||||
private Map<Integer, List<Exception_data>> pcMap;
|
||||
private Map<Exception_data, Integer> indexMap;
|
||||
private ConstantWriter constantWriter;
|
||||
}
|
@ -9,13 +9,16 @@ err.file.not.found=file not found: {0}
|
||||
err.h.not.supported=-h is no longer available - use the 'javah' program
|
||||
err.incompatible.options=bad combination of options: {0}
|
||||
err.internal.error=internal error: {0} {1} {2}
|
||||
err.invalid.arg.for.option=invalid argument for option: {0}
|
||||
err.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
|
||||
err.no.SourceFile.attribute=no SourceFile attribute
|
||||
err.source.file.not.found=source file not found
|
||||
warn.Xold.not.supported=-Xold is no longer available
|
||||
|
||||
main.usage.summary=\
|
||||
Usage: {0} <options> <classes>\n\
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 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 sun.tools.javap;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Reads and stores attribute information.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
class AttrData {
|
||||
ClassData cls;
|
||||
int name_cpx;
|
||||
int datalen;
|
||||
byte data[];
|
||||
|
||||
public AttrData (ClassData cls) {
|
||||
this.cls=cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads unknown attribute.
|
||||
*/
|
||||
public void read(int name_cpx, DataInputStream in) throws IOException {
|
||||
this.name_cpx=name_cpx;
|
||||
datalen=in.readInt();
|
||||
data=new byte[datalen];
|
||||
in.readFully(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads just the name of known attribute.
|
||||
*/
|
||||
public void read(int name_cpx){
|
||||
this.name_cpx=name_cpx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns attribute name.
|
||||
*/
|
||||
public String getAttrName(){
|
||||
return cls.getString(name_cpx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns attribute data.
|
||||
*/
|
||||
public byte[] getData(){
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,663 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Central data repository of the Java Disassembler.
|
||||
* Stores all the information in java class file.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
public class ClassData implements RuntimeConstants {
|
||||
|
||||
private int magic;
|
||||
private int minor_version;
|
||||
private int major_version;
|
||||
private int cpool_count;
|
||||
private Object cpool[];
|
||||
private int access;
|
||||
private int this_class = 0;;
|
||||
private int super_class;
|
||||
private int interfaces_count;
|
||||
private int[] interfaces = new int[0];;
|
||||
private int fields_count;
|
||||
private FieldData[] fields;
|
||||
private int methods_count;
|
||||
private MethodData[] methods;
|
||||
private InnerClassData[] innerClasses;
|
||||
private int attributes_count;
|
||||
private AttrData[] attrs;
|
||||
private String classname;
|
||||
private String superclassname;
|
||||
private int source_cpx=0;
|
||||
private byte tags[];
|
||||
private Hashtable<Object,Integer> indexHashAscii = new Hashtable<Object,Integer>();
|
||||
private String pkgPrefix="";
|
||||
private int pkgPrefixLen=0;
|
||||
|
||||
/**
|
||||
* Read classfile to disassemble.
|
||||
*/
|
||||
public ClassData(InputStream infile){
|
||||
try{
|
||||
this.read(new DataInputStream(infile));
|
||||
}catch (FileNotFoundException ee) {
|
||||
error("cant read file");
|
||||
}catch (Error ee) {
|
||||
ee.printStackTrace();
|
||||
error("fatal error");
|
||||
} catch (Exception ee) {
|
||||
ee.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and stores class file information.
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
// Read the header
|
||||
magic = in.readInt();
|
||||
if (magic != JAVA_MAGIC) {
|
||||
throw new ClassFormatError("wrong magic: " +
|
||||
toHex(magic) + ", expected " +
|
||||
toHex(JAVA_MAGIC));
|
||||
}
|
||||
minor_version = in.readShort();
|
||||
major_version = in.readShort();
|
||||
if (major_version != JAVA_VERSION) {
|
||||
}
|
||||
|
||||
// Read the constant pool
|
||||
readCP(in);
|
||||
access = in.readUnsignedShort();
|
||||
this_class = in.readUnsignedShort();
|
||||
super_class = in.readUnsignedShort();
|
||||
|
||||
//Read interfaces.
|
||||
interfaces_count = in.readUnsignedShort();
|
||||
if(interfaces_count > 0){
|
||||
interfaces = new int[interfaces_count];
|
||||
}
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
interfaces[i]=in.readShort();
|
||||
}
|
||||
|
||||
// Read the fields
|
||||
readFields(in);
|
||||
|
||||
// Read the methods
|
||||
readMethods(in);
|
||||
|
||||
// Read the attributes
|
||||
attributes_count = in.readUnsignedShort();
|
||||
attrs=new AttrData[attributes_count];
|
||||
for (int k = 0; k < attributes_count; k++) {
|
||||
int name_cpx=in.readUnsignedShort();
|
||||
if (getTag(name_cpx)==CONSTANT_UTF8
|
||||
&& getString(name_cpx).equals("SourceFile")
|
||||
){ if (in.readInt()!=2)
|
||||
throw new ClassFormatError("invalid attr length");
|
||||
source_cpx=in.readUnsignedShort();
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx);
|
||||
attrs[k]=attr;
|
||||
|
||||
} else if (getTag(name_cpx)==CONSTANT_UTF8
|
||||
&& getString(name_cpx).equals("InnerClasses")
|
||||
){ int length=in.readInt();
|
||||
int num=in.readUnsignedShort();
|
||||
if (2+num*8 != length)
|
||||
throw new ClassFormatError("invalid attr length");
|
||||
innerClasses=new InnerClassData[num];
|
||||
for (int j = 0; j < num; j++) {
|
||||
InnerClassData innerClass=new InnerClassData(this);
|
||||
innerClass.read(in);
|
||||
innerClasses[j]=innerClass;
|
||||
}
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx);
|
||||
attrs[k]=attr;
|
||||
} else {
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx, in);
|
||||
attrs[k]=attr;
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} // end ClassData.read()
|
||||
|
||||
/**
|
||||
* Reads and stores constant pool info.
|
||||
*/
|
||||
void readCP(DataInputStream in) throws IOException {
|
||||
cpool_count = in.readUnsignedShort();
|
||||
tags = new byte[cpool_count];
|
||||
cpool = new Object[cpool_count];
|
||||
for (int i = 1; i < cpool_count; i++) {
|
||||
byte tag = in.readByte();
|
||||
|
||||
switch(tags[i] = tag) {
|
||||
case CONSTANT_UTF8:
|
||||
String str=in.readUTF();
|
||||
indexHashAscii.put(cpool[i] = str, i);
|
||||
break;
|
||||
case CONSTANT_INTEGER:
|
||||
cpool[i] = Integer.valueOf(in.readInt());
|
||||
break;
|
||||
case CONSTANT_FLOAT:
|
||||
cpool[i] = Float.valueOf(in.readFloat());
|
||||
break;
|
||||
case CONSTANT_LONG:
|
||||
cpool[i++] = Long.valueOf(in.readLong());
|
||||
break;
|
||||
case CONSTANT_DOUBLE:
|
||||
cpool[i++] = Double.valueOf(in.readDouble());
|
||||
break;
|
||||
case CONSTANT_CLASS:
|
||||
case CONSTANT_STRING:
|
||||
cpool[i] = new CPX(in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
throw new ClassFormatError("invalid constant type: " + (int)tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and strores field info.
|
||||
*/
|
||||
protected void readFields(DataInputStream in) throws IOException {
|
||||
int fields_count = in.readUnsignedShort();
|
||||
fields=new FieldData[fields_count];
|
||||
for (int k = 0; k < fields_count; k++) {
|
||||
FieldData field=new FieldData(this);
|
||||
field.read(in);
|
||||
fields[k]=field;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and strores Method info.
|
||||
*/
|
||||
protected void readMethods(DataInputStream in) throws IOException {
|
||||
int methods_count = in.readUnsignedShort();
|
||||
methods=new MethodData[methods_count];
|
||||
for (int k = 0; k < methods_count ; k++) {
|
||||
MethodData method=new MethodData(this);
|
||||
method.read(in);
|
||||
methods[k]=method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a string
|
||||
*/
|
||||
public String getString(int n) {
|
||||
return (n == 0) ? null : (String)cpool[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* get the type of constant given an index
|
||||
*/
|
||||
public byte getTag(int n) {
|
||||
try{
|
||||
return tags[n];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return (byte)100;
|
||||
}
|
||||
}
|
||||
|
||||
static final String hexString="0123456789ABCDEF";
|
||||
|
||||
public static char hexTable[]=hexString.toCharArray();
|
||||
|
||||
static String toHex(long val, int width) {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i=width-1; i>=0; i--)
|
||||
s.append(hexTable[((int)(val>>(4*i)))&0xF]);
|
||||
return "0x"+s.toString();
|
||||
}
|
||||
|
||||
static String toHex(long val) {
|
||||
int width;
|
||||
for (width=16; width>0; width--) {
|
||||
if ((val>>(width-1)*4)!=0) break;
|
||||
}
|
||||
return toHex(val, width);
|
||||
}
|
||||
|
||||
static String toHex(int val) {
|
||||
int width;
|
||||
for (width=8; width>0; width--) {
|
||||
if ((val>>(width-1)*4)!=0) break;
|
||||
}
|
||||
return toHex(val, width);
|
||||
}
|
||||
|
||||
public void error(String msg) {
|
||||
System.err.println("ERROR:" +msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this class.
|
||||
*/
|
||||
public String getClassName() {
|
||||
String res=null;
|
||||
if (this_class==0) {
|
||||
return res;
|
||||
}
|
||||
int tcpx;
|
||||
try {
|
||||
if (tags[this_class]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
tcpx=((CPX)cpool[this_class]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
try {
|
||||
return (String)(cpool[tcpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of class at perticular index.
|
||||
*/
|
||||
public String getClassName(int cpx) {
|
||||
String res="#"+cpx;
|
||||
if (cpx==0) {
|
||||
return res;
|
||||
}
|
||||
int scpx;
|
||||
try {
|
||||
if (tags[cpx]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
scpx=((CPX)cpool[cpx]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
res="#"+scpx;
|
||||
try {
|
||||
return (String)(cpool[scpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it is a class
|
||||
*/
|
||||
public boolean isClass() {
|
||||
if((access & ACC_INTERFACE) == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it is a interface.
|
||||
*/
|
||||
public boolean isInterface(){
|
||||
if((access & ACC_INTERFACE) != 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this member is public, false otherwise.
|
||||
*/
|
||||
public boolean isPublic(){
|
||||
return (access & ACC_PUBLIC) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access of this class or interface.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of innerclasses.
|
||||
*/
|
||||
public InnerClassData[] getInnerClasses(){
|
||||
return innerClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of attributes.
|
||||
*/
|
||||
public AttrData[] getAttributes(){
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if superbit is set.
|
||||
*/
|
||||
public boolean isSuperSet(){
|
||||
if ((access & ACC_SUPER) !=0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns super class name.
|
||||
*/
|
||||
public String getSuperClassName(){
|
||||
String res=null;
|
||||
if (super_class==0) {
|
||||
return res;
|
||||
}
|
||||
int scpx;
|
||||
try {
|
||||
if (tags[super_class]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
scpx=((CPX)cpool[super_class]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
try {
|
||||
return (String)(cpool[scpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of super interfaces.
|
||||
*/
|
||||
public String[] getSuperInterfaces(){
|
||||
String interfacenames[] = new String[interfaces.length];
|
||||
int interfacecpx = -1;
|
||||
for(int i = 0; i < interfaces.length; i++){
|
||||
interfacecpx=((CPX)cpool[interfaces[i]]).cpx;
|
||||
interfacenames[i] = (String)(cpool[interfacecpx]);
|
||||
}
|
||||
return interfacenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string at prticular constant pool index.
|
||||
*/
|
||||
public String getStringValue(int cpoolx) {
|
||||
try {
|
||||
return ((String)cpool[cpoolx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return "//invalid constant pool index:"+cpoolx;
|
||||
} catch (ClassCastException e) {
|
||||
return "//invalid constant pool ref:"+cpoolx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of field info.
|
||||
*/
|
||||
public FieldData[] getFields(){
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of method info.
|
||||
*/
|
||||
public MethodData[] getMethods(){
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constant pool entry at that index.
|
||||
*/
|
||||
public CPX2 getCpoolEntry(int cpx){
|
||||
return ((CPX2)(cpool[cpx]));
|
||||
}
|
||||
|
||||
public Object getCpoolEntryobj(int cpx){
|
||||
return (cpool[cpx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of this class.
|
||||
*/
|
||||
public int getthis_cpx(){
|
||||
return this_class;
|
||||
}
|
||||
|
||||
public String TagString (int tag) {
|
||||
String res=Tables.tagName(tag);
|
||||
if (res==null) return "BOGUS_TAG:"+tag;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string at that index.
|
||||
*/
|
||||
public String StringValue(int cpx) {
|
||||
if (cpx==0) return "#0";
|
||||
int tag;
|
||||
Object x;
|
||||
String suffix="";
|
||||
try {
|
||||
tag=tags[cpx];
|
||||
x=cpool[cpx];
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return "<Incorrect CP index:"+cpx+">";
|
||||
}
|
||||
|
||||
if (x==null) return "<NULL>";
|
||||
switch (tag) {
|
||||
case CONSTANT_UTF8: {
|
||||
StringBuffer sb=new StringBuffer();
|
||||
String s=(String)x;
|
||||
for (int k=0; k<s.length(); k++) {
|
||||
char c=s.charAt(k);
|
||||
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();
|
||||
}
|
||||
case CONSTANT_DOUBLE: {
|
||||
Double d=(Double)x;
|
||||
String sd=d.toString();
|
||||
return sd+"d";
|
||||
}
|
||||
case CONSTANT_FLOAT: {
|
||||
Float f=(Float)x;
|
||||
String sf=(f).toString();
|
||||
return sf+"f";
|
||||
}
|
||||
case CONSTANT_LONG: {
|
||||
Long ln = (Long)x;
|
||||
return ln.toString()+'l';
|
||||
}
|
||||
case CONSTANT_INTEGER: {
|
||||
Integer in = (Integer)x;
|
||||
return in.toString();
|
||||
}
|
||||
case CONSTANT_CLASS:
|
||||
return javaName(getClassName(cpx));
|
||||
case CONSTANT_STRING:
|
||||
return StringValue(((CPX)x).cpx);
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
//return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
|
||||
return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);
|
||||
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
return getName(((CPX2)x).cpx1)+":"+StringValue(((CPX2)x).cpx2);
|
||||
default:
|
||||
return "UnknownTag"; //TBD
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns resolved java type name.
|
||||
*/
|
||||
public String javaName(String name) {
|
||||
if( name==null) return "null";
|
||||
int len=name.length();
|
||||
if (len==0) return "\"\"";
|
||||
int cc='/';
|
||||
fullname: { // xxx/yyy/zzz
|
||||
int cp;
|
||||
for (int k=0; k<len; k += Character.charCount(cp)) {
|
||||
cp=name.codePointAt(k);
|
||||
if (cc=='/') {
|
||||
if (!Character.isJavaIdentifierStart(cp)) break fullname;
|
||||
} else if (cp!='/') {
|
||||
if (!Character.isJavaIdentifierPart(cp)) break fullname;
|
||||
}
|
||||
cc=cp;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
return "\""+name+"\"";
|
||||
}
|
||||
|
||||
public String getName(int cpx) {
|
||||
String res;
|
||||
try {
|
||||
return javaName((String)cpool[cpx]); //.replace('/','.');
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return "<invalid constant pool index:"+cpx+">";
|
||||
} catch (ClassCastException e) {
|
||||
return "<invalid constant pool ref:"+cpx+">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unqualified class name.
|
||||
*/
|
||||
public String getShortClassName(int cpx) {
|
||||
String classname=javaName(getClassName(cpx));
|
||||
pkgPrefixLen=classname.lastIndexOf("/")+1;
|
||||
if (pkgPrefixLen!=0) {
|
||||
pkgPrefix=classname.substring(0,pkgPrefixLen);
|
||||
if (classname.startsWith(pkgPrefix)) {
|
||||
return classname.substring(pkgPrefixLen);
|
||||
}
|
||||
}
|
||||
return classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns source file name.
|
||||
*/
|
||||
public String getSourceName(){
|
||||
return getName(source_cpx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns package name.
|
||||
*/
|
||||
public String getPkgName(){
|
||||
String classname=getClassName(this_class);
|
||||
pkgPrefixLen=classname.lastIndexOf("/")+1;
|
||||
if (pkgPrefixLen!=0) {
|
||||
pkgPrefix=classname.substring(0,pkgPrefixLen);
|
||||
return("package "+pkgPrefix.substring(0,pkgPrefixLen-1)+";\n");
|
||||
}else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns total constant pool entry count.
|
||||
*/
|
||||
public int getCpoolCount(){
|
||||
return cpool_count;
|
||||
}
|
||||
|
||||
public String StringTag(int cpx) {
|
||||
byte tag=0;
|
||||
String str=null;
|
||||
try {
|
||||
if (cpx==0) throw new IndexOutOfBoundsException();
|
||||
tag=tags[cpx];
|
||||
return TagString(tag);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
str="Incorrect CP index:"+cpx;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns minor version of class file.
|
||||
*/
|
||||
public int getMinor_version(){
|
||||
return minor_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns major version of class file.
|
||||
*/
|
||||
public int getMajor_version(){
|
||||
return major_version;
|
||||
}
|
||||
}
|
@ -1,372 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 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 sun.tools.javap;
|
||||
|
||||
/**
|
||||
* This interface defines constant that are used
|
||||
* throughout the compiler. It inherits from RuntimeConstants,
|
||||
* which is an autogenerated class that contains contstants
|
||||
* defined in the interpreter.
|
||||
*/
|
||||
|
||||
public
|
||||
interface Constants extends RuntimeConstants {
|
||||
|
||||
/**
|
||||
* End of input
|
||||
*/
|
||||
public static final int EOF = -1;
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
public static final int F_VERBOSE = 1 << 0;
|
||||
public static final int F_DUMP = 1 << 1;
|
||||
public static final int F_WARNINGS = 1 << 2;
|
||||
public static final int F_DEBUG = 1 << 3;
|
||||
public static final int F_OPTIMIZE = 1 << 4;
|
||||
public static final int F_DEPENDENCIES = 1 << 5;
|
||||
|
||||
/*
|
||||
* Type codes
|
||||
*/
|
||||
public static final int TC_BOOLEAN = 0;
|
||||
public static final int TC_BYTE = 1;
|
||||
public static final int TC_CHAR = 2;
|
||||
public static final int TC_SHORT = 3;
|
||||
public static final int TC_INT = 4;
|
||||
public static final int TC_LONG = 5;
|
||||
public static final int TC_FLOAT = 6;
|
||||
public static final int TC_DOUBLE = 7;
|
||||
public static final int TC_NULL = 8;
|
||||
public static final int TC_ARRAY = 9;
|
||||
public static final int TC_CLASS = 10;
|
||||
public static final int TC_VOID = 11;
|
||||
public static final int TC_METHOD = 12;
|
||||
public static final int TC_ERROR = 13;
|
||||
|
||||
/*
|
||||
* Type Masks
|
||||
*/
|
||||
public static final int TM_NULL = 1 << TC_NULL;
|
||||
public static final int TM_VOID = 1 << TC_VOID;
|
||||
public static final int TM_BOOLEAN = 1 << TC_BOOLEAN;
|
||||
public static final int TM_BYTE = 1 << TC_BYTE;
|
||||
public static final int TM_CHAR = 1 << TC_CHAR;
|
||||
public static final int TM_SHORT = 1 << TC_SHORT;
|
||||
public static final int TM_INT = 1 << TC_INT;
|
||||
public static final int TM_LONG = 1 << TC_LONG;
|
||||
public static final int TM_FLOAT = 1 << TC_FLOAT;
|
||||
public static final int TM_DOUBLE = 1 << TC_DOUBLE;
|
||||
public static final int TM_ARRAY = 1 << TC_ARRAY;
|
||||
public static final int TM_CLASS = 1 << TC_CLASS;
|
||||
public static final int TM_METHOD = 1 << TC_METHOD;
|
||||
public static final int TM_ERROR = 1 << TC_ERROR;
|
||||
|
||||
public static final int TM_INT32 = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
|
||||
public static final int TM_NUM32 = TM_INT32 | TM_FLOAT;
|
||||
public static final int TM_NUM64 = TM_LONG | TM_DOUBLE;
|
||||
public static final int TM_INTEGER = TM_INT32 | TM_LONG;
|
||||
public static final int TM_REAL = TM_FLOAT | TM_DOUBLE;
|
||||
public static final int TM_NUMBER = TM_INTEGER | TM_REAL;
|
||||
public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
|
||||
|
||||
/*
|
||||
* Class status
|
||||
*/
|
||||
public static final int CS_UNDEFINED = 0;
|
||||
public static final int CS_UNDECIDED = 1;
|
||||
public static final int CS_BINARY = 2;
|
||||
public static final int CS_SOURCE = 3;
|
||||
public static final int CS_PARSED = 4;
|
||||
public static final int CS_COMPILED = 5;
|
||||
public static final int CS_NOTFOUND = 6;
|
||||
|
||||
/*
|
||||
* Attributes
|
||||
*/
|
||||
public static final int ATT_ALL = -1;
|
||||
public static final int ATT_CODE = 1;
|
||||
|
||||
/*
|
||||
* Number of bits used in file offsets
|
||||
*/
|
||||
public static final int OFFSETBITS = 19;
|
||||
public static final int MAXFILESIZE = (1 << OFFSETBITS) - 1;
|
||||
public static final int MAXLINENUMBER = (1 << (32 - OFFSETBITS)) - 1;
|
||||
|
||||
/*
|
||||
* Operators
|
||||
*/
|
||||
public final int COMMA = 0;
|
||||
public final int ASSIGN = 1;
|
||||
|
||||
public final int ASGMUL = 2;
|
||||
public final int ASGDIV = 3;
|
||||
public final int ASGREM = 4;
|
||||
public final int ASGADD = 5;
|
||||
public final int ASGSUB = 6;
|
||||
public final int ASGLSHIFT = 7;
|
||||
public final int ASGRSHIFT = 8;
|
||||
public final int ASGURSHIFT = 9;
|
||||
public final int ASGBITAND = 10;
|
||||
public final int ASGBITOR = 11;
|
||||
public final int ASGBITXOR = 12;
|
||||
|
||||
public final int COND = 13;
|
||||
public final int OR = 14;
|
||||
public final int AND = 15;
|
||||
public final int BITOR = 16;
|
||||
public final int BITXOR = 17;
|
||||
public final int BITAND = 18;
|
||||
public final int NE = 19;
|
||||
public final int EQ = 20;
|
||||
public final int GE = 21;
|
||||
public final int GT = 22;
|
||||
public final int LE = 23;
|
||||
public final int LT = 24;
|
||||
public final int INSTANCEOF = 25;
|
||||
public final int LSHIFT = 26;
|
||||
public final int RSHIFT = 27;
|
||||
public final int URSHIFT = 28;
|
||||
public final int ADD = 29;
|
||||
public final int SUB = 30;
|
||||
public final int DIV = 31;
|
||||
public final int REM = 32;
|
||||
public final int MUL = 33;
|
||||
public final int CAST = 34; // (x)y
|
||||
public final int POS = 35; // +x
|
||||
public final int NEG = 36; // -x
|
||||
public final int NOT = 37;
|
||||
public final int BITNOT = 38;
|
||||
public final int PREINC = 39; // ++x
|
||||
public final int PREDEC = 40; // --x
|
||||
public final int NEWARRAY = 41;
|
||||
public final int NEWINSTANCE = 42;
|
||||
public final int NEWFROMNAME = 43;
|
||||
public final int POSTINC = 44; // x++
|
||||
public final int POSTDEC = 45; // x--
|
||||
public final int FIELD = 46;
|
||||
public final int METHOD = 47; // x(y)
|
||||
public final int ARRAYACCESS = 48; // x[y]
|
||||
public final int NEW = 49;
|
||||
public final int INC = 50;
|
||||
public final int DEC = 51;
|
||||
|
||||
public final int CONVERT = 55; // implicit conversion
|
||||
public final int EXPR = 56; // (x)
|
||||
public final int ARRAY = 57; // {x, y, ...}
|
||||
public final int GOTO = 58;
|
||||
|
||||
/*
|
||||
* Value tokens
|
||||
*/
|
||||
public final int IDENT = 60;
|
||||
public final int BOOLEANVAL = 61;
|
||||
public final int BYTEVAL = 62;
|
||||
public final int CHARVAL = 63;
|
||||
public final int SHORTVAL = 64;
|
||||
public final int INTVAL = 65;
|
||||
public final int LONGVAL = 66;
|
||||
public final int FLOATVAL = 67;
|
||||
public final int DOUBLEVAL = 68;
|
||||
public final int STRINGVAL = 69;
|
||||
|
||||
/*
|
||||
* Type keywords
|
||||
*/
|
||||
public final int BYTE = 70;
|
||||
public final int CHAR = 71;
|
||||
public final int SHORT = 72;
|
||||
public final int INT = 73;
|
||||
public final int LONG = 74;
|
||||
public final int FLOAT = 75;
|
||||
public final int DOUBLE = 76;
|
||||
public final int VOID = 77;
|
||||
public final int BOOLEAN = 78;
|
||||
|
||||
/*
|
||||
* Expression keywords
|
||||
*/
|
||||
public final int TRUE = 80;
|
||||
public final int FALSE = 81;
|
||||
public final int THIS = 82;
|
||||
public final int SUPER = 83;
|
||||
public final int NULL = 84;
|
||||
|
||||
/*
|
||||
* Statement keywords
|
||||
*/
|
||||
public final int IF = 90;
|
||||
public final int ELSE = 91;
|
||||
public final int FOR = 92;
|
||||
public final int WHILE = 93;
|
||||
public final int DO = 94;
|
||||
public final int SWITCH = 95;
|
||||
public final int CASE = 96;
|
||||
public final int DEFAULT = 97;
|
||||
public final int BREAK = 98;
|
||||
public final int CONTINUE = 99;
|
||||
public final int RETURN = 100;
|
||||
public final int TRY = 101;
|
||||
public final int CATCH = 102;
|
||||
public final int FINALLY = 103;
|
||||
public final int THROW = 104;
|
||||
public final int STAT = 105;
|
||||
public final int EXPRESSION = 106;
|
||||
public final int DECLARATION = 107;
|
||||
public final int VARDECLARATION = 108;
|
||||
|
||||
/*
|
||||
* Declaration keywords
|
||||
*/
|
||||
public final int IMPORT = 110;
|
||||
public final int CLASS = 111;
|
||||
public final int EXTENDS = 112;
|
||||
public final int IMPLEMENTS = 113;
|
||||
public final int INTERFACE = 114;
|
||||
public final int PACKAGE = 115;
|
||||
|
||||
/*
|
||||
* Modifier keywords
|
||||
*/
|
||||
public final int PRIVATE = 120;
|
||||
public final int PUBLIC = 121;
|
||||
public final int PROTECTED = 122;
|
||||
public final int CONST = 123;
|
||||
public final int STATIC = 124;
|
||||
public final int TRANSIENT = 125;
|
||||
public final int SYNCHRONIZED = 126;
|
||||
public final int NATIVE = 127;
|
||||
public final int FINAL = 128;
|
||||
public final int VOLATILE = 129;
|
||||
public final int ABSTRACT = 130;
|
||||
public final int STRICT = 165;
|
||||
|
||||
/*
|
||||
* Punctuation
|
||||
*/
|
||||
public final int SEMICOLON = 135;
|
||||
public final int COLON = 136;
|
||||
public final int QUESTIONMARK = 137;
|
||||
public final int LBRACE = 138;
|
||||
public final int RBRACE = 139;
|
||||
public final int LPAREN = 140;
|
||||
public final int RPAREN = 141;
|
||||
public final int LSQBRACKET = 142;
|
||||
public final int RSQBRACKET = 143;
|
||||
public final int THROWS = 144;
|
||||
|
||||
/*
|
||||
* Special tokens
|
||||
*/
|
||||
public final int ERROR = 145; // an error
|
||||
public final int COMMENT = 146; // not used anymore.
|
||||
public final int TYPE = 147;
|
||||
public final int LENGTH = 148;
|
||||
public final int INLINERETURN = 149;
|
||||
public final int INLINEMETHOD = 150;
|
||||
public final int INLINENEWINSTANCE = 151;
|
||||
|
||||
/*
|
||||
* Added for jasm
|
||||
*/
|
||||
public final int METHODREF = 152;
|
||||
public final int FIELDREF = 153;
|
||||
public final int STACK = 154;
|
||||
public final int LOCAL = 155;
|
||||
public final int CPINDEX = 156;
|
||||
public final int CPNAME = 157;
|
||||
public final int SIGN = 158;
|
||||
public final int BITS = 159;
|
||||
public final int INF = 160;
|
||||
public final int NAN = 161;
|
||||
public final int INNERCLASS = 162;
|
||||
public final int OF = 163;
|
||||
public final int SYNTHETIC = 164;
|
||||
// last used=165;
|
||||
|
||||
/*
|
||||
* Operator precedence
|
||||
*/
|
||||
public static final int opPrecedence[] = {
|
||||
10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
18, 19, 19, 19, 19, 19, 20, 20, 20, 21,
|
||||
21, 22, 22, 22, 23, 24, 24, 24, 24, 24,
|
||||
24, 25, 25, 26, 26, 26, 26, 26, 26
|
||||
};
|
||||
|
||||
/*
|
||||
* Operator names
|
||||
*/
|
||||
public static final String opNames[] = {
|
||||
",", "=", "*=", "/=", "%=",
|
||||
"+=", "-=", "<<=", ">>=", "<<<=",
|
||||
"&=", "|=", "^=", "?:", "||",
|
||||
"&&", "|", "^", "&", "!=",
|
||||
"==", ">=", ">", "<=", "<",
|
||||
"instanceof", "<<", ">>", "<<<", "+",
|
||||
"-", "/", "%", "*", "cast",
|
||||
"+", "-", "!", "~", "++",
|
||||
"--", "new", "new", "new", "++",
|
||||
"--", "field", "method", "[]", "new",
|
||||
"++", "--", null, null, null,
|
||||
|
||||
"convert", "expr", "array", "goto", null,
|
||||
|
||||
"Identifier", "Boolean", "Byte", "Char", "Short",
|
||||
"Integer", "Long", "Float", "Double", "String",
|
||||
|
||||
"byte", "char", "short", "int", "long",
|
||||
"float", "double", "void", "boolean", null,
|
||||
|
||||
"true", "false", "this", "super", "null",
|
||||
null, null, null, null, null,
|
||||
|
||||
"if", "else", "for", "while", "do",
|
||||
"switch", "case", "default", "break", "continue",
|
||||
"return", "try", "catch", "finally", "throw",
|
||||
"stat", "expression", "declaration", "declaration", null,
|
||||
|
||||
"import", "class", "extends", "implements", "interface",
|
||||
"package", null, null, null, null,
|
||||
|
||||
"private", "public", "protected", "const", "static",
|
||||
"transient", "synchronized", "native", "final", "volatile",
|
||||
"abstract", null, null, null, null,
|
||||
|
||||
";", ":", "?", "{", "}",
|
||||
"(", ")", "[", "]", "throws",
|
||||
"error", "comment", "type", "length", "inline-return",
|
||||
"inline-method", "inline-new",
|
||||
"method", "field", "stack", "locals", "CPINDEX", "CPName", "SIGN",
|
||||
"bits", "INF", "NaN", "InnerClass", "of", "synthetic"
|
||||
};
|
||||
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Strores field data informastion.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
|
||||
public class FieldData implements RuntimeConstants {
|
||||
|
||||
ClassData cls;
|
||||
int access;
|
||||
int name_index;
|
||||
int descriptor_index;
|
||||
int attributes_count;
|
||||
int value_cpx=0;
|
||||
boolean isSynthetic=false;
|
||||
boolean isDeprecated=false;
|
||||
Vector<AttrData> attrs;
|
||||
|
||||
public FieldData(ClassData cls){
|
||||
this.cls=cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and store field info.
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
access = in.readUnsignedShort();
|
||||
name_index = in.readUnsignedShort();
|
||||
descriptor_index = in.readUnsignedShort();
|
||||
// Read the attributes
|
||||
int attributes_count = in.readUnsignedShort();
|
||||
attrs=new Vector<AttrData>(attributes_count);
|
||||
for (int i = 0; i < attributes_count; i++) {
|
||||
int attr_name_index=in.readUnsignedShort();
|
||||
if (cls.getTag(attr_name_index)!=CONSTANT_UTF8) continue;
|
||||
String attr_name=cls.getString(attr_name_index);
|
||||
if (attr_name.equals("ConstantValue")){
|
||||
if (in.readInt()!=2)
|
||||
throw new ClassFormatError("invalid ConstantValue attr length");
|
||||
value_cpx=in.readUnsignedShort();
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
} else if (attr_name.equals("Synthetic")){
|
||||
if (in.readInt()!=0)
|
||||
throw new ClassFormatError("invalid Synthetic attr length");
|
||||
isSynthetic=true;
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
} else if (attr_name.equals("Deprecated")){
|
||||
if (in.readInt()!=0)
|
||||
throw new ClassFormatError("invalid Synthetic attr length");
|
||||
isDeprecated = true;
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
} else {
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index, in);
|
||||
attrs.addElement(attr);
|
||||
}
|
||||
}
|
||||
|
||||
} // end read
|
||||
|
||||
/**
|
||||
* Returns access of a field.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_PRIVATE) !=0) v.addElement("private");
|
||||
if ((access & ACC_PROTECTED) !=0) v.addElement("protected");
|
||||
if ((access & ACC_STATIC) !=0) v.addElement("static");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_VOLATILE) !=0) v.addElement("volatile");
|
||||
if ((access & ACC_TRANSIENT) !=0) v.addElement("transient");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns name of a field.
|
||||
*/
|
||||
public String getName(){
|
||||
return cls.getStringValue(name_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns internal signature of a field
|
||||
*/
|
||||
public String getInternalSig(){
|
||||
return cls.getStringValue(descriptor_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature of a field.
|
||||
*/
|
||||
public String getType(){
|
||||
return new TypeSignature(getInternalSig()).getFieldType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is synthetic.
|
||||
*/
|
||||
public boolean isSynthetic(){
|
||||
return isSynthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if field is deprecated.
|
||||
*/
|
||||
public boolean isDeprecated(){
|
||||
return isDeprecated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of constant value in cpool.
|
||||
*/
|
||||
public int getConstantValueIndex(){
|
||||
return (value_cpx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of attributes of field.
|
||||
*/
|
||||
public Vector<?> getAttributes(){
|
||||
return attrs;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Strores InnerClass data informastion.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
class InnerClassData implements RuntimeConstants {
|
||||
ClassData cls;
|
||||
|
||||
|
||||
int inner_class_info_index
|
||||
,outer_class_info_index
|
||||
,inner_name_index
|
||||
,access
|
||||
;
|
||||
|
||||
public InnerClassData(ClassData cls) {
|
||||
this.cls=cls;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Innerclass attribute data.
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
inner_class_info_index = in.readUnsignedShort();
|
||||
outer_class_info_index = in.readUnsignedShort();
|
||||
inner_name_index = in.readUnsignedShort();
|
||||
access = in.readUnsignedShort();
|
||||
} // end read
|
||||
|
||||
/**
|
||||
* Returns the access of this class or interface.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
} // end InnerClassData
|
@ -1,355 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.util.jar.*;
|
||||
|
||||
|
||||
/**
|
||||
* Strores flag values according to command line options
|
||||
* and sets path where to find classes.
|
||||
*
|
||||
* @author Sucheta Dambalkar
|
||||
*/
|
||||
public class JavapEnvironment {
|
||||
|
||||
//Access flags
|
||||
public static final int PRIVATE = 0;
|
||||
public static final int PROTECTED = 1;
|
||||
public static final int PACKAGE = 2;
|
||||
public static final int PUBLIC = 3;
|
||||
|
||||
//search path flags.
|
||||
private static final int start = 0;
|
||||
private static final int cmdboot= 1;
|
||||
private static final int sunboot = 2;
|
||||
private static final int javaclass= 3;
|
||||
private static final int cmdextdir= 4;
|
||||
private static final int javaext= 5;
|
||||
private static final int cmdclasspath= 6;
|
||||
private static final int envclasspath= 7;
|
||||
private static final int javaclasspath= 8;
|
||||
private static final int currentdir = 9;
|
||||
|
||||
|
||||
// JavapEnvironment flag settings
|
||||
boolean showLineAndLocal = false;
|
||||
int showAccess = PACKAGE;
|
||||
boolean showDisassembled = false;
|
||||
boolean showVerbose = false;
|
||||
boolean showInternalSigs = false;
|
||||
String classPathString = null;
|
||||
String bootClassPathString = null;
|
||||
String extDirsString = null;
|
||||
boolean extDirflag = false;
|
||||
boolean nothingToDo = true;
|
||||
boolean showallAttr = false;
|
||||
String classpath = null;
|
||||
int searchpath = start;
|
||||
|
||||
/**
|
||||
* According to which flags are set,
|
||||
* returns file input stream for classfile to disassemble.
|
||||
*/
|
||||
|
||||
public InputStream getFileInputStream(String Name){
|
||||
InputStream fileInStream = null;
|
||||
searchpath = cmdboot;
|
||||
try{
|
||||
if(searchpath == cmdboot){
|
||||
if(bootClassPathString != null){
|
||||
//search in specified bootclasspath.
|
||||
classpath = bootClassPathString;
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path.
|
||||
else searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = sunboot;
|
||||
}
|
||||
|
||||
if(searchpath == sunboot){
|
||||
if(System.getProperty("sun.boot.class.path") != null){
|
||||
//search in sun.boot.class.path
|
||||
classpath = System.getProperty("sun.boot.class.path");
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path
|
||||
else searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = javaclass;
|
||||
}
|
||||
|
||||
if(searchpath == javaclass){
|
||||
if(System.getProperty("java.class.path") != null){
|
||||
//search in java.class.path
|
||||
classpath =System.getProperty("java.class.path");
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path
|
||||
else searchpath = cmdextdir;
|
||||
}
|
||||
else searchpath = cmdextdir;
|
||||
}
|
||||
|
||||
if(searchpath == cmdextdir){
|
||||
if(extDirsString != null){
|
||||
//search in specified extdir.
|
||||
classpath = extDirsString;
|
||||
extDirflag = true;
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path
|
||||
else {
|
||||
searchpath = cmdclasspath;
|
||||
extDirflag = false;
|
||||
}
|
||||
}
|
||||
else searchpath = javaext;
|
||||
}
|
||||
|
||||
if(searchpath == javaext){
|
||||
if(System.getProperty("java.ext.dirs") != null){
|
||||
//search in java.ext.dirs
|
||||
classpath = System.getProperty("java.ext.dirs");
|
||||
extDirflag = true;
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path
|
||||
else {
|
||||
searchpath = cmdclasspath;
|
||||
extDirflag = false;
|
||||
}
|
||||
}
|
||||
else searchpath = cmdclasspath;
|
||||
}
|
||||
if(searchpath == cmdclasspath){
|
||||
if(classPathString != null){
|
||||
//search in specified classpath.
|
||||
classpath = classPathString;
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path
|
||||
else searchpath = 8;
|
||||
}
|
||||
else searchpath = envclasspath;
|
||||
}
|
||||
|
||||
if(searchpath == envclasspath){
|
||||
if(System.getProperty("env.class.path")!= null){
|
||||
//search in env.class.path
|
||||
classpath = System.getProperty("env.class.path");
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path.
|
||||
else searchpath = javaclasspath;
|
||||
}
|
||||
else searchpath = javaclasspath;
|
||||
}
|
||||
|
||||
if(searchpath == javaclasspath){
|
||||
if(("application.home") == null){
|
||||
//search in java.class.path
|
||||
classpath = System.getProperty("java.class.path");
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
//no classes found in search path.
|
||||
else searchpath = currentdir;
|
||||
}
|
||||
else searchpath = currentdir;
|
||||
}
|
||||
|
||||
if(searchpath == currentdir){
|
||||
classpath = ".";
|
||||
//search in current dir.
|
||||
if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
|
||||
else {
|
||||
//no classes found in search path.
|
||||
error("Could not find "+ Name);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}catch(SecurityException excsec){
|
||||
excsec.printStackTrace();
|
||||
error("fatal exception");
|
||||
}catch(NullPointerException excnull){
|
||||
excnull.printStackTrace();
|
||||
error("fatal exception");
|
||||
}catch(IllegalArgumentException excill){
|
||||
excill.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void error(String msg) {
|
||||
System.err.println("ERROR:" +msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves file name for classfile to disassemble.
|
||||
*/
|
||||
public InputStream resolvefilename(String name){
|
||||
String classname = name.replace('.', '/') + ".class";
|
||||
while (true) {
|
||||
InputStream instream = extDirflag
|
||||
? resolveExdirFilename(classname)
|
||||
: resolveclasspath(classname);
|
||||
if (instream != null)
|
||||
return instream;
|
||||
int lastindex = classname.lastIndexOf('/');
|
||||
if (lastindex == -1) return null;
|
||||
classname = classname.substring(0, lastindex) + "$" +
|
||||
classname.substring(lastindex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves file name for classfile to disassemble if flag exdir is set.
|
||||
*/
|
||||
public InputStream resolveExdirFilename(String classname){
|
||||
if(classpath.indexOf(File.pathSeparator) != -1){
|
||||
//separates path
|
||||
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
|
||||
while(st.hasMoreTokens()){
|
||||
String path = st.nextToken();
|
||||
InputStream in = resolveExdirFilenamehelper(path, classname);
|
||||
if (in != null)
|
||||
return in;
|
||||
}
|
||||
}else return (resolveExdirFilenamehelper(classpath, classname));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves file name for classfile to disassemble.
|
||||
*/
|
||||
public InputStream resolveclasspath(String classname){
|
||||
if(classpath.indexOf(File.pathSeparator) != -1){
|
||||
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
|
||||
//separates path.
|
||||
while(st.hasMoreTokens()){
|
||||
String path = (st.nextToken()).trim();
|
||||
InputStream in = resolveclasspathhelper(path, classname);
|
||||
if(in != null) return in;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else return (resolveclasspathhelper(classpath, classname));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns file input stream for classfile to disassemble if exdir is set.
|
||||
*/
|
||||
public InputStream resolveExdirFilenamehelper(String path, String classname){
|
||||
File fileobj = new File(path);
|
||||
if(fileobj.isDirectory()){
|
||||
// gets list of files in that directory.
|
||||
File[] filelist = fileobj.listFiles();
|
||||
for(int i = 0; i < filelist.length; i++){
|
||||
try{
|
||||
//file is a jar file.
|
||||
if(filelist[i].toString().endsWith(".jar")){
|
||||
JarFile jfile = new JarFile(filelist[i]);
|
||||
if((jfile.getEntry(classname)) != null){
|
||||
|
||||
InputStream filein = jfile.getInputStream(jfile.getEntry(classname));
|
||||
int bytearraysize = filein.available();
|
||||
byte []b = new byte[bytearraysize];
|
||||
int totalread = 0;
|
||||
while(totalread < bytearraysize){
|
||||
totalread += filein.read(b, totalread, bytearraysize-totalread);
|
||||
}
|
||||
InputStream inbyte = new ByteArrayInputStream(b);
|
||||
filein.close();
|
||||
return inbyte;
|
||||
}
|
||||
} else {
|
||||
//not a jar file.
|
||||
String filename = path+"/"+ classname;
|
||||
File file = new File(filename);
|
||||
if(file.isFile()){
|
||||
return (new FileInputStream(file));
|
||||
}
|
||||
}
|
||||
}catch(FileNotFoundException fnexce){
|
||||
fnexce.printStackTrace();
|
||||
error("cant read file");
|
||||
error("fatal exception");
|
||||
}catch(IOException ioexc){
|
||||
ioexc.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns file input stream for classfile to disassemble.
|
||||
*/
|
||||
public InputStream resolveclasspathhelper(String path, String classname){
|
||||
File fileobj = new File(path);
|
||||
try{
|
||||
if(fileobj.isDirectory()){
|
||||
//is a directory.
|
||||
String filename = path+"/"+ classname;
|
||||
File file = new File(filename);
|
||||
if(file.isFile()){
|
||||
return (new FileInputStream(file));
|
||||
}
|
||||
|
||||
}else if(fileobj.isFile()){
|
||||
if(fileobj.toString().endsWith(".jar")){
|
||||
//is a jar file.
|
||||
JarFile jfile = new JarFile(fileobj);
|
||||
if((jfile.getEntry(classname)) != null){
|
||||
InputStream filein = jfile.getInputStream(jfile.getEntry(classname));
|
||||
int bytearraysize = filein.available();
|
||||
byte []b = new byte[bytearraysize];
|
||||
int totalread = 0;
|
||||
while(totalread < bytearraysize){
|
||||
totalread += filein.read(b, totalread, bytearraysize-totalread);
|
||||
}
|
||||
InputStream inbyte = new ByteArrayInputStream(b);
|
||||
filein.close();
|
||||
return inbyte;
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(FileNotFoundException fnexce){
|
||||
fnexce.printStackTrace();
|
||||
error("cant read file");
|
||||
error("fatal exception");
|
||||
}catch(IOException ioexce){
|
||||
ioexce.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,919 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
|
||||
/**
|
||||
* Program to print information about class files
|
||||
*
|
||||
* @author Sucheta Dambalkar
|
||||
*/
|
||||
public class JavapPrinter {
|
||||
JavapEnvironment env;
|
||||
ClassData cls;
|
||||
byte[] code;
|
||||
String lP= "";
|
||||
PrintWriter out;
|
||||
|
||||
public JavapPrinter(InputStream cname, PrintWriter out, JavapEnvironment env){
|
||||
this.out = out;
|
||||
this.cls = new ClassData(cname);
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point to print class file information.
|
||||
*/
|
||||
public void print(){
|
||||
printclassHeader();
|
||||
printfields();
|
||||
printMethods();
|
||||
printend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a description of the class (not members).
|
||||
*/
|
||||
public void printclassHeader(){
|
||||
String srcName="";
|
||||
if ((srcName = cls.getSourceName()) != "null") // requires debug info
|
||||
out.println("Compiled from " + javaclassname(srcName));
|
||||
|
||||
if(cls.isInterface()) {
|
||||
// The only useful access modifier of an interface is
|
||||
// public; interfaces are always marked as abstract and
|
||||
// cannot be final.
|
||||
out.print((cls.isPublic()?"public ":"") +
|
||||
"interface "+ javaclassname(cls.getClassName()));
|
||||
}
|
||||
else if(cls.isClass()) {
|
||||
String []accflags = cls.getAccess();
|
||||
printAccess(accflags);
|
||||
out.print("class "+ javaclassname(cls.getClassName()));
|
||||
|
||||
if(cls.getSuperClassName() != null){
|
||||
out.print(" extends " + javaclassname(cls.getSuperClassName()));
|
||||
}
|
||||
}
|
||||
|
||||
String []interfacelist = cls.getSuperInterfaces();
|
||||
if(interfacelist.length > 0){
|
||||
if(cls.isClass()) {
|
||||
out.print(" implements ");
|
||||
}
|
||||
else if(cls.isInterface()){
|
||||
out.print(" extends ");
|
||||
}
|
||||
|
||||
for(int j = 0; j < interfacelist.length; j++){
|
||||
out.print(javaclassname(interfacelist[j]));
|
||||
|
||||
if((j+1) < interfacelist.length) {
|
||||
out.print(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print class attribute information.
|
||||
if((env.showallAttr) || (env.showVerbose)){
|
||||
printClassAttributes();
|
||||
}
|
||||
// Print verbose output.
|
||||
if(env.showVerbose){
|
||||
printverbosecls();
|
||||
}
|
||||
out.println("{");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print verbose output.
|
||||
*/
|
||||
public void printverbosecls(){
|
||||
out.println(" minor version: "+cls.getMinor_version());
|
||||
out.println(" major version: "+cls.getMajor_version());
|
||||
out.println(" Constant pool:");
|
||||
printcp();
|
||||
env.showallAttr = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print class attribute information.
|
||||
*/
|
||||
public void printClassAttributes(){
|
||||
out.println();
|
||||
AttrData[] clsattrs = cls.getAttributes();
|
||||
for(int i = 0; i < clsattrs.length; i++){
|
||||
String clsattrname = clsattrs[i].getAttrName();
|
||||
if(clsattrname.equals("SourceFile")){
|
||||
out.println(" SourceFile: "+ cls.getSourceName());
|
||||
}else if(clsattrname.equals("InnerClasses")){
|
||||
printInnerClasses();
|
||||
}else {
|
||||
printAttrData(clsattrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the fields
|
||||
*/
|
||||
public void printfields(){
|
||||
FieldData[] fields = cls.getFields();
|
||||
for(int f = 0; f < fields.length; f++){
|
||||
String[] accflags = fields[f].getAccess();
|
||||
if(checkAccess(accflags)){
|
||||
if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
|
||||
|| env.showInternalSigs || env.showallAttr)){
|
||||
out.print(" ");
|
||||
}
|
||||
printAccess(accflags);
|
||||
out.println(fields[f].getType()+" " +fields[f].getName()+";");
|
||||
if (env.showInternalSigs) {
|
||||
out.println(" Signature: " + (fields[f].getInternalSig()));
|
||||
}
|
||||
|
||||
// print field attribute information.
|
||||
if (env.showallAttr){
|
||||
printFieldAttributes(fields[f]);
|
||||
|
||||
}
|
||||
if((env.showDisassembled) || (env.showLineAndLocal)){
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* print field attribute information. */
|
||||
public void printFieldAttributes(FieldData field){
|
||||
Vector<?> fieldattrs = field.getAttributes();
|
||||
for(int j = 0; j < fieldattrs.size(); j++){
|
||||
String fieldattrname = ((AttrData)fieldattrs.elementAt(j)).getAttrName();
|
||||
if(fieldattrname.equals("ConstantValue")){
|
||||
printConstantValue(field);
|
||||
}else if (fieldattrname.equals("Deprecated")){
|
||||
out.println("Deprecated: "+ field.isDeprecated());
|
||||
}else if (fieldattrname.equals("Synthetic")){
|
||||
out.println(" Synthetic: "+ field.isSynthetic());
|
||||
}else {
|
||||
printAttrData((AttrData)fieldattrs.elementAt(j));
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the methods
|
||||
*/
|
||||
public void printMethods(){
|
||||
MethodData[] methods = cls.getMethods();
|
||||
for(int m = 0; m < methods.length; m++){
|
||||
String[] accflags = methods[m].getAccess();
|
||||
if(checkAccess(accflags)){
|
||||
if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
|
||||
|| env.showInternalSigs || env.showallAttr)){
|
||||
out.print(" ");
|
||||
}
|
||||
printMethodSignature(methods[m], accflags);
|
||||
printExceptions(methods[m]);
|
||||
out.println(";");
|
||||
|
||||
// Print internal signature of method.
|
||||
if (env.showInternalSigs){
|
||||
out.println(" Signature: " + (methods[m].getInternalSig()));
|
||||
}
|
||||
|
||||
//Print disassembled code.
|
||||
if(env.showDisassembled && ! env.showallAttr) {
|
||||
printcodeSequence(methods[m]);
|
||||
printExceptionTable(methods[m]);
|
||||
out.println();
|
||||
}
|
||||
|
||||
// Print line and local variable attribute information.
|
||||
if (env.showLineAndLocal) {
|
||||
printLineNumTable(methods[m]);
|
||||
printLocVarTable(methods[m]);
|
||||
out.println();
|
||||
}
|
||||
|
||||
// Print method attribute information.
|
||||
if (env.showallAttr){
|
||||
printMethodAttributes(methods[m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print method signature.
|
||||
*/
|
||||
public void printMethodSignature(MethodData method, String[] accflags){
|
||||
printAccess(accflags);
|
||||
|
||||
if((method.getName()).equals("<init>")){
|
||||
out.print(javaclassname(cls.getClassName()));
|
||||
out.print(method.getParameters());
|
||||
}else if((method.getName()).equals("<clinit>")){
|
||||
out.print("{}");
|
||||
}else{
|
||||
out.print(method.getReturnType()+" ");
|
||||
out.print(method.getName());
|
||||
out.print(method.getParameters());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* print method attribute information.
|
||||
*/
|
||||
public void printMethodAttributes(MethodData method){
|
||||
Vector<?> methodattrs = method.getAttributes();
|
||||
Vector<?> codeattrs = method.getCodeAttributes();
|
||||
for(int k = 0; k < methodattrs.size(); k++){
|
||||
String methodattrname = ((AttrData)methodattrs.elementAt(k)).getAttrName();
|
||||
if(methodattrname.equals("Code")){
|
||||
printcodeSequence(method);
|
||||
printExceptionTable(method);
|
||||
for(int c = 0; c < codeattrs.size(); c++){
|
||||
String codeattrname = ((AttrData)codeattrs.elementAt(c)).getAttrName();
|
||||
if(codeattrname.equals("LineNumberTable")){
|
||||
printLineNumTable(method);
|
||||
}else if(codeattrname.equals("LocalVariableTable")){
|
||||
printLocVarTable(method);
|
||||
}else if(codeattrname.equals("StackMapTable")) {
|
||||
// Java SE JSR 202 stack map tables
|
||||
printStackMapTable(method);
|
||||
}else if(codeattrname.equals("StackMap")) {
|
||||
// Java ME CLDC stack maps
|
||||
printStackMap(method);
|
||||
} else {
|
||||
printAttrData((AttrData)codeattrs.elementAt(c));
|
||||
}
|
||||
}
|
||||
}else if(methodattrname.equals("Exceptions")){
|
||||
out.println(" Exceptions: ");
|
||||
printExceptions(method);
|
||||
}else if (methodattrname.equals("Deprecated")){
|
||||
out.println(" Deprecated: "+ method.isDeprecated());
|
||||
}else if (methodattrname.equals("Synthetic")){
|
||||
out.println(" Synthetic: "+ method.isSynthetic());
|
||||
}else {
|
||||
printAttrData((AttrData)methodattrs.elementAt(k));
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print exceptions.
|
||||
*/
|
||||
public void printExceptions(MethodData method){
|
||||
int []exc_index_table = method.get_exc_index_table();
|
||||
if (exc_index_table != null) {
|
||||
if(!(env. showLineAndLocal || env.showDisassembled || env.showVerbose
|
||||
|| env.showInternalSigs || env.showallAttr)){
|
||||
out.print(" ");
|
||||
}
|
||||
out.print(" throws ");
|
||||
int k;
|
||||
int l = exc_index_table.length;
|
||||
|
||||
for (k=0; k<l; k++) {
|
||||
out.print(javaclassname(cls.getClassName(exc_index_table[k])));
|
||||
if (k<l-1) out.print(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print code sequence.
|
||||
*/
|
||||
public void printcodeSequence(MethodData method){
|
||||
code = method.getCode();
|
||||
if(code != null){
|
||||
out.println(" Code:");
|
||||
if(env.showVerbose){
|
||||
printVerboseHeader(method);
|
||||
}
|
||||
|
||||
for (int pc=0; pc < code.length; ) {
|
||||
out.print(" "+pc+":\t");
|
||||
pc=pc+printInstr(pc);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print instructions.
|
||||
*/
|
||||
public int printInstr(int pc){
|
||||
int opcode = getUbyte(pc);
|
||||
int opcode2;
|
||||
String mnem;
|
||||
switch (opcode) {
|
||||
case opc_nonpriv:
|
||||
case opc_priv:
|
||||
opcode2 = getUbyte(pc+1);
|
||||
mnem=Tables.opcName((opcode<<8)+opcode2);
|
||||
if (mnem==null)
|
||||
// assume all (even nonexistent) priv and nonpriv instructions
|
||||
// are 2 bytes long
|
||||
mnem=Tables.opcName(opcode)+" "+opcode2;
|
||||
out.print(mnem);
|
||||
return 2;
|
||||
case opc_wide: {
|
||||
opcode2 = getUbyte(pc+1);
|
||||
mnem=Tables.opcName((opcode<<8)+opcode2);
|
||||
if (mnem==null) {
|
||||
// nonexistent opcode - but we have to print something
|
||||
out.print("bytecode "+opcode);
|
||||
return 1;
|
||||
}
|
||||
out.print(mnem+" "+getUShort(pc+2));
|
||||
if (opcode2==opc_iinc) {
|
||||
out.print(", "+getShort(pc+4));
|
||||
return 6;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
mnem=Tables.opcName(opcode);
|
||||
if (mnem==null) {
|
||||
// nonexistent opcode - but we have to print something
|
||||
out.print("bytecode "+opcode);
|
||||
return 1;
|
||||
}
|
||||
if (opcode>opc_jsr_w) {
|
||||
// pseudo opcodes should be printed as bytecodes
|
||||
out.print("bytecode "+opcode);
|
||||
return 1;
|
||||
}
|
||||
out.print(Tables.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:
|
||||
out.print("\t"+getUbyte(pc+1));
|
||||
return 2;
|
||||
case opc_iinc:
|
||||
out.print("\t"+getUbyte(pc+1)+", "+getbyte(pc+2));
|
||||
return 3;
|
||||
case opc_tableswitch:{
|
||||
int tb=align(pc+1);
|
||||
int default_skip = getInt(tb); /* default skip pamount */
|
||||
int low = getInt(tb+4);
|
||||
int high = getInt(tb+8);
|
||||
int count = high - low;
|
||||
out.print("{ //"+low+" to "+high);
|
||||
for (int i = 0; i <= count; i++)
|
||||
out.print( "\n\t\t" + (i+low) + ": "+lP+(pc+getInt(tb+12+4*i))+";");
|
||||
out.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 = getInt(tb);
|
||||
int npairs = getInt(tb+4);
|
||||
out.print("{ //"+npairs);
|
||||
for (int i = 1; i <= npairs; i++)
|
||||
out.print("\n\t\t"+getInt(tb+i*8)
|
||||
+": "+lP+(pc+getInt(tb+4+i*8))+";"
|
||||
);
|
||||
out.print("\n\t\tdefault: "+lP+(default_skip + pc) + " }");
|
||||
return tb-pc+(npairs+1)*8;
|
||||
}
|
||||
case opc_newarray:
|
||||
int type=getUbyte(pc+1);
|
||||
switch (type) {
|
||||
case T_BOOLEAN:out.print(" boolean");break;
|
||||
case T_BYTE: out.print(" byte"); break;
|
||||
case T_CHAR: out.print(" char"); break;
|
||||
case T_SHORT: out.print(" short"); break;
|
||||
case T_INT: out.print(" int"); break;
|
||||
case T_LONG: out.print(" long"); break;
|
||||
case T_FLOAT: out.print(" float"); break;
|
||||
case T_DOUBLE: out.print(" double"); break;
|
||||
case T_CLASS: out.print(" class"); break;
|
||||
default: out.print(" BOGUS TYPE:"+type);
|
||||
}
|
||||
return 2;
|
||||
|
||||
case opc_anewarray: {
|
||||
int index = getUShort(pc+1);
|
||||
out.print("\t#"+index+"; //");
|
||||
PrintConstant(index);
|
||||
return 3;
|
||||
}
|
||||
|
||||
case opc_sipush:
|
||||
out.print("\t"+getShort(pc+1));
|
||||
return 3;
|
||||
|
||||
case opc_bipush:
|
||||
out.print("\t"+getbyte(pc+1));
|
||||
return 2;
|
||||
|
||||
case opc_ldc: {
|
||||
int index = getUbyte(pc+1);
|
||||
out.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 = getUShort(pc+1);
|
||||
out.print("\t#"+index+"; //");
|
||||
PrintConstant(index);
|
||||
return 3;
|
||||
}
|
||||
|
||||
case opc_invokeinterface: {
|
||||
int index = getUShort(pc+1), nargs=getUbyte(pc+3);
|
||||
out.print("\t#"+index+", "+nargs+"; //");
|
||||
PrintConstant(index);
|
||||
return 5;
|
||||
}
|
||||
|
||||
case opc_invokedynamic: {
|
||||
int index = getUShort(pc+1);
|
||||
out.print("\t#"+index+"; //");
|
||||
PrintConstant(index);
|
||||
return 5;
|
||||
}
|
||||
|
||||
case opc_multianewarray: {
|
||||
int index = getUShort(pc+1), dimensions=getUbyte(pc+3);
|
||||
out.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:
|
||||
out.print("\t"+lP+(pc + getShort(pc+1)) );
|
||||
return 3;
|
||||
|
||||
case opc_jsr_w:
|
||||
case opc_goto_w:
|
||||
out.print("\t"+lP+(pc + getInt(pc+1)));
|
||||
return 5;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Print code attribute details.
|
||||
*/
|
||||
public void printVerboseHeader(MethodData method) {
|
||||
int argCount = method.getArgumentlength();
|
||||
if (!method.isStatic())
|
||||
++argCount; // for 'this'
|
||||
|
||||
out.println(" Stack=" + method.getMaxStack()
|
||||
+ ", Locals=" + method.getMaxLocals()
|
||||
+ ", Args_size=" + argCount);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print the exception table for this method code
|
||||
*/
|
||||
void printExceptionTable(MethodData method){//throws IOException
|
||||
Vector<?> exception_table = method.getexception_table();
|
||||
if (exception_table.size() > 0) {
|
||||
out.println(" Exception table:");
|
||||
out.println(" from to target type");
|
||||
for (int idx = 0; idx < exception_table.size(); ++idx) {
|
||||
TrapData handler = (TrapData)exception_table.elementAt(idx);
|
||||
printFixedWidthInt(handler.start_pc, 6);
|
||||
printFixedWidthInt(handler.end_pc, 6);
|
||||
printFixedWidthInt(handler.handler_pc, 6);
|
||||
out.print(" ");
|
||||
int catch_cpx = handler.catch_cpx;
|
||||
if (catch_cpx == 0) {
|
||||
out.println("any");
|
||||
}else {
|
||||
out.print("Class ");
|
||||
out.println(cls.getClassName(catch_cpx));
|
||||
out.println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print LineNumberTable attribute information.
|
||||
*/
|
||||
public void printLineNumTable(MethodData method) {
|
||||
int numlines = method.getnumlines();
|
||||
Vector<?> lin_num_tb = method.getlin_num_tb();
|
||||
if( lin_num_tb.size() > 0){
|
||||
out.println(" LineNumberTable: ");
|
||||
for (int i=0; i<numlines; i++) {
|
||||
LineNumData linnumtb_entry=(LineNumData)lin_num_tb.elementAt(i);
|
||||
out.println(" line " + linnumtb_entry.line_number + ": "
|
||||
+ linnumtb_entry.start_pc);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print LocalVariableTable attribute information.
|
||||
*/
|
||||
public void printLocVarTable(MethodData method){
|
||||
int siz = method.getloc_var_tbsize();
|
||||
if(siz > 0){
|
||||
out.println(" LocalVariableTable: ");
|
||||
out.print(" ");
|
||||
out.println("Start Length Slot Name Signature");
|
||||
}
|
||||
Vector<?> loc_var_tb = method.getloc_var_tb();
|
||||
|
||||
for (int i=0; i<siz; i++) {
|
||||
LocVarData entry=(LocVarData)loc_var_tb.elementAt(i);
|
||||
|
||||
out.println(" "+entry.start_pc+" "+entry.length+" "+
|
||||
entry.slot+" "+cls.StringValue(entry.name_cpx) +
|
||||
" "+cls.StringValue(entry.sig_cpx));
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print StackMap attribute information.
|
||||
*/
|
||||
public void printStackMap(MethodData method) {
|
||||
StackMapData[] stack_map_tb = method.getStackMap();
|
||||
int number_of_entries = stack_map_tb.length;
|
||||
if (number_of_entries > 0) {
|
||||
out.println(" StackMap: number_of_entries = " + number_of_entries);
|
||||
|
||||
for (StackMapData frame : stack_map_tb) {
|
||||
frame.print(this);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print StackMapTable attribute information.
|
||||
*/
|
||||
public void printStackMapTable(MethodData method) {
|
||||
StackMapTableData[] stack_map_tb = method.getStackMapTable();
|
||||
int number_of_entries = stack_map_tb.length;
|
||||
if (number_of_entries > 0) {
|
||||
out.println(" StackMapTable: number_of_entries = " + number_of_entries);
|
||||
|
||||
for (StackMapTableData frame : stack_map_tb) {
|
||||
frame.print(this);
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
void printMap(String name, int[] map) {
|
||||
out.print(name);
|
||||
for (int i=0; i<map.length; i++) {
|
||||
int fulltype = map[i];
|
||||
int type = fulltype & 0xFF;
|
||||
int argument = fulltype >> 8;
|
||||
switch (type) {
|
||||
case ITEM_Object:
|
||||
out.print(" ");
|
||||
PrintConstant(argument);
|
||||
break;
|
||||
case ITEM_NewObject:
|
||||
out.print(" " + Tables.mapTypeName(type));
|
||||
out.print(" " + argument);
|
||||
break;
|
||||
default:
|
||||
out.print(" " + Tables.mapTypeName(type));
|
||||
}
|
||||
out.print( (i==(map.length-1)? ' ' : ','));
|
||||
}
|
||||
out.println("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print ConstantValue attribute information.
|
||||
*/
|
||||
public void printConstantValue(FieldData field){
|
||||
out.print(" Constant value: ");
|
||||
int cpx = (field.getConstantValueIndex());
|
||||
byte tag=0;
|
||||
try {
|
||||
tag=cls.getTag(cpx);
|
||||
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
out.print("Error:");
|
||||
return;
|
||||
}
|
||||
switch (tag) {
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_FIELD: {
|
||||
CPX2 x = cls.getCpoolEntry(cpx);
|
||||
if (x.cpx1 == cls.getthis_cpx()) {
|
||||
// don't print class part for local references
|
||||
cpx=x.cpx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print InnerClass attribute information.
|
||||
*/
|
||||
public void printInnerClasses(){//throws ioexception
|
||||
|
||||
InnerClassData[] innerClasses = cls.getInnerClasses();
|
||||
if(innerClasses != null){
|
||||
if(innerClasses.length > 0){
|
||||
out.print(" ");
|
||||
out.println("InnerClass: ");
|
||||
for(int i = 0 ; i < innerClasses.length; i++){
|
||||
out.print(" ");
|
||||
//access
|
||||
String[] accflags = innerClasses[i].getAccess();
|
||||
if(checkAccess(accflags)){
|
||||
printAccess(accflags);
|
||||
if (innerClasses[i].inner_name_index!=0) {
|
||||
out.print("#"+innerClasses[i].inner_name_index+"= ");
|
||||
}
|
||||
out.print("#"+innerClasses[i].inner_class_info_index);
|
||||
if (innerClasses[i].outer_class_info_index!=0) {
|
||||
out.print(" of #"+innerClasses[i].outer_class_info_index);
|
||||
}
|
||||
out.print("; //");
|
||||
if (innerClasses[i].inner_name_index!=0) {
|
||||
out.print(cls.getName(innerClasses[i].inner_name_index)+"=");
|
||||
}
|
||||
PrintConstant(innerClasses[i].inner_class_info_index);
|
||||
if (innerClasses[i].outer_class_info_index!=0) {
|
||||
out.print(" of ");
|
||||
PrintConstant(innerClasses[i].outer_class_info_index);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print constant pool information.
|
||||
*/
|
||||
public void printcp(){
|
||||
int cpx = 1 ;
|
||||
|
||||
while (cpx < cls.getCpoolCount()) {
|
||||
out.print("const #"+cpx+" = ");
|
||||
cpx+=PrintlnConstantEntry(cpx);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print constant pool entry information.
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public int PrintlnConstantEntry(int cpx) {
|
||||
int size=1;
|
||||
byte tag=0;
|
||||
try {
|
||||
tag=cls.getTag(cpx);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
out.println(" <Incorrect CP index>");
|
||||
return 1;
|
||||
}
|
||||
out.print(cls.StringTag(cpx)+"\t");
|
||||
Object x=cls.getCpoolEntryobj(cpx);
|
||||
if (x==null) {
|
||||
switch (tag) {
|
||||
case CONSTANT_LONG:
|
||||
case CONSTANT_DOUBLE:
|
||||
size=2;
|
||||
}
|
||||
out.println("null;");
|
||||
return size;
|
||||
}
|
||||
String str=cls.StringValue(cpx);
|
||||
|
||||
switch (tag) {
|
||||
case CONSTANT_CLASS:
|
||||
case CONSTANT_STRING:
|
||||
out.println("#"+(((CPX)x).cpx)+";\t// "+str);
|
||||
break;
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
out.println("#"+((CPX2)x).cpx1+".#"+((CPX2)x).cpx2+";\t// "+str);
|
||||
break;
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
out.println("#"+((CPX2)x).cpx1+":#"+((CPX2)x).cpx2+";// "+str);
|
||||
break;
|
||||
case CONSTANT_LONG:
|
||||
case CONSTANT_DOUBLE:
|
||||
size=2;
|
||||
// fall through
|
||||
default:
|
||||
out.println(str+";");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks access of class, field or method.
|
||||
*/
|
||||
public boolean checkAccess(String accflags[]){
|
||||
|
||||
boolean ispublic = false;
|
||||
boolean isprotected = false;
|
||||
boolean isprivate = false;
|
||||
boolean ispackage = false;
|
||||
|
||||
for(int i= 0; i < accflags.length; i++){
|
||||
if(accflags[i].equals("public")) ispublic = true;
|
||||
else if (accflags[i].equals("protected")) isprotected = true;
|
||||
else if (accflags[i].equals("private")) isprivate = true;
|
||||
}
|
||||
|
||||
if(!(ispublic || isprotected || isprivate)) ispackage = true;
|
||||
|
||||
if((env.showAccess == env.PUBLIC) && (isprotected || isprivate || ispackage)) return false;
|
||||
else if((env.showAccess == env.PROTECTED) && (isprivate || ispackage)) return false;
|
||||
else if((env.showAccess == env.PACKAGE) && (isprivate)) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints access of class, field or method.
|
||||
*/
|
||||
public void printAccess(String []accflags){
|
||||
for(int j = 0; j < accflags.length; j++){
|
||||
out.print(accflags[j]+" ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an integer so that it takes 'length' characters in
|
||||
* the output. Temporary until formatting code is stable.
|
||||
*/
|
||||
public void printFixedWidthInt(long x, int length) {
|
||||
CharArrayWriter baStream = new CharArrayWriter();
|
||||
PrintWriter pStream = new PrintWriter(baStream);
|
||||
pStream.print(x);
|
||||
String str = baStream.toString();
|
||||
for (int cnt = length - str.length(); cnt > 0; --cnt)
|
||||
out.print(' ');
|
||||
out.print(str);
|
||||
}
|
||||
|
||||
protected int getbyte (int pc) {
|
||||
return code[pc];
|
||||
}
|
||||
|
||||
protected int getUbyte (int pc) {
|
||||
return code[pc]&0xFF;
|
||||
}
|
||||
|
||||
int getShort (int pc) {
|
||||
return (code[pc]<<8) | (code[pc+1]&0xFF);
|
||||
}
|
||||
|
||||
int getUShort (int pc) {
|
||||
return ((code[pc]<<8) | (code[pc+1]&0xFF))&0xFFFF;
|
||||
}
|
||||
|
||||
protected int getInt (int pc) {
|
||||
return (getShort(pc)<<16) | (getShort(pc+2)&0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print constant value at that index.
|
||||
*/
|
||||
void PrintConstant(int cpx) {
|
||||
if (cpx==0) {
|
||||
out.print("#0");
|
||||
return;
|
||||
}
|
||||
byte tag=0;
|
||||
try {
|
||||
tag=cls.getTag(cpx);
|
||||
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
out.print("#"+cpx);
|
||||
return;
|
||||
}
|
||||
switch (tag) {
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_FIELD: {
|
||||
// CPX2 x=(CPX2)(cpool[cpx]);
|
||||
CPX2 x = cls.getCpoolEntry(cpx);
|
||||
if (x.cpx1 == cls.getthis_cpx()) {
|
||||
// don't print class part for local references
|
||||
cpx=x.cpx2;
|
||||
}
|
||||
}
|
||||
}
|
||||
out.print(cls.TagString(tag)+" "+ cls.StringValue(cpx));
|
||||
}
|
||||
|
||||
protected static int align (int n) {
|
||||
return (n+3) & ~3 ;
|
||||
}
|
||||
|
||||
public void printend(){
|
||||
out.println("}");
|
||||
out.println();
|
||||
}
|
||||
|
||||
public String javaclassname(String name){
|
||||
return name.replace('/','.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Print attribute data in hex.
|
||||
*/
|
||||
public void printAttrData(AttrData attr){
|
||||
byte []data = attr.getData();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
out.print(" "+attr.getAttrName()+": ");
|
||||
out.println("length = " + cls.toHex(attr.datalen));
|
||||
|
||||
out.print(" ");
|
||||
|
||||
|
||||
while (i < data.length){
|
||||
String databytestring = cls.toHex(data[i]);
|
||||
if(databytestring.equals("0x")) out.print("00");
|
||||
else if(databytestring.substring(2).length() == 1){
|
||||
out.print("0"+databytestring.substring(2));
|
||||
} else{
|
||||
out.print(databytestring.substring(2));
|
||||
}
|
||||
|
||||
j++;
|
||||
if(j == 16) {
|
||||
out.println();
|
||||
out.print(" ");
|
||||
j = 0;
|
||||
}
|
||||
else out.print(" ");
|
||||
i++;
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Entry point for javap, class file disassembler.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from old javap)
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
private Vector<String> classList = new Vector<String>();
|
||||
private PrintWriter out;
|
||||
JavapEnvironment env = new JavapEnvironment();
|
||||
private static boolean errorOccurred = false;
|
||||
private static final String progname = "javap";
|
||||
|
||||
|
||||
public Main(PrintWriter out){
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Entry point for tool if you don't want System.exit() called.
|
||||
*/
|
||||
public static void entry(String argv[]) {
|
||||
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
|
||||
try {
|
||||
|
||||
Main jpmain = new Main(out);
|
||||
jpmain.perform(argv);
|
||||
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the arguments and perform the desired action
|
||||
*/
|
||||
private void perform(String argv[]) {
|
||||
if (parseArguments(argv)) {
|
||||
displayResults();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void error(String msg) {
|
||||
errorOccurred = true;
|
||||
System.err.println(msg);
|
||||
System.err.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print usage information
|
||||
*/
|
||||
private void usage() {
|
||||
java.io.PrintStream out = System.out;
|
||||
out.println("Usage: " + progname + " <options> <classes>...");
|
||||
out.println();
|
||||
out.println("where options include:");
|
||||
out.println(" -c Disassemble the code");
|
||||
out.println(" -classpath <pathlist> Specify where to find user class files");
|
||||
out.println(" -extdirs <dirs> Override location of installed extensions");
|
||||
out.println(" -help Print this usage message");
|
||||
out.println(" -J<flag> Pass <flag> directly to the runtime system");
|
||||
out.println(" -l Print line number and local variable tables");
|
||||
out.println(" -public Show only public classes and members");
|
||||
out.println(" -protected Show protected/public classes and members");
|
||||
out.println(" -package Show package/protected/public classes");
|
||||
out.println(" and members (default)");
|
||||
out.println(" -private Show all classes and members");
|
||||
out.println(" -s Print internal type signatures");
|
||||
out.println(" -bootclasspath <pathlist> Override location of class files loaded");
|
||||
out.println(" by the bootstrap class loader");
|
||||
out.println(" -verbose Print stack size, number of locals and args for methods");
|
||||
out.println(" If verifying, print reasons for failure");
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the command line arguments.
|
||||
* Set flags, construct the class list and create environment.
|
||||
*/
|
||||
private boolean parseArguments(String argv[]) {
|
||||
for (int i = 0 ; i < argv.length ; i++) {
|
||||
String arg = argv[i];
|
||||
if (arg.startsWith("-")) {
|
||||
if (arg.equals("-l")) {
|
||||
env.showLineAndLocal = true;
|
||||
} else if (arg.equals("-private") || arg.equals("-p")) {
|
||||
env.showAccess = env.PRIVATE;
|
||||
} else if (arg.equals("-package")) {
|
||||
env.showAccess = env.PACKAGE;
|
||||
} else if (arg.equals("-protected")) {
|
||||
env.showAccess = env.PROTECTED;
|
||||
} else if (arg.equals("-public")) {
|
||||
env.showAccess = env.PUBLIC;
|
||||
} else if (arg.equals("-c")) {
|
||||
env.showDisassembled = true;
|
||||
} else if (arg.equals("-s")) {
|
||||
env.showInternalSigs = true;
|
||||
} else if (arg.equals("-verbose")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-v")) {
|
||||
env.showVerbose = true;
|
||||
} else if (arg.equals("-h")) {
|
||||
error("-h is no longer available - use the 'javah' program");
|
||||
return false;
|
||||
} else if (arg.equals("-verify")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-verify-verbose")) {
|
||||
error("-verify is no longer available - use 'java -verify'");
|
||||
return false;
|
||||
} else if (arg.equals("-help")) {
|
||||
usage();
|
||||
return false;
|
||||
} else if (arg.equals("-classpath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.classPathString = argv[++i];
|
||||
} else {
|
||||
error("-classpath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-bootclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.bootClassPathString = argv[++i];
|
||||
} else {
|
||||
error("-bootclasspath requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-extdirs")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
env.extDirsString = argv[++i];
|
||||
} else {
|
||||
error("-extdirs requires argument");
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else if (arg.equals("-all")) {
|
||||
env.showallAttr = true;
|
||||
} else if (arg.equals("-Xold")) {
|
||||
// ignore: this is old javap
|
||||
} else {
|
||||
error("invalid flag: " + arg);
|
||||
usage();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
classList.addElement(arg);
|
||||
env.nothingToDo = false;
|
||||
}
|
||||
}
|
||||
if (env.nothingToDo) {
|
||||
System.out.println("No classes were specified on the command line. Try -help.");
|
||||
errorOccurred = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display results
|
||||
*/
|
||||
private void displayResults() {
|
||||
for (int i = 0; i < classList.size() ; i++ ) {
|
||||
String Name = classList.elementAt(i);
|
||||
InputStream classin = env.getFileInputStream(Name);
|
||||
|
||||
try {
|
||||
JavapPrinter printer = new JavapPrinter(classin, out, env);
|
||||
printer.print(); // actual do display
|
||||
|
||||
} catch (IllegalArgumentException exc) {
|
||||
error(exc.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,416 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
|
||||
/**
|
||||
* Strores method data informastion.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
public class MethodData {
|
||||
|
||||
ClassData cls;
|
||||
int access;
|
||||
int name_index;
|
||||
int descriptor_index;
|
||||
int attributes_count;
|
||||
byte[] code;
|
||||
Vector<TrapData> exception_table = new Vector<TrapData>(0);
|
||||
Vector<LineNumData> lin_num_tb = new Vector<LineNumData>(0);
|
||||
Vector<LocVarData> loc_var_tb = new Vector<LocVarData>(0);
|
||||
StackMapTableData[] stackMapTable;
|
||||
StackMapData[] stackMap;
|
||||
int[] exc_index_table=null;
|
||||
Vector<AttrData> attrs=new Vector<AttrData>(0);
|
||||
Vector<AttrData> code_attrs=new Vector<AttrData>(0);
|
||||
int max_stack, max_locals;
|
||||
boolean isSynthetic=false;
|
||||
boolean isDeprecated=false;
|
||||
|
||||
public MethodData(ClassData cls){
|
||||
this.cls=cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read method info.
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
access = in.readUnsignedShort();
|
||||
name_index=in.readUnsignedShort();
|
||||
descriptor_index =in.readUnsignedShort();
|
||||
int attributes_count = in.readUnsignedShort();
|
||||
for (int i = 0; i < attributes_count; i++) {
|
||||
int attr_name_index=in.readUnsignedShort();
|
||||
|
||||
readAttr: {
|
||||
if (cls.getTag(attr_name_index)==CONSTANT_UTF8) {
|
||||
String attr_name=cls.getString(attr_name_index);
|
||||
if ( attr_name.equals("Code")){
|
||||
readCode (in);
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
break readAttr;
|
||||
} else if ( attr_name.equals("Exceptions")){
|
||||
readExceptions(in);
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
break readAttr;
|
||||
} else if (attr_name.equals("Synthetic")){
|
||||
if (in.readInt()!=0)
|
||||
throw new ClassFormatError("invalid Synthetic attr length");
|
||||
isSynthetic=true;
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
break readAttr;
|
||||
} else if (attr_name.equals("Deprecated")){
|
||||
if (in.readInt()!=0)
|
||||
throw new ClassFormatError("invalid Synthetic attr length");
|
||||
isDeprecated = true;
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index);
|
||||
attrs.addElement(attr);
|
||||
break readAttr;
|
||||
}
|
||||
}
|
||||
AttrData attr=new AttrData(cls);
|
||||
attr.read(attr_name_index, in);
|
||||
attrs.addElement(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read code attribute info.
|
||||
*/
|
||||
public void readCode(DataInputStream in) throws IOException {
|
||||
|
||||
int attr_length = in.readInt();
|
||||
max_stack=in.readUnsignedShort();
|
||||
max_locals=in.readUnsignedShort();
|
||||
int codelen=in.readInt();
|
||||
|
||||
code=new byte[codelen];
|
||||
int totalread = 0;
|
||||
while(totalread < codelen){
|
||||
totalread += in.read(code, totalread, codelen-totalread);
|
||||
}
|
||||
// in.read(code, 0, codelen);
|
||||
int clen = 0;
|
||||
readExceptionTable(in);
|
||||
int code_attributes_count = in.readUnsignedShort();
|
||||
|
||||
for (int k = 0 ; k < code_attributes_count ; k++) {
|
||||
int table_name_index=in.readUnsignedShort();
|
||||
int table_name_tag=cls.getTag(table_name_index);
|
||||
AttrData attr=new AttrData(cls);
|
||||
if (table_name_tag==CONSTANT_UTF8) {
|
||||
String table_name_tstr=cls.getString(table_name_index);
|
||||
if (table_name_tstr.equals("LineNumberTable")) {
|
||||
readLineNumTable(in);
|
||||
attr.read(table_name_index);
|
||||
} else if (table_name_tstr.equals("LocalVariableTable")) {
|
||||
readLocVarTable(in);
|
||||
attr.read(table_name_index);
|
||||
} else if (table_name_tstr.equals("StackMapTable")) {
|
||||
readStackMapTable(in);
|
||||
attr.read(table_name_index);
|
||||
} else if (table_name_tstr.equals("StackMap")) {
|
||||
readStackMap(in);
|
||||
attr.read(table_name_index);
|
||||
} else {
|
||||
attr.read(table_name_index, in);
|
||||
}
|
||||
code_attrs.addElement(attr);
|
||||
continue;
|
||||
}
|
||||
|
||||
attr.read(table_name_index, in);
|
||||
code_attrs.addElement(attr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read exception table info.
|
||||
*/
|
||||
void readExceptionTable (DataInputStream in) throws IOException {
|
||||
int exception_table_len=in.readUnsignedShort();
|
||||
exception_table=new Vector<TrapData>(exception_table_len);
|
||||
for (int l = 0; l < exception_table_len; l++) {
|
||||
exception_table.addElement(new TrapData(in, l));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read LineNumberTable attribute info.
|
||||
*/
|
||||
void readLineNumTable (DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); // attr_length
|
||||
int lin_num_tb_len = in.readUnsignedShort();
|
||||
lin_num_tb=new Vector<LineNumData>(lin_num_tb_len);
|
||||
for (int l = 0; l < lin_num_tb_len; l++) {
|
||||
lin_num_tb.addElement(new LineNumData(in));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read LocalVariableTable attribute info.
|
||||
*/
|
||||
void readLocVarTable (DataInputStream in) throws IOException {
|
||||
int attr_len=in.readInt(); // attr_length
|
||||
int loc_var_tb_len = in.readUnsignedShort();
|
||||
loc_var_tb = new Vector<LocVarData>(loc_var_tb_len);
|
||||
for (int l = 0; l < loc_var_tb_len; l++) {
|
||||
loc_var_tb.addElement(new LocVarData(in));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Exception attribute info.
|
||||
*/
|
||||
public void readExceptions(DataInputStream in) throws IOException {
|
||||
int attr_len=in.readInt(); // attr_length in prog
|
||||
int num_exceptions = in.readUnsignedShort();
|
||||
exc_index_table=new int[num_exceptions];
|
||||
for (int l = 0; l < num_exceptions; l++) {
|
||||
int exc=in.readShort();
|
||||
exc_index_table[l]=exc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read StackMapTable attribute info.
|
||||
*/
|
||||
void readStackMapTable(DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); //attr_length
|
||||
int stack_map_tb_len = in.readUnsignedShort();
|
||||
stackMapTable = new StackMapTableData[stack_map_tb_len];
|
||||
for (int i=0; i<stack_map_tb_len; i++) {
|
||||
stackMapTable[i] = StackMapTableData.getInstance(in, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read StackMap attribute info.
|
||||
*/
|
||||
void readStackMap(DataInputStream in) throws IOException {
|
||||
int attr_len = in.readInt(); //attr_length
|
||||
int stack_map_len = in.readUnsignedShort();
|
||||
stackMap = new StackMapData[stack_map_len];
|
||||
for (int i = 0; i<stack_map_len; i++) {
|
||||
stackMap[i] = new StackMapData(in, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return access of the method.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
|
||||
Vector<String> v = new Vector<String>();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_PRIVATE) !=0) v.addElement("private");
|
||||
if ((access & ACC_PROTECTED) !=0) v.addElement("protected");
|
||||
if ((access & ACC_STATIC) !=0) v.addElement("static");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_SYNCHRONIZED) !=0) v.addElement("synchronized");
|
||||
if ((access & ACC_NATIVE) !=0) v.addElement("native");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
if ((access & ACC_STRICT) !=0) v.addElement("strictfp");
|
||||
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return name of the method.
|
||||
*/
|
||||
public String getName(){
|
||||
return cls.getStringValue(name_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal siganature of the method.
|
||||
*/
|
||||
public String getInternalSig(){
|
||||
return cls.getStringValue(descriptor_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return java return type signature of method.
|
||||
*/
|
||||
public String getReturnType(){
|
||||
|
||||
String rttype = (new TypeSignature(getInternalSig())).getReturnType();
|
||||
return rttype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return java type parameter signature.
|
||||
*/
|
||||
public String getParameters(){
|
||||
String ptype = (new TypeSignature(getInternalSig())).getParameters();
|
||||
|
||||
return ptype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return code attribute data of a method.
|
||||
*/
|
||||
public byte[] getCode(){
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LineNumberTable size.
|
||||
*/
|
||||
public int getnumlines(){
|
||||
return lin_num_tb.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LineNumberTable
|
||||
*/
|
||||
public Vector<?> getlin_num_tb(){
|
||||
return lin_num_tb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return LocalVariableTable size.
|
||||
*/
|
||||
public int getloc_var_tbsize(){
|
||||
return loc_var_tb.size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return LocalVariableTable.
|
||||
*/
|
||||
public Vector<?> getloc_var_tb(){
|
||||
return loc_var_tb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return StackMap.
|
||||
*/
|
||||
public StackMapData[] getStackMap() {
|
||||
return stackMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return StackMapTable.
|
||||
*/
|
||||
public StackMapTableData[] getStackMapTable() {
|
||||
return stackMapTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of arguments of that method.
|
||||
*/
|
||||
public int getArgumentlength(){
|
||||
return new TypeSignature(getInternalSig()).getArgumentlength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if method is static
|
||||
*/
|
||||
public boolean isStatic(){
|
||||
if ((access & ACC_STATIC) !=0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return max depth of operand stack.
|
||||
*/
|
||||
public int getMaxStack(){
|
||||
return max_stack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return number of local variables.
|
||||
*/
|
||||
public int getMaxLocals(){
|
||||
return max_locals;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return exception index table in Exception attribute.
|
||||
*/
|
||||
public int []get_exc_index_table(){
|
||||
return exc_index_table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return exception table in code attributre.
|
||||
*/
|
||||
public Vector<?> getexception_table(){
|
||||
return exception_table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return method attributes.
|
||||
*/
|
||||
public Vector<?> getAttributes(){
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return code attributes.
|
||||
*/
|
||||
public Vector<?> getCodeAttributes(){
|
||||
return code_attrs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if method id synthetic.
|
||||
*/
|
||||
public boolean isSynthetic(){
|
||||
return isSynthetic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if method is deprecated.
|
||||
*/
|
||||
public boolean isDeprecated(){
|
||||
return isDeprecated;
|
||||
}
|
||||
}
|
@ -1,787 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2005 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 sun.tools.javap;
|
||||
|
||||
public interface RuntimeConstants {
|
||||
|
||||
/* Signature Characters */
|
||||
public static final char SIGC_VOID = 'V';
|
||||
public static final String SIG_VOID = "V";
|
||||
public static final char SIGC_BOOLEAN = 'Z';
|
||||
public static final String SIG_BOOLEAN = "Z";
|
||||
public static final char SIGC_BYTE = 'B';
|
||||
public static final String SIG_BYTE = "B";
|
||||
public static final char SIGC_CHAR = 'C';
|
||||
public static final String SIG_CHAR = "C";
|
||||
public static final char SIGC_SHORT = 'S';
|
||||
public static final String SIG_SHORT = "S";
|
||||
public static final char SIGC_INT = 'I';
|
||||
public static final String SIG_INT = "I";
|
||||
public static final char SIGC_LONG = 'J';
|
||||
public static final String SIG_LONG = "J";
|
||||
public static final char SIGC_FLOAT = 'F';
|
||||
public static final String SIG_FLOAT = "F";
|
||||
public static final char SIGC_DOUBLE = 'D';
|
||||
public static final String SIG_DOUBLE = "D";
|
||||
public static final char SIGC_ARRAY = '[';
|
||||
public static final String SIG_ARRAY = "[";
|
||||
public static final char SIGC_CLASS = 'L';
|
||||
public static final String SIG_CLASS = "L";
|
||||
public static final char SIGC_METHOD = '(';
|
||||
public static final String SIG_METHOD = "(";
|
||||
public static final char SIGC_ENDCLASS = ';';
|
||||
public static final String SIG_ENDCLASS = ";";
|
||||
public static final char SIGC_ENDMETHOD = ')';
|
||||
public static final String SIG_ENDMETHOD = ")";
|
||||
public static final char SIGC_PACKAGE = '/';
|
||||
public static final String SIG_PACKAGE = "/";
|
||||
|
||||
/* Class File Constants */
|
||||
public static final int JAVA_MAGIC = 0xcafebabe;
|
||||
public static final int JAVA_VERSION = 45;
|
||||
public static final int JAVA_MINOR_VERSION = 3;
|
||||
|
||||
/* Constant table */
|
||||
public static final int CONSTANT_UTF8 = 1;
|
||||
public static final int CONSTANT_UNICODE = 2;
|
||||
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_FIELD = 9;
|
||||
public static final int CONSTANT_METHOD = 10;
|
||||
public static final int CONSTANT_INTERFACEMETHOD = 11;
|
||||
public static final int CONSTANT_NAMEANDTYPE = 12;
|
||||
|
||||
/* Access Flags */
|
||||
public static final int ACC_PUBLIC = 0x00000001;
|
||||
public static final int ACC_PRIVATE = 0x00000002;
|
||||
public static final int ACC_PROTECTED = 0x00000004;
|
||||
public static final int ACC_STATIC = 0x00000008;
|
||||
public static final int ACC_FINAL = 0x00000010;
|
||||
public static final int ACC_SYNCHRONIZED = 0x00000020;
|
||||
public static final int ACC_SUPER = 0x00000020;
|
||||
public static final int ACC_VOLATILE = 0x00000040;
|
||||
public static final int ACC_TRANSIENT = 0x00000080;
|
||||
public static final int ACC_NATIVE = 0x00000100;
|
||||
public static final int ACC_INTERFACE = 0x00000200;
|
||||
public static final int ACC_ABSTRACT = 0x00000400;
|
||||
public static final int ACC_STRICT = 0x00000800;
|
||||
public static final int ACC_EXPLICIT = 0x00001000;
|
||||
public static final int ACC_SYNTHETIC = 0x00010000; // actually, this is an attribute
|
||||
|
||||
/* Type codes */
|
||||
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;
|
||||
|
||||
/* Type codes for StackMap attribute */
|
||||
public static final int ITEM_Bogus =0; // an unknown or uninitialized value
|
||||
public static final int ITEM_Integer =1; // a 32-bit integer
|
||||
public static final int ITEM_Float =2; // not used
|
||||
public static final int ITEM_Double =3; // not used
|
||||
public static final int ITEM_Long =4; // a 64-bit integer
|
||||
public static final int ITEM_Null =5; // the type of null
|
||||
public static final int ITEM_InitObject =6; // "this" in constructor
|
||||
public static final int ITEM_Object =7; // followed by 2-byte index of class name
|
||||
public static final int ITEM_NewObject =8; // followed by 2-byte ref to "new"
|
||||
|
||||
/* Constants used in StackMapTable attribute */
|
||||
public static final int SAME_FRAME_BOUND = 64;
|
||||
public static final int SAME_LOCALS_1_STACK_ITEM_BOUND = 128;
|
||||
public static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
|
||||
public static final int SAME_FRAME_EXTENDED = 251;
|
||||
public static final int FULL_FRAME = 255;
|
||||
|
||||
/* 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_invokedynamic = 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 */
|
||||
public 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",
|
||||
"invokedynamic",
|
||||
"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 */
|
||||
public 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
|
||||
};
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005 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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
|
||||
/* represents one entry of StackMap attribute
|
||||
*/
|
||||
class StackMapData {
|
||||
final int offset;
|
||||
final int[] locals;
|
||||
final int[] stack;
|
||||
|
||||
StackMapData(int offset, int[] locals, int[] stack) {
|
||||
this.offset = offset;
|
||||
this.locals = locals;
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
StackMapData(DataInputStream in, MethodData method) throws IOException {
|
||||
offset = in.readUnsignedShort();
|
||||
int local_size = in.readUnsignedShort();
|
||||
locals = readTypeArray(in, local_size, method);
|
||||
int stack_size = in.readUnsignedShort();
|
||||
stack = readTypeArray(in, stack_size, method);
|
||||
}
|
||||
|
||||
static final int[] readTypeArray(DataInputStream in, int length, MethodData method) throws IOException {
|
||||
int[] types = new int[length];
|
||||
for (int i=0; i<length; i++) {
|
||||
types[i] = readType(in, method);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
static final int readType(DataInputStream in, MethodData method) throws IOException {
|
||||
int type = in.readUnsignedByte();
|
||||
if (type == ITEM_Object || type == ITEM_NewObject) {
|
||||
type = type | (in.readUnsignedShort()<<8);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
void print(JavapPrinter p) {
|
||||
p.out.println(" " + offset + ":");
|
||||
p.printMap(" locals = [", locals);
|
||||
p.printMap(" stack = [", stack);
|
||||
}
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005 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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static sun.tools.javap.RuntimeConstants.*;
|
||||
|
||||
/* represents one entry of StackMapTable attribute
|
||||
*/
|
||||
class StackMapTableData {
|
||||
final int frameType;
|
||||
int offsetDelta;
|
||||
|
||||
StackMapTableData(int frameType) {
|
||||
this.frameType = frameType;
|
||||
}
|
||||
|
||||
void print(JavapPrinter p) {
|
||||
p.out.print(" frame_type = " + frameType);
|
||||
}
|
||||
|
||||
static class SameFrame extends StackMapTableData {
|
||||
SameFrame(int frameType, int offsetDelta) {
|
||||
super(frameType);
|
||||
this.offsetDelta = offsetDelta;
|
||||
}
|
||||
void print(JavapPrinter p) {
|
||||
super.print(p);
|
||||
if (frameType < SAME_FRAME_BOUND) {
|
||||
p.out.println(" /* same */");
|
||||
} else {
|
||||
p.out.println(" /* same_frame_extended */");
|
||||
p.out.println(" offset_delta = " + offsetDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SameLocals1StackItem extends StackMapTableData {
|
||||
final int[] stack;
|
||||
SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
|
||||
super(frameType);
|
||||
this.offsetDelta = offsetDelta;
|
||||
this.stack = stack;
|
||||
}
|
||||
void print(JavapPrinter p) {
|
||||
super.print(p);
|
||||
if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
|
||||
p.out.println(" /* same_locals_1_stack_item_frame_extended */");
|
||||
p.out.println(" offset_delta = " + offsetDelta);
|
||||
} else {
|
||||
p.out.println(" /* same_locals_1_stack_item */");
|
||||
}
|
||||
p.printMap(" stack = [", stack);
|
||||
}
|
||||
}
|
||||
|
||||
static class ChopFrame extends StackMapTableData {
|
||||
ChopFrame(int frameType, int offsetDelta) {
|
||||
super(frameType);
|
||||
this.offsetDelta = offsetDelta;
|
||||
}
|
||||
void print(JavapPrinter p) {
|
||||
super.print(p);
|
||||
p.out.println(" /* chop */");
|
||||
p.out.println(" offset_delta = " + offsetDelta);
|
||||
}
|
||||
}
|
||||
|
||||
static class AppendFrame extends StackMapTableData {
|
||||
final int[] locals;
|
||||
AppendFrame(int frameType, int offsetDelta, int[] locals) {
|
||||
super(frameType);
|
||||
this.offsetDelta = offsetDelta;
|
||||
this.locals = locals;
|
||||
}
|
||||
void print(JavapPrinter p) {
|
||||
super.print(p);
|
||||
p.out.println(" /* append */");
|
||||
p.out.println(" offset_delta = " + offsetDelta);
|
||||
p.printMap(" locals = [", locals);
|
||||
}
|
||||
}
|
||||
|
||||
static class FullFrame extends StackMapTableData {
|
||||
final int[] locals;
|
||||
final int[] stack;
|
||||
FullFrame(int offsetDelta, int[] locals, int[] stack) {
|
||||
super(FULL_FRAME);
|
||||
this.offsetDelta = offsetDelta;
|
||||
this.locals = locals;
|
||||
this.stack = stack;
|
||||
}
|
||||
void print(JavapPrinter p) {
|
||||
super.print(p);
|
||||
p.out.println(" /* full_frame */");
|
||||
p.out.println(" offset_delta = " + offsetDelta);
|
||||
p.printMap(" locals = [", locals);
|
||||
p.printMap(" stack = [", stack);
|
||||
}
|
||||
}
|
||||
|
||||
static StackMapTableData getInstance(DataInputStream in, MethodData method)
|
||||
throws IOException {
|
||||
int frameType = in.readUnsignedByte();
|
||||
|
||||
if (frameType < SAME_FRAME_BOUND) {
|
||||
// same_frame
|
||||
return new SameFrame(frameType, frameType);
|
||||
} else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
|
||||
// same_locals_1_stack_item_frame
|
||||
// read additional single stack element
|
||||
return new SameLocals1StackItem(frameType,
|
||||
(frameType - SAME_FRAME_BOUND),
|
||||
StackMapData.readTypeArray(in, 1, method));
|
||||
} else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
|
||||
// same_locals_1_stack_item_extended
|
||||
return new SameLocals1StackItem(frameType,
|
||||
in.readUnsignedShort(),
|
||||
StackMapData.readTypeArray(in, 1, method));
|
||||
} else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType && frameType < SAME_FRAME_EXTENDED) {
|
||||
// chop_frame or same_frame_extended
|
||||
return new ChopFrame(frameType, in.readUnsignedShort());
|
||||
} else if (frameType == SAME_FRAME_EXTENDED) {
|
||||
// chop_frame or same_frame_extended
|
||||
return new SameFrame(frameType, in.readUnsignedShort());
|
||||
} else if (SAME_FRAME_EXTENDED < frameType && frameType < FULL_FRAME) {
|
||||
// append_frame
|
||||
return new AppendFrame(frameType, in.readUnsignedShort(),
|
||||
StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
|
||||
} else if (frameType == FULL_FRAME) {
|
||||
// full_frame
|
||||
int offsetDelta = in.readUnsignedShort();
|
||||
int locals_size = in.readUnsignedShort();
|
||||
int[] locals = StackMapData.readTypeArray(in, locals_size, method);
|
||||
int stack_size = in.readUnsignedShort();
|
||||
int[] stack = StackMapData.readTypeArray(in, stack_size, method);
|
||||
return new FullFrame(offsetDelta, locals, stack);
|
||||
} else {
|
||||
throw new ClassFormatError("unrecognized frame_type in StackMapTable");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,375 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
public class Tables implements Constants {
|
||||
/**
|
||||
* Define mnemocodes table.
|
||||
*/
|
||||
static Hashtable<String,Integer> mnemocodes = new Hashtable<String,Integer>(301, 0.5f);
|
||||
static String opcExtNamesTab[]=new String[128];
|
||||
static String opcPrivExtNamesTab[]=new String[128];
|
||||
static void defineNonPriv(int opc, String mnem) {
|
||||
mnemocodes.put(opcExtNamesTab[opc]=mnem, opc_nonpriv*256+opc);
|
||||
}
|
||||
static void definePriv(int opc, String mnem) {
|
||||
mnemocodes.put(opcPrivExtNamesTab[opc]="priv_"+mnem, opc_priv*256+opc);
|
||||
}
|
||||
static void defineExt(int opc, String mnem) {
|
||||
defineNonPriv(opc, mnem);
|
||||
definePriv(opc, mnem);
|
||||
}
|
||||
static { int k;
|
||||
for (k=0; k<opc_wide; k++) {
|
||||
mnemocodes.put(opcNamesTab[k], k);
|
||||
}
|
||||
for (k=opc_wide+1; k<opcNamesTab.length; k++) {
|
||||
mnemocodes.put(opcNamesTab[k], k);
|
||||
}
|
||||
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 (k=0; k<32; k++) {
|
||||
definePriv(k+64, "read_reg_"+k);
|
||||
}
|
||||
for (k=0; k<32; k++) {
|
||||
definePriv(k+96, "write_reg_"+k);
|
||||
}
|
||||
}
|
||||
|
||||
public static int opcLength(int opc) throws ArrayIndexOutOfBoundsException {
|
||||
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 ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
case opc_nonpriv:
|
||||
case opc_priv:
|
||||
return 2;
|
||||
default:
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int opcode(String mnem) {
|
||||
Integer Val=mnemocodes.get(mnem);
|
||||
if (Val == null) return -1;
|
||||
return Val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialized keyword and token Hashtables
|
||||
*/
|
||||
static Vector<String> keywordNames = new Vector<String>(40);
|
||||
private static void defineKeywordName(String id, int token) {
|
||||
|
||||
if (token>=keywordNames.size()) {
|
||||
keywordNames.setSize(token+1);
|
||||
}
|
||||
keywordNames.setElementAt(id, token);
|
||||
}
|
||||
public static String keywordName(int token) {
|
||||
if (token==-1) return "EOF";
|
||||
if (token>=keywordNames.size()) return null;
|
||||
return keywordNames.elementAt(token);
|
||||
}
|
||||
static {
|
||||
defineKeywordName("ident", IDENT);
|
||||
defineKeywordName("STRINGVAL", STRINGVAL);
|
||||
defineKeywordName("intVal", INTVAL);
|
||||
defineKeywordName("longVal", LONGVAL);
|
||||
defineKeywordName("floatVal", FLOATVAL);
|
||||
defineKeywordName("doubleVal", DOUBLEVAL);
|
||||
defineKeywordName("SEMICOLON", SEMICOLON);
|
||||
defineKeywordName("COLON", COLON);
|
||||
defineKeywordName("LBRACE", LBRACE);
|
||||
defineKeywordName("RBRACE", RBRACE);
|
||||
}
|
||||
|
||||
static Hashtable<String,Integer> keywords = new Hashtable<String,Integer>(40);
|
||||
public static int keyword(String idValue) {
|
||||
Integer val=keywords.get(idValue);
|
||||
if (val == null) return IDENT;
|
||||
return val.intValue();
|
||||
}
|
||||
|
||||
private static void defineKeyword(String id, int token) {
|
||||
keywords.put(id, token);
|
||||
defineKeywordName(id, token);
|
||||
}
|
||||
static {
|
||||
// Modifier keywords
|
||||
defineKeyword("private", PRIVATE);
|
||||
defineKeyword("public", PUBLIC);
|
||||
defineKeyword("protected", PROTECTED);
|
||||
defineKeyword("static", STATIC);
|
||||
defineKeyword("transient", TRANSIENT);
|
||||
defineKeyword("synchronized", SYNCHRONIZED);
|
||||
defineKeyword("super", SUPER);
|
||||
defineKeyword("native", NATIVE);
|
||||
defineKeyword("abstract", ABSTRACT);
|
||||
defineKeyword("volatile", VOLATILE);
|
||||
defineKeyword("final", FINAL);
|
||||
defineKeyword("interface",INTERFACE);
|
||||
defineKeyword("synthetic",SYNTHETIC);
|
||||
defineKeyword("strict",STRICT);
|
||||
|
||||
// Declaration keywords
|
||||
defineKeyword("package",PACKAGE);
|
||||
defineKeyword("class",CLASS);
|
||||
defineKeyword("extends",EXTENDS);
|
||||
defineKeyword("implements",IMPLEMENTS);
|
||||
defineKeyword("const", CONST);
|
||||
defineKeyword("throws",THROWS);
|
||||
defineKeyword("interface",INTERFACE);
|
||||
defineKeyword("Method",METHODREF);
|
||||
defineKeyword("Field",FIELDREF);
|
||||
defineKeyword("stack",STACK);
|
||||
defineKeyword("locals",LOCAL);
|
||||
|
||||
// used in switchtables
|
||||
defineKeyword("default", DEFAULT);
|
||||
|
||||
// used in inner class declarations
|
||||
defineKeyword("InnerClass", INNERCLASS);
|
||||
defineKeyword("of", OF);
|
||||
|
||||
// misc
|
||||
defineKeyword("bits",BITS);
|
||||
defineKeyword("Infinity",INF);
|
||||
defineKeyword("Inf",INF);
|
||||
defineKeyword("NaN",NAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define tag table.
|
||||
*/
|
||||
private static Vector<String> tagNames = new Vector<String>(10);
|
||||
private static Hashtable<String,Integer> Tags = new Hashtable<String,Integer>(10);
|
||||
static {
|
||||
defineTag("Asciz",CONSTANT_UTF8);
|
||||
defineTag("int",CONSTANT_INTEGER);
|
||||
defineTag("float",CONSTANT_FLOAT);
|
||||
defineTag("long",CONSTANT_LONG);
|
||||
defineTag("double",CONSTANT_DOUBLE);
|
||||
defineTag("class",CONSTANT_CLASS);
|
||||
defineTag("String",CONSTANT_STRING);
|
||||
defineTag("Field",CONSTANT_FIELD);
|
||||
defineTag("Method",CONSTANT_METHOD);
|
||||
defineTag("InterfaceMethod",CONSTANT_INTERFACEMETHOD);
|
||||
defineTag("NameAndType",CONSTANT_NAMEANDTYPE);
|
||||
}
|
||||
private static void defineTag(String id, int val) {
|
||||
Tags.put(id, val);
|
||||
if (val>=tagNames.size()) {
|
||||
tagNames.setSize(val+1);
|
||||
}
|
||||
tagNames.setElementAt(id, val);
|
||||
}
|
||||
public static String tagName(int tag) {
|
||||
if (tag>=tagNames.size()) return null;
|
||||
return tagNames.elementAt(tag);
|
||||
}
|
||||
public static int tagValue(String idValue) {
|
||||
Integer Val=Tags.get(idValue);
|
||||
if (Val == null) return 0;
|
||||
return Val.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define type table. These types used in "newarray" instruction only.
|
||||
*/
|
||||
private static Vector<String> typeNames = new Vector<String>(10);
|
||||
private static Hashtable<String,Integer> Types = new Hashtable<String,Integer>(10);
|
||||
static {
|
||||
defineType("int",T_INT);
|
||||
defineType("long",T_LONG);
|
||||
defineType("float",T_FLOAT);
|
||||
defineType("double",T_DOUBLE);
|
||||
defineType("class",T_CLASS);
|
||||
defineType("boolean",T_BOOLEAN);
|
||||
defineType("char",T_CHAR);
|
||||
defineType("byte",T_BYTE);
|
||||
defineType("short",T_SHORT);
|
||||
}
|
||||
private static void defineType(String id, int val) {
|
||||
Types.put(id, val);
|
||||
if (val>=typeNames.size()) {
|
||||
typeNames.setSize(val+1);
|
||||
}
|
||||
typeNames.setElementAt(id, val);
|
||||
}
|
||||
public static int typeValue(String idValue) {
|
||||
Integer Val=Types.get(idValue);
|
||||
if (Val == null) return -1;
|
||||
return Val.intValue();
|
||||
}
|
||||
public static String typeName(int type) {
|
||||
if (type>=typeNames.size()) return null;
|
||||
return typeNames.elementAt(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define MapTypes table.
|
||||
* These constants used in stackmap tables only.
|
||||
*/
|
||||
private static Vector<String> mapTypeNames = new Vector<String>(10);
|
||||
private static Hashtable<String,Integer> MapTypes = new Hashtable<String,Integer>(10);
|
||||
static {
|
||||
defineMapType("bogus", ITEM_Bogus);
|
||||
defineMapType("int", ITEM_Integer);
|
||||
defineMapType("float", ITEM_Float);
|
||||
defineMapType("double", ITEM_Double);
|
||||
defineMapType("long", ITEM_Long);
|
||||
defineMapType("null", ITEM_Null);
|
||||
defineMapType("this", ITEM_InitObject);
|
||||
defineMapType("CP", ITEM_Object);
|
||||
defineMapType("uninitialized", ITEM_NewObject);
|
||||
}
|
||||
private static void defineMapType(String id, int val) {
|
||||
MapTypes.put(id, val);
|
||||
if (val>=mapTypeNames.size()) {
|
||||
mapTypeNames.setSize(val+1);
|
||||
}
|
||||
mapTypeNames.setElementAt(id, val);
|
||||
}
|
||||
public static int mapTypeValue(String idValue) {
|
||||
Integer Val=MapTypes.get(idValue);
|
||||
if (Val == null) return -1;
|
||||
return Val.intValue();
|
||||
}
|
||||
public static String mapTypeName(int type) {
|
||||
if (type>=mapTypeNames.size()) return null;
|
||||
return mapTypeNames.elementAt(type);
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Stores exception table data in code attribute.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
class TrapData {
|
||||
short start_pc, end_pc, handler_pc, catch_cpx;
|
||||
int num;
|
||||
|
||||
|
||||
/**
|
||||
* Read and store exception table data in code attribute.
|
||||
*/
|
||||
public TrapData(DataInputStream in, int num) throws IOException {
|
||||
this.num=num;
|
||||
start_pc = in.readShort();
|
||||
end_pc=in.readShort();
|
||||
handler_pc=in.readShort();
|
||||
catch_cpx=in.readShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns recommended identifier
|
||||
*/
|
||||
public String ident() {
|
||||
return "t"+num;
|
||||
}
|
||||
|
||||
}
|
@ -1,295 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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 sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Returns java type signature.
|
||||
*
|
||||
* @author Sucheta Dambalkar
|
||||
*/
|
||||
public class TypeSignature {
|
||||
|
||||
String parameters = null;
|
||||
String returntype = null;
|
||||
String fieldtype = null;
|
||||
int argumentlength = 0;
|
||||
|
||||
public TypeSignature(String JVMSignature){
|
||||
|
||||
if(JVMSignature != null){
|
||||
if(JVMSignature.indexOf("(") == -1){
|
||||
//This is a field type.
|
||||
this.fieldtype = getFieldTypeSignature(JVMSignature);
|
||||
}else {
|
||||
String parameterdes = null;
|
||||
if((JVMSignature.indexOf(")")-1) > (JVMSignature.indexOf("("))){
|
||||
//Get parameter signature.
|
||||
parameterdes =
|
||||
JVMSignature.substring(JVMSignature.indexOf("(")+1,
|
||||
JVMSignature.indexOf(")"));
|
||||
this.parameters = getParametersHelper(parameterdes);
|
||||
}else this.parameters = "()";
|
||||
//Get return type signature.
|
||||
String returndes = JVMSignature.substring(JVMSignature.lastIndexOf(")")+1);
|
||||
this.returntype = getReturnTypeHelper(returndes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature of a field.
|
||||
*/
|
||||
public String getFieldTypeSignature(String fielddes){
|
||||
if(fielddes.startsWith("L")){
|
||||
return(getObjectType(fielddes));
|
||||
}else if(fielddes.startsWith("[")){
|
||||
return(getArrayType(fielddes));
|
||||
}else
|
||||
return(getBaseType(fielddes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature of a parameter.
|
||||
*/
|
||||
public String getParametersHelper(String parameterdes){
|
||||
Vector<String> parameters = new Vector<String>();
|
||||
int startindex = -1;
|
||||
int endindex = -1;
|
||||
String param = "";
|
||||
|
||||
while(parameterdes != null){
|
||||
|
||||
if(parameterdes.startsWith("L")){
|
||||
//parameter is a object.
|
||||
startindex = parameterdes.indexOf("L");
|
||||
endindex = parameterdes.indexOf(";");
|
||||
if(startindex < parameterdes.length()) {
|
||||
if(endindex == parameterdes.length()-1) {
|
||||
//last parameter
|
||||
param = parameterdes.substring(startindex);
|
||||
parameterdes = null;
|
||||
}else if(endindex+1 < parameterdes.length()){
|
||||
//rest parameters
|
||||
param = parameterdes.substring(startindex, endindex+1);
|
||||
parameterdes = parameterdes.substring(endindex+1);
|
||||
|
||||
}
|
||||
parameters.add(getObjectType(param));
|
||||
}
|
||||
}else if(parameterdes.startsWith("[")){
|
||||
//parameter is an array.
|
||||
String componentType = "";
|
||||
int enddim = -1;
|
||||
int st = 0;
|
||||
while(true){
|
||||
if(st < parameterdes.length()){
|
||||
if(parameterdes.charAt(st) == '['){
|
||||
|
||||
enddim = st;
|
||||
st++;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if(enddim+1 < parameterdes.length()){
|
||||
/* Array dimension.*/
|
||||
param = parameterdes.substring(0,enddim+1);
|
||||
|
||||
}
|
||||
|
||||
int stotherparam = param.lastIndexOf("[")+1;
|
||||
|
||||
if(stotherparam < parameterdes.length()){
|
||||
componentType = parameterdes.substring(stotherparam);
|
||||
}
|
||||
|
||||
if(componentType.startsWith("L")){
|
||||
//parameter is array of objects.
|
||||
startindex = parameterdes.indexOf("L");
|
||||
endindex = parameterdes.indexOf(";");
|
||||
|
||||
if(endindex == parameterdes.length()-1){
|
||||
//last parameter
|
||||
param += parameterdes.substring(startindex);
|
||||
parameterdes = null;
|
||||
}else if(endindex+1 < parameterdes.length()){
|
||||
//rest parameters
|
||||
param += parameterdes.substring(startindex, endindex+1);
|
||||
parameterdes = parameterdes.substring(endindex+1);
|
||||
}
|
||||
}else{
|
||||
//parameter is array of base type.
|
||||
if(componentType.length() == 1){
|
||||
//last parameter.
|
||||
param += componentType;
|
||||
parameterdes = null;
|
||||
}
|
||||
else if (componentType.length() > 1) {
|
||||
//rest parameters.
|
||||
param += componentType.substring(0,1);
|
||||
parameterdes = componentType.substring(1);
|
||||
}
|
||||
}
|
||||
parameters.add(getArrayType(param));
|
||||
|
||||
|
||||
}else {
|
||||
|
||||
//parameter is of base type.
|
||||
if(parameterdes.length() == 1){
|
||||
//last parameter
|
||||
param = parameterdes;
|
||||
parameterdes = null;
|
||||
}
|
||||
else if (parameterdes.length() > 1) {
|
||||
//rest parameters.
|
||||
param = parameterdes.substring(0,1);
|
||||
parameterdes = parameterdes.substring(1);
|
||||
}
|
||||
parameters.add(getBaseType(param));
|
||||
}
|
||||
}
|
||||
|
||||
/* number of arguments of a method.*/
|
||||
argumentlength = parameters.size();
|
||||
|
||||
/* java type signature.*/
|
||||
String parametersignature = "(";
|
||||
int i;
|
||||
|
||||
for(i = 0; i < parameters.size(); i++){
|
||||
parametersignature += parameters.elementAt(i);
|
||||
if(i != parameters.size()-1){
|
||||
parametersignature += ", ";
|
||||
}
|
||||
}
|
||||
parametersignature += ")";
|
||||
return parametersignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for a return type.
|
||||
*/
|
||||
public String getReturnTypeHelper(String returndes){
|
||||
return getFieldTypeSignature(returndes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for a base type.
|
||||
*/
|
||||
public String getBaseType(String baseType){
|
||||
if(baseType != null){
|
||||
if(baseType.equals("B")) return "byte";
|
||||
else if(baseType.equals("C")) return "char";
|
||||
else if(baseType.equals("D")) return "double";
|
||||
else if(baseType.equals("F")) return "float";
|
||||
else if(baseType.equals("I")) return "int";
|
||||
else if(baseType.equals("J")) return "long";
|
||||
else if(baseType.equals("S")) return "short";
|
||||
else if(baseType.equals("Z")) return "boolean";
|
||||
else if(baseType.equals("V")) return "void";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for a object type.
|
||||
*/
|
||||
public String getObjectType(String JVMobjectType) {
|
||||
String objectType = "";
|
||||
int startindex = JVMobjectType.indexOf("L")+1;
|
||||
int endindex = JVMobjectType.indexOf(";");
|
||||
if((startindex != -1) && (endindex != -1)){
|
||||
if((startindex < JVMobjectType.length()) && (endindex < JVMobjectType.length())){
|
||||
objectType = JVMobjectType.substring(startindex, endindex);
|
||||
}
|
||||
objectType = objectType.replace('/','.');
|
||||
return objectType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for array type.
|
||||
*/
|
||||
public String getArrayType(String arrayType) {
|
||||
if(arrayType != null){
|
||||
String dimention = "";
|
||||
|
||||
while(arrayType.indexOf("[") != -1){
|
||||
dimention += "[]";
|
||||
|
||||
int startindex = arrayType.indexOf("[")+1;
|
||||
if(startindex <= arrayType.length()){
|
||||
arrayType = arrayType.substring(startindex);
|
||||
}
|
||||
}
|
||||
|
||||
String componentType = "";
|
||||
if(arrayType.startsWith("L")){
|
||||
componentType = getObjectType(arrayType);
|
||||
}else {
|
||||
componentType = getBaseType(arrayType);
|
||||
}
|
||||
return componentType+dimention;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for parameters.
|
||||
*/
|
||||
public String getParameters(){
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for return type.
|
||||
*/
|
||||
public String getReturnType(){
|
||||
return returntype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns java type signature for field type.
|
||||
*/
|
||||
public String getFieldType(){
|
||||
return fieldtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of arguments of a method.
|
||||
*/
|
||||
public int getArgumentlength(){
|
||||
return argumentlength;
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ public class TestIndex extends JavadocTester {
|
||||
|
||||
//Javadoc arguments.
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-d", BUG_ID, "-source", "1.5", "-sourcepath", SRC_DIR, "pkg", SRC_DIR + FS + "NoPackage.java"
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", SRC_DIR + FS + "NoPackage.java"
|
||||
};
|
||||
|
||||
//Input for string search tests.
|
||||
|
@ -42,7 +42,7 @@ public class TestInterface extends JavadocTester {
|
||||
|
||||
//Javadoc arguments.
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-source", "1.5", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
|
||||
};
|
||||
|
||||
//Input for string search tests.
|
||||
|
@ -40,7 +40,7 @@ public class TestNavagation extends JavadocTester {
|
||||
|
||||
//Javadoc arguments.
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "-source", "1.5", "pkg"
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
|
||||
};
|
||||
|
||||
//Input for string search tests.
|
||||
|
@ -36,7 +36,7 @@ public class TestTagInheritence extends JavadocTester {
|
||||
|
||||
private static final String BUG_ID = "4496223-4496270-4618686-4720974-4812240-6253614-6253604";
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-source", "1.5", "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "firstSentence", "firstSentence2"
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,8 +27,8 @@
|
||||
* @summary com/sun/tools/javac/comp/Check.java refers to the undefined resource
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.5 -Werror 5005368.java
|
||||
* @compile/fail -source 1.5 -Werror -Xlint:unchecked 5005368.java
|
||||
* @compile -Werror 5005368.java
|
||||
* @compile/fail -Werror -Xlint:unchecked 5005368.java
|
||||
*/
|
||||
|
||||
package p5005368;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/
|
||||
* @bug 6304921
|
||||
* @compile/fail/ref=T6304921.out -XDstdout -XDcompilePolicy=bytodo -XDdiags=%b:%s/%o/%e:%_%t%m|%p%m -Xjcov -Xlint:all,-path -Werror T6304921.java
|
||||
* @compile/fail/ref=T6304921.out -XDstdout -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -1,20 +1,7 @@
|
||||
T6304921.java:671/671/680: warning: [rawtypes] found raw type: java.util.ArrayList
|
||||
List<Integer> list = new ArrayList();
|
||||
^
|
||||
missing type parameters for generic class java.util.ArrayList<E>
|
||||
T6304921.java:667/667/682: warning: [unchecked] unchecked conversion
|
||||
List<Integer> list = new ArrayList();
|
||||
^
|
||||
required: java.util.List<java.lang.Integer>
|
||||
found: java.util.ArrayList
|
||||
error: warnings found and -Werror specified
|
||||
T6304921.java:727/733/737: cannot find symbol
|
||||
System.orr.println("abc"); // name not found
|
||||
^
|
||||
symbol: variable orr
|
||||
location: class java.lang.System
|
||||
T6304921.java:812/816/822: operator + cannot be applied to int,boolean
|
||||
return 123 + true; // bad binary expression
|
||||
^
|
||||
T6304921.java:29:34: compiler.warn.raw.class.use: java.util.ArrayList, java.util.ArrayList<E>
|
||||
T6304921.java:29:30: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.ArrayList, java.util.List<java.lang.Integer>
|
||||
- compiler.err.warnings.and.werror
|
||||
T6304921.java:35:15: compiler.err.cant.resolve.location: kindname.variable, orr, , , kindname.class, java.lang.System
|
||||
T6304921.java:38:20: compiler.err.operator.cant.be.applied: +, int,boolean
|
||||
3 errors
|
||||
2 warnings
|
||||
|
@ -27,7 +27,7 @@ import javax.lang.model.*;
|
||||
import javax.lang.model.element.*;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_6)
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_7)
|
||||
public class Anno extends AbstractProcessor {
|
||||
public boolean process(Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundEnv) {
|
||||
|
@ -26,7 +26,7 @@
|
||||
* @bug 6464451
|
||||
* @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
|
||||
* @author Wei Tao
|
||||
* @compile -target 5 BigFinally.java
|
||||
* @compile -source 5 -target 5 BigFinally.java
|
||||
* @clean BigFinally
|
||||
* @compile/fail BigFinally.java
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@
|
||||
* @bug 6464451
|
||||
* @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
|
||||
* @author Wei Tao
|
||||
* @compile -target 5 DeepNestedFinally.java
|
||||
* @compile -source 5 -target 5 DeepNestedFinally.java
|
||||
* @clean DeepNestedFinally
|
||||
* @compile/fail DeepNestedFinally.java
|
||||
*/
|
||||
|
@ -26,7 +26,7 @@
|
||||
* @bug 6464451
|
||||
* @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
|
||||
* @author Wei Tao
|
||||
* @compile -target 5 ManyExitsInTry.java
|
||||
* @compile -source 5 -target 5 ManyExitsInTry.java
|
||||
* @clean ManyExitsInTry
|
||||
* @compile/fail ManyExitsInTry.java
|
||||
*/
|
||||
|
@ -1,2 +1,2 @@
|
||||
T6491592.java:12:11: compiler.err.operator.cant.be.applied: +, java.lang.Object,<nulltype>
|
||||
T6491592.java:12:11: compiler.err.operator.cant.be.applied: +, java.lang.Object,compiler.misc.type.null
|
||||
1 error
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Missing ambiguity error when two methods are equally specific
|
||||
* @author gafter
|
||||
*
|
||||
* @compile/fail -source 1.5 Ambig3.java
|
||||
* @compile/fail Ambig3.java
|
||||
*/
|
||||
|
||||
class Test<T,E> {
|
||||
|
@ -28,7 +28,7 @@
|
||||
* compilation. This was fixed in 1.2beta2.
|
||||
* @author turnidge
|
||||
*
|
||||
* @compile -source 1.4 ArrayCast.java
|
||||
* @compile ArrayCast.java
|
||||
*/
|
||||
|
||||
public class ArrayCast {
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Compiler allows inheritance of multiple methods with unrelated return types
|
||||
* @author gafter
|
||||
*
|
||||
* @compile/fail -source 1.5 BadCovar.java
|
||||
* @compile/fail BadCovar.java
|
||||
*/
|
||||
|
||||
package bad.covar;
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Use ldc instruction for class literals
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -target 1.5 ClassLit.java
|
||||
* @compile -source 1.5 -target 1.5 ClassLit.java
|
||||
* @run main ClassLit
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Using a class literal causes outermost class to be initialized early
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4.2 InitializeOuter.java
|
||||
* @compile InitializeOuter.java
|
||||
* @run main InitializeOuter
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary class literal causes the referenced class to be initialized
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4.2 InitializeTarget.java
|
||||
* @compile InitializeTarget.java
|
||||
* @run main InitializeTarget
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Generics: assignment of Class to type parm's default should elicit error
|
||||
* @author never
|
||||
*
|
||||
* @compile/fail -source 1.5 ClassToTypeParm.java
|
||||
* @compile/fail ClassToTypeParm.java
|
||||
*/
|
||||
|
||||
class ClassToTypeParm<T> {
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Initialization of up-level links, immediately after super(), occurs too late.
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4 Closure1.java
|
||||
* @compile Closure1.java
|
||||
* @run main Closure1
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Initialization of up-level links, immediately after super(), occurs too late.
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4 Closure2.java
|
||||
* @compile Closure2.java
|
||||
* @run main Closure2
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Initialization of up-level links, immediately after super(), occurs too late.
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4 Closure3.java
|
||||
* @compile Closure3.java
|
||||
* @run main Closure3
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Initialization of up-level links, immediately after super(), occurs too late.
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4 Closure4.java
|
||||
* @compile Closure4.java
|
||||
* @run main Closure4
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary Incorrect order for initializers in nested class
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 -target 1.4 Closure5.java
|
||||
* @compile Closure5.java
|
||||
* @run main Closure5
|
||||
*/
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary drop compound boxing operations
|
||||
* @author gafter
|
||||
*
|
||||
* @compile/fail -source 1.5 CompoundBox.java
|
||||
* @compile/fail CompoundBox.java
|
||||
*/
|
||||
|
||||
class CompoundBox {
|
||||
|
@ -28,7 +28,7 @@
|
||||
* @author maddox
|
||||
*
|
||||
* @compile/fail -source 1.4 ConditionalArgTypes_1.java
|
||||
* @compile -source 1.5 ConditionalArgTypes_1.java
|
||||
* @compile ConditionalArgTypes_1.java
|
||||
*/
|
||||
|
||||
// This is the problematic case -- the controlling expression is a boolean constant.
|
||||
|
@ -28,7 +28,7 @@
|
||||
* @author maddox
|
||||
*
|
||||
* @compile/fail -source 1.4 ConditionalArgTypes_2.java
|
||||
* @compile -source 1.5 ConditionalArgTypes_2.java
|
||||
* @compile ConditionalArgTypes_2.java
|
||||
*/
|
||||
|
||||
// This case was working before -- controlling expression is not a constant.
|
||||
|
@ -22,12 +22,12 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test %E
|
||||
* @test
|
||||
* @bug 4478838 4533580
|
||||
* @summary Check correct handling of DU in assert statements
|
||||
* @author Neal Gafter (gafter)
|
||||
*
|
||||
* @run compile -source 1.4 DUAssert.java
|
||||
* @run compile DUAssert.java
|
||||
*/
|
||||
|
||||
class DUSwitch {
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6722234
|
||||
* @summary javac diagnostics need better integration with the type-system
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6722234a_1.out -XDrawDiagnostics -XDdiags=disambiguateTvars T6722234a.java
|
||||
* @compile/fail/ref=T6722234a_2.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6722234a.java
|
||||
*/
|
||||
|
||||
class T6722234a<T extends String> {
|
||||
<T extends Integer> void test(T t) {
|
||||
m(t);
|
||||
}
|
||||
void m(T t) {}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
T6722234a.java:35:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, null
|
||||
1 error
|
@ -0,0 +1,3 @@
|
||||
T6722234a.java:35:9: compiler.err.cant.apply.symbol: kindname.method, m, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T6722234a<compiler.misc.type.var: T, 1>, null
|
||||
- compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T6722234a),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, java.lang.Integer, kindname.method, <compiler.misc.type.var: T, 2>test(compiler.misc.type.var: T, 2))}
|
||||
1 error
|
@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
* 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
|
||||
@ -23,28 +21,21 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
/**
|
||||
* @test
|
||||
* @bug 6722234
|
||||
* @summary javac diagnostics need better integration with the type-system
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6722234b_1.out -XDrawDiagnostics -XDdiags=simpleNames T6722234b.java
|
||||
* @compile/fail/ref=T6722234b_2.out -XDrawDiagnostics -XDdiags=simpleNames,where T6722234b.java
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Strores LineNumberTable data information.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
class LineNumData {
|
||||
short start_pc, line_number;
|
||||
|
||||
public LineNumData() {}
|
||||
|
||||
/**
|
||||
* Read LineNumberTable attribute.
|
||||
*/
|
||||
public LineNumData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
line_number=in.readShort();
|
||||
class T6722234b {
|
||||
<T> void m(List<T> l1, List<T> l2) {}
|
||||
|
||||
void test(List<? extends T6722234b> list) {
|
||||
m(list, list);
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
T6722234b.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, List<T>,List<T>, List<compiler.misc.type.captureof: 1, ? extends T6722234b>,List<compiler.misc.type.captureof: 2, ? extends T6722234b>, kindname.class, T6722234b, null
|
||||
1 error
|
@ -0,0 +1,4 @@
|
||||
T6722234b.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, List<T>,List<T>, List<compiler.misc.captured.type: 1>,List<compiler.misc.captured.type: 2>, kindname.class, T6722234b, null
|
||||
- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, Object, kindname.method, <T>m(List<T>,List<T>))}
|
||||
- compiler.misc.where.description.captured.1: compiler.misc.captured.type: 1,compiler.misc.captured.type: 2,{(compiler.misc.where.captured.1: compiler.misc.captured.type: 1, T6722234b, compiler.misc.type.null, ? extends T6722234b),(compiler.misc.where.captured.1: compiler.misc.captured.type: 2, T6722234b, compiler.misc.type.null, ? extends T6722234b)}
|
||||
1 error
|
@ -1,12 +1,10 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
* 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
|
||||
@ -23,19 +21,19 @@
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
|
||||
/**
|
||||
* Stores constant pool entry information with two fields.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
* @test
|
||||
* @bug 6722234
|
||||
* @summary javac diagnostics need better integration with the type-system
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6722234c.out -XDrawDiagnostics -XDdiags=simpleNames T6722234c.java
|
||||
*/
|
||||
class CPX2 {
|
||||
int cpx1,cpx2;
|
||||
|
||||
CPX2 (int cpx1, int cpx2) {
|
||||
this.cpx1=cpx1;
|
||||
this.cpx2=cpx2;
|
||||
class T6722234c {
|
||||
static class String {}
|
||||
<T> void m(String s2) {}
|
||||
|
||||
void test() {
|
||||
m("");
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
T6722234c.java:37:9: compiler.err.cant.apply.symbol: kindname.method, m, T6722234c.String, java.lang.String, kindname.class, T6722234c, null
|
||||
1 error
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6722234
|
||||
* @summary javac diagnostics need better integration with the type-system
|
||||
* @author mcimadamore
|
||||
* @compile/fail/ref=T6722234d_1.out -XDrawDiagnostics -XDdiags=where T6722234d.java
|
||||
* @compile/fail/ref=T6722234d_2.out -XDrawDiagnostics -XDdiags=where,simpleNames T6722234d.java
|
||||
*/
|
||||
|
||||
class T6722234d {
|
||||
interface I1 {}
|
||||
interface I2 {}
|
||||
class A implements I1, I2 {}
|
||||
class B implements I1, I2 {}
|
||||
class Test {
|
||||
<Z> Z m(Z z1, Z z2) { return null; }
|
||||
void main(){
|
||||
A a = m(new A(), new B());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
T6722234d.java:41:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), compiler.misc.intersection.type: 1, T6722234d.A
|
||||
- compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, java.lang.Object,T6722234d.I1,T6722234d.I2)}
|
||||
1 error
|
@ -0,0 +1,3 @@
|
||||
T6722234d.java:41:20: compiler.err.prob.found.req: (compiler.misc.incompatible.types), compiler.misc.intersection.type: 1, T6722234d.A
|
||||
- compiler.misc.where.description.intersection: compiler.misc.intersection.type: 1,{(compiler.misc.where.intersection: compiler.misc.intersection.type: 1, Object,I1,I2)}
|
||||
1 error
|
@ -27,9 +27,6 @@
|
||||
* @summary Verify that assertions are enabled before the class is initialized
|
||||
* and not thereafter
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 EarlyAssert.java
|
||||
* @run main EarlyAssert
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -26,9 +26,6 @@
|
||||
* @bug 4934060
|
||||
* @summary private enum ctor versus specialized enum constant crashes javac
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.5 Enum1.java
|
||||
* @run main Enum1
|
||||
*/
|
||||
|
||||
public enum Enum1 {
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @bug 4336282 4785453
|
||||
* @summary Verify that extending an erray class does not crash the compiler.
|
||||
*
|
||||
* @compile/fail/ref=ExtendArray.out -XDstdout -XDdiags=%b:%l:%_%m ExtendArray.java
|
||||
* @compile/fail/ref=ExtendArray.out -XDstdout -XDrawDiagnostics ExtendArray.java
|
||||
*/
|
||||
|
||||
// Note that an error is expected, but not a crash.
|
||||
|
@ -1,6 +1,2 @@
|
||||
ExtendArray.java:11: unexpected type
|
||||
public class ExtendArray extends Object[] {}
|
||||
^
|
||||
required: class
|
||||
found: java.lang.Object[]
|
||||
ExtendArray.java:11:40: compiler.err.type.found.req: java.lang.Object[], (compiler.misc.type.req.class)
|
||||
1 error
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary multiple methods inheritence
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.5 GoodCovar.java
|
||||
* @compile GoodCovar.java
|
||||
*/
|
||||
|
||||
package good.covar;
|
||||
|
@ -26,9 +26,6 @@
|
||||
* @bug 4920023
|
||||
* @summary add "hexadecimal floating-point literal" support to javac as per 4896828
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.5 HexFloatLiterals.java
|
||||
* @run main HexFloatLiterals
|
||||
*/
|
||||
|
||||
public class HexFloatLiterals {
|
||||
|
@ -26,9 +26,6 @@
|
||||
* @bug 4920023
|
||||
* @summary Test hex floating-point literals
|
||||
* @author darcy
|
||||
*
|
||||
* @compile -source 1.5 HexThree.java
|
||||
* @run main HexThree
|
||||
*/
|
||||
|
||||
public class HexThree {
|
||||
|
@ -26,9 +26,6 @@
|
||||
* @bug 4399129
|
||||
* @summary Check that assertions compile properly when nested in an interface
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -source 1.4 InterfaceAssert.java
|
||||
* @run main InterfaceAssert
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary The compiler should detect an invalid cast between interfaces.
|
||||
* @author turnidge
|
||||
*
|
||||
* @compile -source 1.5 InvalidIntfCast.java
|
||||
* @compile InvalidIntfCast.java
|
||||
*/
|
||||
|
||||
interface I {
|
||||
|
@ -27,7 +27,7 @@
|
||||
* @summary unclear diagnostic for "new T()"
|
||||
* @author never
|
||||
*
|
||||
* @compile/fail -source 1.5 NewGeneric.java
|
||||
* @compile/fail NewGeneric.java
|
||||
*/
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user