提交 4ed706a5 编写于 作者: Y yan

Merge

......@@ -33,3 +33,6 @@ dbdeb4a7581b2a8699644b91cae6793cb01953f7 jdk7-b53
825f23a4f262eb06cfc94406140f3bfecb17ffe8 jdk7-b56
4030cc469205bbd517ca629fb170afb81760bbc5 jdk7-b57
5bcac54d408b436d2364925ee7947b5609e07962 jdk7-b58
88bcb6772159602317f2e184a69010737db72270 jdk7-b59
5cdce469ea2ad90d308c9abe420fd0643c0a6b9e jdk7-b60
522520757dd34321b27a7145ecbd24ac4fb64f34 jdk7-b61
......@@ -15,7 +15,7 @@ that expect to be able to build this workspace with GNU Make.
System Requirements:
Ant: version 1.6.5 or later
NetBeans: version 5.0 or later (optional)
NetBeans: version 6.0 or later (optional)
JDK: currently version 1.5.0, although 1.6.0 is recommended
OS: any system supporting the above tools
......
......@@ -105,6 +105,11 @@ else
endif
endif
ifeq ($(DEBUG_CLASSFILES), true)
ANT_OPTIONS += -Djavac.debug=true
ANT_OPTIONS += -Ddebug.classfiles=true
endif
# Note: jdk/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN)
# and the somewhat misnamed CLASS_VERSION (-target NN)
ifdef TARGET_CLASS_VERSION
......@@ -115,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)
......
Building the "langtools" workspace.
The "langtools" workspace can be built from the command line with Ant.
The build file is make/build.xml, in conjunction with make/build.properties.
Some additional user-specific properties files are also read, to allow
you to customize selected properties as needed.
Individual tools within the workspace can also be built and worked on
with NetBeans, using the projects in the make/netbeans directory.
The "langtools" workspace can also be built from the command line with
GNU Make, although the Makefile is simply a wrapper around the Ant
build file. This is provided for systems (such as the full OpenJDK build)
that expect to be able to build this workspace with GNU Make.
System Requirements:
Ant: version 1.6.5 or later
NetBeans: version 6.0 or later (optional)
JDK: currently version 1.5.0, although 1.6.0 is recommended
OS: any system supporting the above tools
For more information:
Ant: http://ant.apache.org/
GNU Make: http://www.gnu.org/software/make/
NetBeans: http://www.netbeans.org/
Testing the "langtools" workspace.
The primary set of tests for the compiler is the compiler TCK. This
tests that the compiler performs according to the specifications in
JLS and JVMS.
In addition, there is a substantial collection of regression and unit
tests for all the tools in the maain langtools test/ directory.
Finally, there is a small set of tests to do basic validation of a build
of the langtools workspace for use by JDK. These tests check the contents
of the dist/ directory generated by the build, and verify that the various
tools can do basic "Hello World"-style processing. These tests should be
run by jtreg, with the -jdk option set a version of JDK capable of running
the default output of the javac compiler in this workspace. Currently,
this means JDK 6 or better.
......@@ -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
......
......@@ -32,6 +32,13 @@
<project name="langtools" default="build" basedir="..">
<!-- Force full debuginfo for javac if the debug.classfiles
property is set. This must be BEFORE the include of
build.properties because it sets javac.debuglevel. -->
<condition property="javac.debuglevel" value="source,lines,vars">
<equals arg1="${debug.classfiles}" arg2="true"/>
</condition>
<!-- The following locations can be used to override default property values. -->
<!-- Use this location for customizations specific to this instance of this workspace -->
......@@ -308,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>
......@@ -393,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=""/>
......@@ -411,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}"/>
......@@ -435,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=""/>
......@@ -450,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}"/>
......@@ -474,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}"/>
......@@ -502,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}"/>
......@@ -515,6 +528,7 @@
excludes="@{excludes}"
sourcepath=""
includeAntRuntime="no"
source="@{javac.source}"
target="@{javac.target}"
debug="${javac.debug}"
debuglevel="${javac.debuglevel}">
......@@ -540,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"
......@@ -555,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();
}
......
/*
* 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;
}
}
......@@ -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;
}
/*
* 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;
}
/**
* 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();
InstructionDetailWriter(Context context) {
super(context);
}
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
......
/*
* 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;
}
/*
* 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);
......
/*
* 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,28 +23,20 @@
* have any questions.
*/
package com.sun.tools.javap;
package sun.tools.javap;
import java.util.*;
import java.io.*;
import java.util.Locale;
/**
* Strores LineNumberTable data information.
* 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 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();
public interface Messages {
String getMessage(String key, Object... args);
}
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;
......
/*
* 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;
}
/*
* 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 = { };
}
/*
* 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\
......
/*
* 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;
}
}
/*
* 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"
};
}
/*
* 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;
}
}
/*
* 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
/*
* 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;
}
}
此差异已折叠。
/*
* 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);
}
}
此差异已折叠。
/*
* 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;
}
}
......@@ -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;
......
/*
* @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;
......
......@@ -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
*/
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
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
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册