You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/06/19 19:26:43 UTC
svn commit: r669581 - in /harmony/enhanced: jdktools/trunk/modules/samsa/
jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/
trunk/
Author: tellison
Date: Thu Jun 19 10:26:42 2008
New Revision: 669581
URL: http://svn.apache.org/viewvc?rev=669581&view=rev
Log:
Import contribution HARMONY-1680 ([classlib][tools] The java class file disassembler contribution)
Added:
harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/
harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java (with props)
harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java (with props)
harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java (with props)
Modified:
harmony/enhanced/jdktools/trunk/modules/samsa/build.xml
harmony/enhanced/trunk/COPYRIGHT
Modified: harmony/enhanced/jdktools/trunk/modules/samsa/build.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/samsa/build.xml?rev=669581&r1=669580&r2=669581&view=diff
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/samsa/build.xml (original)
+++ harmony/enhanced/jdktools/trunk/modules/samsa/build.xml Thu Jun 19 10:26:42 2008
@@ -69,6 +69,9 @@
<copy file="${hy.samsa.exe}" tofile="${jdktools.deploy.dir}/bin/javadoc${exe.suffix}" />
<chmod file="${jdktools.deploy.dir}/bin/javadoc${exe.suffix}" perm="ugo+x" />
+ <copy file="${hy.samsa.exe}" tofile="${jdktools.deploy.dir}/bin/javap${exe.suffix}" />
+ <chmod file="${jdktools.deploy.dir}/bin/javap${exe.suffix}" perm="ugo+x" />
+
<copy file="${hy.samsa.exe}" tofile="${jdktools.deploy.dir}/bin/keytool${exe.suffix}" />
<chmod file="${jdktools.deploy.dir}/bin/keytool${exe.suffix}" perm="ugo+x" />
@@ -105,6 +108,7 @@
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/javac${progdb.suffix}" />
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/javah${progdb.suffix}" />
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/javadoc${progdb.suffix}" />
+ <copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/javap${progdb.suffix}" />
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/keytool${progdb.suffix}" />
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/jarsigner${progdb.suffix}" />
<copy file="${hy.samsa.progdb}" tofile="${jdktools.deploy.dir}/bin/unpack200${progdb.suffix}" />
Added: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java?rev=669581&view=auto
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java Thu Jun 19 10:26:42 2008
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tools.javap;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.util.ClassPath;
+
+/**
+ * This class locates a class in the given class path with the given name. You
+ * can use this class to get a JavaClass object which represents the found
+ * class.
+ *
+ * This class depends on Apache Byte Code Engineering Library (BCEL) 5.0 or
+ * later. Please see http://jakarta.apache.org/bcel for more information
+ * about this library.
+ */
+public class ClassProvider {
+
+ /**
+ * Loading class files from a class path.
+ */
+ private ClassPath classpath;
+
+ /**
+ * Verbose output or not.
+ */
+ private boolean verbose;
+
+ /**
+ * Keeps loaded and parsed class files.
+ */
+ private Map cache;
+
+ /**
+ * Constructs a <code>ClassProvider</code> object.
+ *
+ * @param bootClasspath - a path that will be prepended to the default
+ * class path.
+ * @param classpath - a path that will be apppended to the default class
+ * path.
+ * @param verbose - a verbose output.
+ */
+ public ClassProvider(String bootClasspath, String classpath, boolean verbose) {
+ StringBuffer pathString = new StringBuffer();
+
+ // Append the given boot class path, if any.
+ if (bootClasspath != null) {
+ pathString.append(bootClasspath).append(File.pathSeparatorChar);
+ }
+
+ // Append the default class path.
+ pathString.append(getSystemClassPath()).append(File.pathSeparatorChar);
+
+ // Append the given class path, if any.
+ if (classpath != null) {
+ pathString.append(classpath).append(File.pathSeparatorChar);
+ }
+
+ if (verbose) {
+ System.out.println("class.path: " + pathString.toString());
+ }
+
+ this.classpath = new ClassPath(pathString.toString());
+ this.verbose = verbose;
+ this.cache = new HashMap();
+ }
+
+ /**
+ * Returns the system class path.
+ *
+ * @return the system class path.
+ */
+ private String getSystemClassPath() {
+ String sep = System.getProperty("path.separator");
+ StringBuffer cp = new StringBuffer();
+ for (Enumeration e = System.getProperties().propertyNames(); e.hasMoreElements();) {
+ // Enumerate all the system properties.
+ String prop = (String) e.nextElement();
+ if (prop.endsWith("class.path")) {
+ // Add the value of a property to the class path, if its
+ // name ends with "class.path".
+ cp.append(System.getProperty(prop)).append(sep);
+ }
+ }
+ return cp.toString();
+ }
+
+ /**
+ * Returns a JavaClass object which represents a class file with the given
+ * name.
+ *
+ * @param name - a fully qualified name of a class.
+ * @return a JavaClass object which represents a class file with the given
+ * name.
+ * @throws ClassNotFoundException if a class file with the given name is
+ * not found.
+ */
+ public synchronized JavaClass getJavaClass(String name)
+ throws ClassNotFoundException {
+ try {
+ // Try to get the class from the cache.
+ JavaClass result = (JavaClass) cache.get(name);
+ // If cache doesn't contain such a class load it from a class path.
+ if (result == null) {
+ // Get a file and parse its contents.
+ ClassPath.ClassFile cf = classpath.getClassFile(name);
+ InputStream is = cf.getInputStream();
+ ClassParser parser = new ClassParser(is, cf.getPath());
+ result = parser.parse();
+ // Put the parsed class file into the cache.
+ cache.put(name, result);
+
+ if (verbose) {
+ StringBuffer s = new StringBuffer();
+ // If we use BCEL 5.1 or later one day we definitely
+ // should remove the following if and replace
+ // cf.getPath() with cf.getBase()!
+ if (!(is instanceof FileInputStream)) {
+ s.append("class.path:");
+ }
+ s.append(cf.getPath());
+ System.out.println(name + " loaded from " + s);
+ }
+ } else {
+ if (verbose) {
+ System.out.println(name + " retrieved from a cache");
+ }
+ }
+ return result;
+ } catch (Exception e) {
+ throw new ClassNotFoundException(name, e);
+ }
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/ClassProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java?rev=669581&view=auto
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java Thu Jun 19 10:26:42 2008
@@ -0,0 +1,916 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tools.javap;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.AccessFlags;
+import org.apache.bcel.classfile.Attribute;
+import org.apache.bcel.classfile.Code;
+import org.apache.bcel.classfile.Constant;
+import org.apache.bcel.classfile.ConstantClass;
+import org.apache.bcel.classfile.ConstantDouble;
+import org.apache.bcel.classfile.ConstantFieldref;
+import org.apache.bcel.classfile.ConstantFloat;
+import org.apache.bcel.classfile.ConstantInteger;
+import org.apache.bcel.classfile.ConstantInterfaceMethodref;
+import org.apache.bcel.classfile.ConstantLong;
+import org.apache.bcel.classfile.ConstantMethodref;
+import org.apache.bcel.classfile.ConstantNameAndType;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.ConstantString;
+import org.apache.bcel.classfile.ConstantUtf8;
+import org.apache.bcel.classfile.ConstantValue;
+import org.apache.bcel.classfile.ExceptionTable;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.InnerClass;
+import org.apache.bcel.classfile.InnerClasses;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.LineNumber;
+import org.apache.bcel.classfile.LineNumberTable;
+import org.apache.bcel.classfile.LocalVariable;
+import org.apache.bcel.classfile.LocalVariableTable;
+import org.apache.bcel.classfile.Method;
+import org.apache.bcel.classfile.Utility;
+
+
+/**
+ * This class is a wrapper of BCEL's Class class.
+ *
+ * This class depends on Apache Byte Code Engineering Library (BCEL) 5.0 or
+ * later. Please see http://jakarta.apache.org/bcel for more information
+ * about this library.
+ */
+public class Clazz {
+
+ /**
+ * A wrapped class.
+ */
+ private JavaClass wrappedClass;
+
+ /**
+ * A constant pool of the wrapped class.
+ */
+ private ConstantPool constPool;
+
+ /**
+ * Verbose output.
+ */
+ private boolean verbose;
+
+ /**
+ * Inner classes of a wrapped class.
+ */
+ private InnerClasses innerClasses;
+
+ /**
+ * Inner class names of a wrapped class.
+ */
+ private String innerClassNames[];
+
+ /**
+ * Whether the disassembled code be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printCode = false;
+
+ /**
+ * Whether line numbers be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printLineNumbers = false;
+
+ /**
+ * Whether local variables be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printLocalVariables = false;
+
+ /**
+ * Whether internal type signatures be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printTypeSignatures = false;
+
+ /**
+ * Whether package private methods be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printPackagePrivate = true;
+
+ /**
+ * Whether public methods be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printPublic = false;
+
+ /**
+ * Whether protected methods be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printProtected = false;
+
+ /**
+ * Whether private methods be printed by
+ * the <code>toString</code> method.
+ */
+ private boolean printPrivate = false;
+
+ /**
+ * Platform dependent line separator.
+ */
+ private static String n = System.getProperty("line.separator");
+
+ /**
+ * Constructs a <code>Clazz</code> object.
+ *
+ * @param classProvider - a helper that provides the class information.
+ * @param className - a fully qualified name of a class.
+ * @param verbose - true, if output should be verbose. Otherwise false.
+ */
+ public Clazz(ClassProvider classProvider, String className, boolean verbose)
+ throws ClassNotFoundException {
+ wrappedClass = classProvider.getJavaClass(className);
+ constPool = wrappedClass.getConstantPool();
+ this.verbose = verbose;
+
+ // Assign an empty array by default.
+ Vector foundInners = new Vector();
+ // Get the class attributes.
+ Attribute attrs[] = wrappedClass.getAttributes();
+ for (int i = 0; i < attrs.length; i++) {
+ // Find the InnerClasses attribute, if any.
+ if (attrs[i] instanceof InnerClasses) {
+ // The InnerClasses attribute is found.
+ innerClasses = (InnerClasses) attrs[i];
+
+ // Get an array of the inner classes.
+ InnerClass inners[] = innerClasses.getInnerClasses();
+ for (int j = 0; j < inners.length; j++) {
+
+ // Get the inner class name from a constant pool.
+ String innerClassName = Utility.compactClassName(
+ innerClasses.getConstantPool().getConstantString(
+ inners[j].getInnerClassIndex(),
+ Constants.CONSTANT_Class),
+ false);
+
+ // The inner class has the InnerClasses attribute as well
+ // as its outer class. So, we should ignore such an inner
+ // class.
+ if (!innerClassName.equals(className)) {
+ foundInners.addElement(innerClassName);
+ }
+ }
+ break;
+ }
+ }
+ // Fill in the inner class array with the found inner classes.
+ innerClassNames = new String[foundInners.size()];
+ foundInners.toArray(innerClassNames);
+ }
+
+ /**
+ * Returns an array of inner classes of this class.
+ *
+ * @return an array of inner class names.
+ */
+ public String[] getInnerClassNames() {
+ return innerClassNames;
+ }
+
+ /**
+ * Allows to include a disassembled code into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includeCode(boolean value) {
+ printCode = value;
+ }
+
+ /**
+ * Allows to include line numbers into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includeLineNumbers(boolean value) {
+ printLineNumbers = value;
+ }
+
+ /**
+ * Allows to include local variables into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includeLocalVariables(boolean value) {
+ printLocalVariables = value;
+ }
+
+ /**
+ * Allows to include internal type signatures into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includeTypeSignatures(boolean value) {
+ printTypeSignatures = value;
+ }
+
+ /**
+ * Allows to include package private methods into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includePackagePrivate(boolean value) {
+ printPackagePrivate = value;
+ }
+
+ /**
+ * Allows to include public methods into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includePublic(boolean value) {
+ printPublic = value;
+ }
+
+ /**
+ * Allows to include protected methods into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includeProtected(boolean value) {
+ printProtected = value;
+ }
+
+ /**
+ * Allows to include private methods into the output of
+ * the <code>toString</code> method.
+ *
+ * @param value - true, if the inclusion is allowed. Otherwise false.
+ */
+ public void includePrivate(boolean value) {
+ printPrivate = value;
+ }
+
+ /**
+ * Determines if the given access is acceptable.
+ *
+ * @param access - the tested flags.
+ * @return true, if the given access of a class or a memeber is acceptable.
+ */
+ private boolean isPrintable(AccessFlags access) {
+ if (access.isPrivate() && !printPrivate
+ || access.isProtected() && !printProtected
+ || access.isPublic() && !printPublic
+ || !access.isPublic() && !access.isProtected()
+ && !access.isPrivate() && !printPackagePrivate) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns a string that does not include the given tokens.
+ *
+ * @param s - a source string.
+ * @param tokens - a string array of tokens to be skipped.
+ * @return the result string.
+ */
+ private String skipTokens(String s, String tokens[]) {
+ StringBuffer result = new StringBuffer();
+ // We are going to process the given string as a series of tokens,
+ // since we want to modify it a little.
+ StringTokenizer st = new StringTokenizer(s);
+ boolean empty = true;
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ boolean skip = false;
+ // Test, if the current token should be skipped.
+ for (int i = 0; i < tokens.length; i++) {
+ if (token.equals(tokens[i])) {
+ skip = true;
+ break;
+ }
+ }
+ if (skip) {
+ continue;
+ }
+ if (!empty) {
+ result.append(' ');
+ }
+ result.append(token);
+ empty = false;
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns a string of spaces whose length is equal to the given argument.
+ *
+ * @param indent - a number of space symbols of the result string.
+ * @return an indentaion string with the specified length.
+ */
+ private String indentString(int indent) {
+ return indentString(indent, "");
+ }
+
+ /**
+ * Indents the given string with the given number of spaces.
+ *
+ * @param indent - a number of space symbols the result string indentation.
+ * @param s - a string to be indent.
+ * @return the given string indented by the given number of spaces.
+ */
+ private String indentString(int indent, String s) {
+ StringBuffer result = new StringBuffer();
+
+ // Prepare the indentation prefix.
+ char[] chars = new char[indent];
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = ' ';
+ }
+
+ // Append it to the result for the first line.
+ result.append(chars);
+
+ // Prepend the prefix to each line of the given string.
+ // We also replace the '\n' symbol which is used as EOL by BCEL with
+ // the platform specific one.
+ int fromIndex = 0;
+ int toIndex = 0;
+ while ((toIndex = s.indexOf('\n', fromIndex)) != -1) {
+ // Append a substring before '\n'.
+ result.append(s.substring(fromIndex, toIndex));
+ // Append "line.separator".
+ result.append(n);
+ fromIndex = toIndex + 1;
+ // Append the prefix in beginning of the next line,
+ // if it is not the latest.
+ if (fromIndex < s.length()) {
+ result.append(chars);
+ }
+ }
+ // Append the rest of the given string.
+ result.append(s.substring(fromIndex));
+
+ return result.toString();
+ }
+
+ /**
+ * Returns some extra information.
+ *
+ * @param indent - an indentation.
+ * @return an indented string with some extra information.
+ */
+ private String printExtra(int indent) {
+ StringBuffer result = new StringBuffer();
+ StringBuffer l = new StringBuffer();
+ StringBuffer r = new StringBuffer();
+
+ // Create the indentation string.
+ String indentStr = indentString(indent);
+
+ // Append a source file name.
+ result.append(indentStr);
+ result.append("SourceFile: ");
+ result.append('\"');
+ result.append(wrappedClass.getSourceFileName());
+ result.append('\"');
+ result.append(n);
+
+ // Append inner classes.
+ if (innerClasses != null && innerClasses.getLength() > 0) {
+ result.append(indentStr);
+ result.append("InnerClass:");
+ result.append(n);
+
+ InnerClass inners[] = innerClasses.getInnerClasses();
+ for (int i = 0; i < inners.length; i++) {
+ InnerClass ic = inners[i];
+ int innerAccessFlags = ic.getInnerAccessFlags();
+ int innerNameIndex = ic.getInnerNameIndex();
+ int innerClassIndex = ic.getInnerClassIndex();
+ int outerClassIndex = ic.getOuterClassIndex();
+
+ // Append the indentation.
+ result.append(indentStr);
+ result.append(indentStr);
+
+ // Append an access string.
+ String access = Utility.accessToString(innerAccessFlags, true);
+ if (access.length() > 0) {
+ result.append(access);
+ result.append(' ');
+ }
+
+ // Construct a string like this:
+ // #?= #? of #?; //?=class ? of class ?
+ // Every number or string represented as '?' may be empty.
+ // So we try to eliminate strings like this:
+ // #0= #0 of #0; //=class of class
+
+ l.setLength(0);
+ r.setLength(0);
+
+ if (innerClassIndex > 0) {
+
+ if (innerNameIndex > 0) {
+ l.append('#');
+ l.append(innerNameIndex);
+ l.append("= ");
+
+ r.append(constPool.constantToString(
+ constPool.getConstant(innerNameIndex)));
+ r.append("=");
+ }
+
+ l.append("#");
+ l.append(innerClassIndex);
+
+ r.append("class ");
+ r.append(constPool.constantToString(
+ constPool.getConstant(innerClassIndex)));
+
+ if (outerClassIndex > 0) {
+ l.append(" of #");
+ l.append(outerClassIndex);
+
+ r.append(" of class ");
+ r.append(constPool.constantToString(
+ constPool.getConstant(outerClassIndex)));
+ }
+
+ if (l.length() > 0) {
+ result.append(l);
+ result.append(";");
+
+ if (r.length() > 0) {
+ result.append(" //");
+ result.append(r);
+ }
+ }
+
+ result.append(n);
+
+ }
+
+ }
+ }
+
+ // Append a version number.
+ result.append(indentStr);
+ result.append("minor version: ");
+ result.append(wrappedClass.getMinor());
+ result.append(n);
+ result.append(indentStr);
+ result.append("major version: ");
+ result.append(wrappedClass.getMajor());
+ result.append(n);
+
+ // Append a constant pool.
+ if (constPool.getLength() > 0) {
+ result.append(indentStr);
+ result.append("Constant pool:");
+ result.append(n);
+
+ Constant pool[] = constPool.getConstantPool();
+ for (int i = 0; i < pool.length; i++) {
+ Constant constant = pool[i];
+ // pool[i] may be null, so we skip such elements.
+ if (constant == null) {
+ continue;
+ }
+
+ result.append(indentStr);
+ result.append(indentStr);
+ result.append("const #");
+ result.append(i);
+ result.append(" = ");
+
+ // Append a constant specific string.
+ if (constant instanceof ConstantUtf8) {
+ ConstantUtf8 c = (ConstantUtf8) constant;
+ result.append("Asciz\t");
+ result.append(constPool.constantToString(c));
+ result.append(';');
+ } else if (constant instanceof ConstantFieldref) {
+ ConstantFieldref c = (ConstantFieldref) constant;
+ result.append("Field\t#");
+ result.append(c.getClassIndex());
+ result.append(".#");
+ result.append(c.getNameAndTypeIndex());
+ result.append(";\t// ");
+ result.append(Utility.replace(
+ constPool.constantToString(c), " ", ":"));
+ } else if (constant instanceof ConstantNameAndType) {
+ ConstantNameAndType c = (ConstantNameAndType) constant;
+ result.append("NameAndType\t#");
+ result.append(c.getNameIndex());
+ result.append(":#");
+ result.append(c.getSignatureIndex());
+ result.append(";\t// ");
+ result.append(Utility.replace(
+ constPool.constantToString(c), " ", ":"));
+ } else if (constant instanceof ConstantMethodref) {
+ ConstantMethodref c = (ConstantMethodref) constant;
+ result.append("Method\t#");
+ result.append(c.getClassIndex());
+ result.append(".#");
+ result.append(c.getNameAndTypeIndex());
+ result.append(";\t// ");
+ result.append(Utility.replace(
+ constPool.constantToString(c), " ", ":"));
+ } else if (constant instanceof ConstantInterfaceMethodref) {
+ ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant;
+ result.append("InterfaceMethod\t#");
+ result.append(c.getClassIndex());
+ result.append(".#");
+ result.append(c.getNameAndTypeIndex());
+ result.append(";\t// ");
+ result.append(Utility.replace(
+ constPool.constantToString(c), " ", ":"));
+ } else if (constant instanceof ConstantDouble) {
+ ConstantDouble c = (ConstantDouble) constant;
+ result.append("double\t");
+ result.append(constPool.constantToString(c));
+ result.append(';');
+ } else if (constant instanceof ConstantFloat) {
+ ConstantFloat c = (ConstantFloat) constant;
+ result.append("float\t");
+ result.append(constPool.constantToString(c));
+ result.append(';');
+ } else if (constant instanceof ConstantInteger) {
+ ConstantInteger c = (ConstantInteger) constant;
+ result.append("int\t");
+ result.append(constPool.constantToString(c));
+ result.append(';');
+ } else if (constant instanceof ConstantLong) {
+ ConstantLong c = (ConstantLong) constant;
+ result.append("long\t");
+ result.append(constPool.constantToString(c));
+ result.append(';');
+ } else if (constant instanceof ConstantClass) {
+ ConstantClass c = (ConstantClass) constant;
+ result.append("class\t#");
+ result.append(c.getNameIndex());
+ result.append(";\t// ");
+ result.append(constPool.constantToString(c));
+ } else if (constant instanceof ConstantString) {
+ ConstantString c = (ConstantString) constant;
+ result.append("String\t#");
+ result.append(c.getStringIndex());
+ result.append(";\t// ");
+ result.append(constPool.constantToString(c));
+ }
+
+ result.append(n);
+ }
+ }
+
+ result.append(n);
+
+ return result.toString();
+ }
+
+ /**
+ * Returns some information about the class fields.
+ *
+ * @param indent - an indentation.
+ * @return an indented string with some information about the class fields.
+ */
+ private String printFields(int indent) {
+ StringBuffer result = new StringBuffer();
+
+ Field fields[] = wrappedClass.getFields();
+ if (fields.length > 0) {
+ // Create the indentation string.
+ String indentStr = indentString(indent);
+
+ boolean found = false;
+ for (int i = 0; i < fields.length; i++) {
+ Field f = fields[i];
+
+ // Skip a field, if we should not print an information about it.
+ if (!isPrintable(f)) {
+ continue;
+ }
+ found = true;
+
+ result.append(n);
+ result.append(indentStr);
+
+ // Append an access string.
+ String access = Utility.accessToString(f.getAccessFlags());
+ if (access.length() > 0) {
+ result.append(access);
+ result.append(' ');
+ }
+ // Append a field signature and name.
+ result.append(Utility.signatureToString(f.getSignature()));
+ result.append(' ');
+ result.append(f.getName());
+ result.append(';');
+ result.append(n);
+
+ // Append a type signature.
+ if (printTypeSignatures) {
+ result.append(indentString(indent * 2, "Signature: "));
+ result.append(f.getSignature());
+ result.append(n);
+ }
+
+ if (verbose) {
+ // Append a field constant value, if any.
+ ConstantValue cv = f.getConstantValue();
+ if (cv != null) {
+ result.append(indentString(indent * 2,
+ "Constant value: "));
+ result.append(cv);
+ result.append(n);
+ }
+
+ Attribute attrs[] = f.getAttributes();
+ for (int j = 0; j < attrs.length; j++) {
+ if (attrs[j].getTag() == Constants.ATTR_SYNTHETIC) {
+ result.append(indentString(indent * 2,
+ "Synthetic: true"));
+ result.append(n);
+ break;
+ }
+ }
+ }
+
+ }
+ if (found) {
+ result.append(n);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns some information about the class methods.
+ *
+ * @param indent - an indentation.
+ * @return an indented string with some information about the class methods.
+ */
+ private String printMethods(int indent) {
+ StringBuffer result = new StringBuffer();
+
+ // Create the indentation string.
+ String indentStr = indentString(indent);
+
+ Method methods[] = wrappedClass.getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method m = methods[i];
+
+ // Skip a method, if we should not print an information about it.
+ if (!isPrintable(m)) {
+ continue;
+ }
+
+ result.append(n);
+ result.append(indentStr);
+
+ // The default values.
+ String methodName = m.getName();
+ String signature = m.getSignature();
+
+ if (methodName.equals("<clinit>")) {
+ // The "static" block of a class.
+ result.append("static {}");
+ } else {
+ boolean ctor = false;
+ if (methodName.equals("<init>")) {
+ // It's a constructor.
+ ctor = true;
+ }
+
+ // Create a method string.
+ String methodStr = Utility.methodSignatureToString(
+ signature,
+ ctor ? wrappedClass.getClassName() : methodName,
+ Utility.accessToString(m.getAccessFlags()),
+ true,
+ m.getLocalVariableTable());
+
+ if (ctor) {
+ // Remove the "void" word, if this is a constructor.
+ methodStr = skipTokens(methodStr, new String[] {"void"});
+ }
+
+ // Append the method string.
+ result.append(methodStr);
+
+ // Append an exception table.
+ ExceptionTable e = m.getExceptionTable();
+ if (e != null) {
+ String exceptions = e.toString();
+ if (exceptions.length() > 0) {
+ result.append(n);
+ result.append(indentString(indent * 3, "throws "));
+ result.append(exceptions);
+ }
+ }
+ }
+
+ result.append(';');
+ result.append(n);
+
+ // Append a signature.
+ if (printTypeSignatures) {
+ result.append(indentString(indent * 2, "Signature: "));
+ result.append(signature);
+ result.append(n);
+ }
+
+ // Append a code.
+ if (printCode) {
+ Code code = m.getCode();
+ // If the method is not abstract.
+ if (code != null) {
+ result.append(indentString(indent * 2, "Code: "));
+ result.append(n);
+
+ if (verbose) {
+ result.append(indentString(indent * 3, "Max stack="));
+ result.append(code.getMaxStack());
+ result.append(", Max locals=");
+ result.append(code.getMaxLocals());
+ result.append(n);
+ }
+
+ // Append the code string.
+ result.append(indentString(
+ indent * 3,
+ Utility.codeToString(
+ code.getCode(), constPool, 0, -1, verbose
+ ))
+ );
+ }
+ }
+
+ // Append a table of the line numbers.
+ if (printLineNumbers) {
+ LineNumberTable lt = m.getLineNumberTable();
+ if (lt != null) {
+ LineNumber nums[] = lt.getLineNumberTable();
+ if (nums.length > 0) {
+ String indentStr3 = indentString(indent * 3);
+ result.append(indentString(
+ indent * 2, "LineNumberTable:"));
+ result.append(n);
+ for (int j = 0; j < nums.length; j++) {
+ LineNumber ln = nums[j];
+ result.append(indentStr3);
+ result.append("line ");
+ result.append(ln.getLineNumber());
+ result.append(": ");
+ result.append(ln.getStartPC());
+ result.append(n);
+ }
+ }
+ }
+ }
+
+ // Append the local variables table.
+ if (printLocalVariables) {
+ LocalVariableTable vt = m.getLocalVariableTable();
+ if (vt != null) {
+ LocalVariable vars[] = vt.getLocalVariableTable();
+ if (vars.length > 0) {
+ String indentStr3 = indentString(indent * 3);
+ result.append(indentString(
+ indent * 2, "LocalVariableTable:"));
+ result.append(n);
+ result.append(indentStr3);
+ result.append("Start\tLength\tSlot\tName\tSignature");
+ result.append(n);
+ for (int j = 0; j < vars.length; j++) {
+ LocalVariable lv = vars[j];
+ result.append(indentStr3);
+ result.append(lv.getStartPC());
+ result.append("\t\t");
+ result.append(lv.getLength());
+ result.append("\t");
+ result.append(lv.getIndex());
+ result.append("\t");
+ result.append(lv.getName());
+ result.append("\t");
+ result.append(lv.getSignature());
+ result.append("\t");
+ result.append(n);
+ }
+ }
+ }
+ }
+
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns a string that represents a structural information about
+ * a wrapped class.
+ */
+ public String toString() {
+ StringBuffer result = new StringBuffer();
+
+ // Append a source file name.
+ result.append(n);
+ result.append("Compiled from ");
+ result.append('\"');
+ result.append(wrappedClass.getSourceFileName());
+ result.append('\"');
+ result.append(n);
+
+ // Construct a class access string.
+ int classAccess = wrappedClass.getAccessFlags();
+ String classAccessStr = Utility.accessToString(classAccess, true);
+ if (wrappedClass.isInterface()) {
+ // Remove the "abstract" word, if this is an interface.
+ classAccessStr = skipTokens(
+ classAccessStr, new String[] {"abstract"});
+ }
+ // Append the access string.
+ if (classAccessStr.length() > 0) {
+ result.append(classAccessStr);
+ result.append(' ');
+ }
+
+ // Append the word "class" or "interface".
+ result.append(Utility.classOrInterface(classAccess));
+ result.append(' ');
+ result.append(wrappedClass.getClassName());
+
+ // Append the name of an extended class.
+ // We skip the sequence "extends java.lang.Object".
+ if (!wrappedClass.getSuperclassName().equals("java.lang.Object")) {
+ result.append(" extends ");
+ result.append(Utility.compactClassName(
+ wrappedClass.getSuperclassName(), false));
+ }
+
+ // Append the names of the implemented interfaces.
+ String interfaces[] = wrappedClass.getInterfaceNames();
+ if (interfaces.length > 0) {
+ result.append(" implements");
+ for (int i = 0; i < interfaces.length; i++) {
+ if (i > 0) {
+ result.append(',');
+ }
+ result.append(' ');
+ result.append(interfaces[i]);
+ }
+ }
+
+ // Append the open brace.
+ result.append(' ');
+ result.append('{');
+ result.append(n);
+
+ // The default value.
+ int indent = 4;
+
+ // Append some extra information, if verbose is true.
+ if (verbose) {
+ result.append(printExtra(indent));
+ }
+
+ // Append the filtered fields and their signatures.
+ result.append(printFields(indent));
+
+ // Append the filtered methods and their signatures.
+ result.append(printMethods(indent));
+
+ // Append the close brace.
+ result.append(n);
+ result.append('}');
+ result.append(n);
+
+ return result.toString();
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Clazz.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java?rev=669581&view=auto
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java Thu Jun 19 10:26:42 2008
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.tools.javap;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+//import org.apache.harmony.tools.javap.ClassProvider;
+
+/**
+ * This is a tool that allows you to disassemble class files.
+ */
+public class Main {
+
+ /**
+ * Prints the usage information.
+ */
+ public static void usage() {
+ System.out.println("Class file disassembler.");
+ System.out.println();
+ System.out.println("Usage: " + Main.class.getName()
+ + " [options] <class names>\n");
+ System.out.println("[options]");
+ System.out.println(" -bootclasspath <path> The given path will be prepended to");
+ System.out.println(" the default class path.\n");
+ System.out.println(" -classpath <path> The given path will be appended to");
+ System.out.println(" the default class path.\n");
+ System.out.println(" -extdirs <dirs> Override extension locations.\n");
+
+ System.out.println(" -package Print package visible, protected");
+ System.out.println(" and public classes and members. (default)\n");
+ System.out.println(" -public Print public classes and members.\n");
+ System.out.println(" -protected Print protected and public classes and members.\n");
+ System.out.println(" -private Print all classes and members.\n");
+ System.out.println(" -c Print the code.\n");
+ System.out.println(" -l Print line numbers and local variables.\n");
+ System.out.println(" -s Print type signatures.\n");
+
+ System.out.println(" -inner Inner classes will be processed automatically.\n");
+ System.out.println(" -verbose Allows running commentary.\n");
+ System.out.println("<class names> A list of the fully qualified class names");
+ System.out.println(" separated by a space.");
+ }
+
+ /**
+ * A convenient way to run this tool from a command line.
+ */
+ public static void main(String args[]) {
+ if (args.length < 1) {
+ usage();
+ System.exit(1);
+ }
+
+ String pathSep = null;
+ try {
+ pathSep = System.getProperty("path.separator");
+ } catch (SecurityException e) {
+ // ignore
+ }
+
+ Set names = new HashSet();
+ Map options = new HashMap();
+ int i = 0;
+ while (i < args.length) {
+ if (args[i].equals("-bootclasspath")
+ || args[i].equals("-classpath")
+ || args[i].equals("-extdirs")) {
+ String path = (String) args[i + 1];
+
+ // Process the "-extdirs" option as "-bootclasspath".
+ String opt = (String) args[i];
+ if (opt.equals("-extdirs")) {
+ opt = "-bootclasspath";
+ }
+
+ // We can concatenate several options, if there is no
+ // security restriction; otherwise, the new option replaces
+ // the old one.
+ if (pathSep != null) {
+ String prevPath = (String) options.get(opt);
+ if (prevPath != null) {
+ path = prevPath + pathSep + path;
+ }
+ }
+
+ options.put(opt, path);
+ i++;
+ } else if (args[i].equals("-c")
+ || args[i].equals("-package")
+ || args[i].equals("-public")
+ || args[i].equals("-protected")
+ || args[i].equals("-private")
+ || args[i].equals("-l")
+ || args[i].equals("-s")
+ || args[i].equals("-inner")
+ || args[i].equals("-verbose")) {
+ options.put(args[i], Boolean.valueOf(true));
+ } else if (args[i].startsWith("-")) {
+ System.err.println("Unknown option: " + args[i]);
+ } else {
+ names.add(args[i]);
+ }
+ i++;
+ }
+ System.exit(run(options, names));
+ }
+
+ /**
+ * Runs a tool.
+ *
+ * @param options - a <code>java.util.Map</code> of the following key-value
+ * pairs.
+ *
+ * <li> <i>key</i> - "-bootclasspath"
+ * <li> <i>value</i> - a <code>java.lang.String</code> which is a path
+ * where bootstrap classes are located.
+ *
+ * <li> <i>key</i> - "-classpath"
+ * <li> <i>value</i> - a <code>java.lang.String</code> which is a path
+ * where classes are located.
+ *
+ * <li> <i>key</i> - "-c"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if the code should be printed.
+ *
+ * <li> <i>key</i> - "-package"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if package visible, protected and public
+ * classes and members should be printed.
+ *
+ * <li> <i>key</i> - "-public"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if public classes and members should be printed.
+ *
+ * <li> <i>key</i> - "-protected"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if protected and public classes and members
+ * should be printed.
+ *
+ * <li> <i>key</i> - "-private"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if all classes and members should be printed.
+ *
+ * <li> <i>key</i> - "-l"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if line numbers and local variables should be printed.
+ *
+ * <li> <i>key</i> - "-s"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if type signatures should be printed.
+ *
+ * <li> <i>key</i> - "-inner"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if inner classes should be processed automatically,
+ * that is, as if they are specified as elements of
+ * the <code>classNames</code> parameter.
+ *
+ * <li> <i>key</i> - "-verbose"
+ * <li> <i>value</i> - a <code>java.lang.Boolean</code> which is equal to
+ * <code>true</code>, if the verbose output is needed.
+ *
+ * @param classNames - a set of the fully qualified class names.
+ * @return <code>0</code> if there is no error; <code>1</code> otherwise.
+ */
+ public static int run(Map options, Set classNames) {
+ String bootClasspath = getString(options, "-bootclasspath");
+ String classpath = getString(options, "-classpath");
+
+ boolean c = getBoolean(options, "-c");
+ boolean l = getBoolean(options, "-l");
+ boolean s = getBoolean(options, "-s");
+ boolean pack = getBoolean(options, "-package");
+ boolean pub = getBoolean(options, "-public");
+ boolean prot = getBoolean(options, "-protected");
+ boolean priv = getBoolean(options, "-private");
+
+ // The default option is "-package".
+ if (!pub && !prot && !priv) {
+ pack = true;
+ }
+
+ // Show all classes and their members.
+ if (priv) {
+ pack = true;
+ }
+ // Show package private, protected and public classes and their members.
+ if (pack) {
+ prot = true;
+ }
+ // Show protected and public classes and their members.
+ if (prot) {
+ pub = true;
+ }
+
+ boolean inner = getBoolean(options, "-inner");
+ boolean verbose = getBoolean(options, "-verbose");
+
+ ClassProvider classProvider = new ClassProvider(bootClasspath,
+ classpath, verbose);
+
+ StringBuffer result = new StringBuffer();
+ try {
+ String n = System.getProperty("line.separator");
+
+ Set innerNames = new HashSet();
+ Iterator namesIter = classNames.iterator();
+ while (namesIter.hasNext()) {
+
+ // Parse the next class.
+ Clazz clazz = new Clazz(classProvider,
+ (String) namesIter.next(), verbose);
+
+ // Set the output filter before we call clazz.toString().
+ clazz.includeCode(c);
+ clazz.includeLineNumbers(l);
+ clazz.includeLocalVariables(l);
+ clazz.includeTypeSignatures(s);
+ clazz.includePackagePrivate(pack);
+ clazz.includePublic(pub);
+ clazz.includeProtected(prot);
+ clazz.includePrivate(priv);
+
+ if (inner) {
+ // Get the inner class names and store them
+ // in a separate set.
+ String innerClassNames[] = clazz.getInnerClassNames();
+ for (int i = 0; i < innerClassNames.length; i++) {
+ innerNames.add(innerClassNames[i]);
+ }
+ }
+
+ // Process the next class.
+ result.append(clazz.toString());
+ result.append(n);
+
+ // Process the inner class names, if any.
+ if (!namesIter.hasNext() && !innerNames.isEmpty()) {
+ // Remove the inner class names that have already
+ // been processed.
+ innerNames.removeAll(classNames);
+
+ // Reset the loop iterator.
+ classNames = new HashSet(innerNames);
+ namesIter = classNames.iterator();
+
+ // Clear the set of the inner class names.
+ innerNames.clear();
+ inner = false;
+ }
+
+ }
+
+ } catch (Exception e) {
+ System.err.println("Error:");
+ e.printStackTrace();
+ return 1;
+ }
+
+ // Print the result.
+ System.out.print(result.toString());
+
+ return 0;
+ }
+
+ private static String getString(Map options, String name) {
+ try {
+ return (String) options.get(name);
+ } catch (ClassCastException e) {
+ throw new RuntimeException(
+ "'" + name + "': expected java.lang.String", e);
+ }
+ }
+
+ private static boolean getBoolean(Map options, String name) {
+ try {
+ Object value = options.get(name);
+ if (value != null) {
+ return ((Boolean) value).booleanValue();
+ }
+ } catch (ClassCastException e) {
+ throw new RuntimeException(
+ "'" + name + "': expected java.lang.Boolean", e);
+ }
+ return false;
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/tools/src/main/java/org/apache/harmony/tools/javap/Main.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/trunk/COPYRIGHT
URL: http://svn.apache.org/viewvc/harmony/enhanced/trunk/COPYRIGHT?rev=669581&r1=669580&r2=669581&view=diff
==============================================================================
--- harmony/enhanced/trunk/COPYRIGHT (original)
+++ harmony/enhanced/trunk/COPYRIGHT Thu Jun 19 10:26:42 2008
@@ -5,3 +5,5 @@
(C) Copyright 2005 Intel Corporation
(C) Copyright 2005-2006 Intel Corporation
+
+ (C) Copyright 2006 Intel Corporation