提交 abb1660b 编写于 作者: T tbell

Merge

......@@ -58,7 +58,7 @@ public class AccessFlags {
public static final int ACC_ENUM = 0x4000; // class, inner, field
public static final int ACC_MODULE = 0x8000; // class, inner, field, method
private static enum Type { Class, InnerClass, Field, Method};
public static enum Kind { Class, InnerClass, Field, Method};
AccessFlags(ClassReader cr) throws IOException {
this(cr.readUnsignedShort());
......@@ -87,11 +87,11 @@ public class AccessFlags {
public Set<String> getClassModifiers() {
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
return getModifiers(f, classModifiers, Type.Class);
return getModifiers(f, classModifiers, Kind.Class);
}
public Set<String> getClassFlags() {
return getFlags(classFlags, Type.Class);
return getFlags(classFlags, Kind.Class);
}
private static final int[] innerClassModifiers = {
......@@ -106,11 +106,11 @@ public class AccessFlags {
public Set<String> getInnerClassModifiers() {
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
return getModifiers(f, innerClassModifiers, Type.InnerClass);
return getModifiers(f, innerClassModifiers, Kind.InnerClass);
}
public Set<String> getInnerClassFlags() {
return getFlags(innerClassFlags, Type.InnerClass);
return getFlags(innerClassFlags, Kind.InnerClass);
}
private static final int[] fieldModifiers = {
......@@ -124,11 +124,11 @@ public class AccessFlags {
};
public Set<String> getFieldModifiers() {
return getModifiers(fieldModifiers, Type.Field);
return getModifiers(fieldModifiers, Kind.Field);
}
public Set<String> getFieldFlags() {
return getFlags(fieldFlags, Type.Field);
return getFlags(fieldFlags, Kind.Field);
}
private static final int[] methodModifiers = {
......@@ -143,18 +143,18 @@ public class AccessFlags {
};
public Set<String> getMethodModifiers() {
return getModifiers(methodModifiers, Type.Method);
return getModifiers(methodModifiers, Kind.Method);
}
public Set<String> getMethodFlags() {
return getFlags(methodFlags, Type.Method);
return getFlags(methodFlags, Kind.Method);
}
private Set<String> getModifiers(int[] modifierFlags, Type t) {
private Set<String> getModifiers(int[] modifierFlags, Kind t) {
return getModifiers(flags, modifierFlags, t);
}
private static Set<String> getModifiers(int flags, int[] modifierFlags, Type t) {
private static Set<String> getModifiers(int flags, int[] modifierFlags, Kind t) {
Set<String> s = new LinkedHashSet<String>();
for (int m: modifierFlags) {
if ((flags & m) != 0)
......@@ -163,7 +163,7 @@ public class AccessFlags {
return s;
}
private Set<String> getFlags(int[] expectedFlags, Type t) {
private Set<String> getFlags(int[] expectedFlags, Kind t) {
Set<String> s = new LinkedHashSet<String>();
int f = flags;
for (int e: expectedFlags) {
......@@ -180,7 +180,7 @@ public class AccessFlags {
return s;
}
private static String flagToModifier(int flag, Type t) {
private static String flagToModifier(int flag, Kind t) {
switch (flag) {
case ACC_PUBLIC:
return "public";
......@@ -195,7 +195,7 @@ public class AccessFlags {
case ACC_SYNCHRONIZED:
return "synchronized";
case 0x80:
return (t == Type.Field ? "transient" : null);
return (t == Kind.Field ? "transient" : null);
case ACC_VOLATILE:
return "volatile";
case ACC_NATIVE:
......@@ -211,7 +211,7 @@ public class AccessFlags {
}
}
private static String flagToName(int flag, Type t) {
private static String flagToName(int flag, Kind t) {
switch (flag) {
case ACC_PUBLIC:
return "ACC_PUBLIC";
......@@ -224,11 +224,11 @@ public class AccessFlags {
case ACC_FINAL:
return "ACC_FINAL";
case 0x20:
return (t == Type.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
return (t == Kind.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
case 0x40:
return (t == Type.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
case 0x80:
return (t == Type.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
case ACC_NATIVE:
return "ACC_NATIVE";
case ACC_INTERFACE:
......@@ -250,5 +250,5 @@ public class AccessFlags {
}
}
final int flags;
public final int flags;
}
......@@ -573,6 +573,11 @@ public class ConstantPool {
return visitor.visitNameAndType(this, data);
}
@Override
public String toString() {
return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
}
public final int name_index;
public final int type_index;
}
......@@ -600,6 +605,11 @@ public class ConstantPool {
return visitor.visitString(this, data);
}
@Override
public String toString() {
return "CONSTANT_String_info[class_index: " + string_index + "]";
}
public final int string_index;
}
......@@ -618,7 +628,19 @@ public class ConstantPool {
@Override
public String toString() {
return "CONSTANT_Utf8_info[value: " + value + "]";
if (value.length() < 32 && isPrintableAscii(value))
return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
else
return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
}
static boolean isPrintableAscii(String s) {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c < 32 || c >= 127)
return false;
}
return true;
}
public <R, D> R accept(Visitor<R, D> visitor, D data) {
......
......@@ -1066,6 +1066,21 @@ public class Type implements PrimitiveType {
return qtype.isErroneous();
}
/**
* Replaces this ForAll's typevars with a set of concrete Java types
* and returns the instantiated generic type. Subclasses might override
* in order to check that the list of types is a valid instantiation
* of the ForAll's typevars.
*
* @param actuals list of actual types
* @param types types instance
* @return qtype where all occurrences of tvars are replaced
* by types in actuals
*/
public Type inst(List<Type> actuals, Types types) {
return types.subst(qtype, tvars, actuals);
}
public Type map(Mapping f) {
return f.apply(qtype);
}
......
......@@ -343,6 +343,14 @@ public class Types {
if (s.tag >= firstPartialTag)
return isSuperType(s, t);
if (s.isCompound()) {
for (Type s2 : interfaces(s).prepend(supertype(s))) {
if (!isSubtype(t, s2, capture))
return false;
}
return true;
}
Type lower = lowerBound(s);
if (s != lower)
return isSubtype(capture ? capture(t) : t, lower, false);
......@@ -2870,6 +2878,14 @@ public class Types {
/**
* Capture conversion as specified by JLS 3rd Ed.
*/
public List<Type> capture(List<Type> ts) {
List<Type> buf = List.nil();
for (Type t : ts) {
buf = buf.prepend(capture(t));
}
return buf.reverse();
}
public Type capture(Type t) {
if (t.tag != CLASS)
return t;
......
......@@ -391,6 +391,10 @@ public class Check {
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
t, pt);
}
} catch (Infer.InvalidInstanceException ex) {
JCDiagnostic d = ex.getDiagnostic();
log.error(pos, "invalid.inferred.types", t.tvars, d);
return types.createErrorType(pt);
}
}
}
......
......@@ -29,6 +29,7 @@ import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.JCDiagnostic;
import static com.sun.tools.javac.code.TypeTags.*;
......@@ -49,6 +50,7 @@ public class Infer {
Symtab syms;
Types types;
Resolve rs;
JCDiagnostic.Factory diags;
public static Infer instance(Context context) {
......@@ -62,48 +64,60 @@ public class Infer {
context.put(inferKey, this);
syms = Symtab.instance(context);
types = Types.instance(context);
rs = Resolve.instance(context);
diags = JCDiagnostic.Factory.instance(context);
ambiguousNoInstanceException =
new NoInstanceException(true, diags);
unambiguousNoInstanceException =
new NoInstanceException(false, diags);
invalidInstanceException =
new InvalidInstanceException(diags);
}
public static class NoInstanceException extends RuntimeException {
public static class InferenceException extends RuntimeException {
private static final long serialVersionUID = 0;
boolean isAmbiguous; // exist several incomparable best instances?
JCDiagnostic diagnostic;
JCDiagnostic.Factory diags;
NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
InferenceException(JCDiagnostic.Factory diags) {
this.diagnostic = null;
this.isAmbiguous = isAmbiguous;
this.diags = diags;
}
NoInstanceException setMessage(String key) {
this.diagnostic = diags.fragment(key);
return this;
}
NoInstanceException setMessage(String key, Object arg1) {
this.diagnostic = diags.fragment(key, arg1);
return this;
}
NoInstanceException setMessage(String key, Object arg1, Object arg2) {
this.diagnostic = diags.fragment(key, arg1, arg2);
return this;
}
NoInstanceException setMessage(String key, Object arg1, Object arg2, Object arg3) {
this.diagnostic = diags.fragment(key, arg1, arg2, arg3);
InferenceException setMessage(String key, Object... args) {
this.diagnostic = diags.fragment(key, args);
return this;
}
public JCDiagnostic getDiagnostic() {
return diagnostic;
return diagnostic;
}
}
public static class NoInstanceException extends InferenceException {
private static final long serialVersionUID = 1;
boolean isAmbiguous; // exist several incomparable best instances?
NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
super(diags);
this.isAmbiguous = isAmbiguous;
}
}
public static class InvalidInstanceException extends InferenceException {
private static final long serialVersionUID = 2;
InvalidInstanceException(JCDiagnostic.Factory diags) {
super(diags);
}
}
private final NoInstanceException ambiguousNoInstanceException;
private final NoInstanceException unambiguousNoInstanceException;
private final InvalidInstanceException invalidInstanceException;
/***************************************************************************
* Auxiliary type values and classes
......@@ -158,8 +172,7 @@ public class Infer {
that.inst = types.glb(that.hibounds);
}
if (that.inst == null ||
that.inst.isErroneous() ||
!types.isSubtypeUnchecked(that.inst, that.hibounds, warn))
that.inst.isErroneous())
throw ambiguousNoInstanceException
.setMessage("no.unique.maximal.instance.exists",
that.qtype, that.hibounds);
......@@ -234,7 +247,7 @@ public class Infer {
*/
public Type instantiateExpr(ForAll that,
Type to,
Warner warn) throws NoInstanceException {
Warner warn) throws InferenceException {
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
UndetVar v = (UndetVar) l.head;
......@@ -260,8 +273,7 @@ public class Infer {
List<Type> targs = Type.map(undetvars, getInstFun);
targs = types.subst(targs, that.tvars, targs);
checkWithinBounds(that.tvars, targs, warn);
return getInstFun.apply(qtype1);
return that.inst(targs, types);
}
/** Instantiate method type `mt' by finding instantiations of
......@@ -269,36 +281,42 @@ public class Infer {
*/
public Type instantiateMethod(List<Type> tvars,
MethodType mt,
List<Type> argtypes,
boolean allowBoxing,
boolean useVarargs,
Warner warn) throws NoInstanceException {
final List<Type> argtypes,
final boolean allowBoxing,
final boolean useVarargs,
final Warner warn) throws InferenceException {
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
List<Type> formals = mt.argtypes;
//need to capture exactly once - otherwise subsequent
//applicability checks might fail
final List<Type> capturedArgs = types.capture(argtypes);
List<Type> actuals = capturedArgs;
List<Type> actualsNoCapture = argtypes;
// instantiate all polymorphic argument types and
// set up lower bounds constraints for undetvars
Type varargsFormal = useVarargs ? formals.last() : null;
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
Type ft = formals.head;
Type at = argtypes.head.baseType();
if (at.tag == FORALL)
at = instantiateArg((ForAll) at, ft, tvars, warn);
Type sft = types.subst(ft, tvars, undetvars);
while (actuals.nonEmpty() && formals.head != varargsFormal) {
Type formal = formals.head;
Type actual = actuals.head.baseType();
Type actualNoCapture = actualsNoCapture.head.baseType();
if (actual.tag == FORALL)
actual = instantiateArg((ForAll)actual, formal, tvars, warn);
Type undetFormal = types.subst(formal, tvars, undetvars);
boolean works = allowBoxing
? types.isConvertible(at, sft, warn)
: types.isSubtypeUnchecked(at, sft, warn);
? types.isConvertible(actual, undetFormal, warn)
: types.isSubtypeUnchecked(actual, undetFormal, warn);
if (!works) {
throw unambiguousNoInstanceException
.setMessage("no.conforming.assignment.exists",
tvars, at, ft);
tvars, actualNoCapture, formal);
}
formals = formals.tail;
argtypes = argtypes.tail;
actuals = actuals.tail;
actualsNoCapture = actualsNoCapture.tail;
}
if (formals.head != varargsFormal || // not enough args
!useVarargs && argtypes.nonEmpty()) { // too many args
!useVarargs && actuals.nonEmpty()) { // too many args
// argument lists differ in length
throw unambiguousNoInstanceException
.setMessage("arg.length.mismatch");
......@@ -306,20 +324,21 @@ public class Infer {
// for varargs arguments as well
if (useVarargs) {
Type elt = types.elemtype(varargsFormal);
Type sft = types.subst(elt, tvars, undetvars);
while (argtypes.nonEmpty()) {
Type ft = sft;
Type at = argtypes.head.baseType();
if (at.tag == FORALL)
at = instantiateArg((ForAll) at, ft, tvars, warn);
boolean works = types.isConvertible(at, sft, warn);
Type elemType = types.elemtype(varargsFormal);
Type elemUndet = types.subst(elemType, tvars, undetvars);
while (actuals.nonEmpty()) {
Type actual = actuals.head.baseType();
Type actualNoCapture = actualsNoCapture.head.baseType();
if (actual.tag == FORALL)
actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
boolean works = types.isConvertible(actual, elemUndet, warn);
if (!works) {
throw unambiguousNoInstanceException
.setMessage("no.conforming.assignment.exists",
tvars, at, ft);
tvars, actualNoCapture, elemType);
}
argtypes = argtypes.tail;
actuals = actuals.tail;
actualsNoCapture = actualsNoCapture.tail;
}
}
......@@ -350,16 +369,38 @@ public class Infer {
}
checkWithinBounds(tvars, undettypes.toList(), warn);
mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
if (!restvars.isEmpty()) {
// if there are uninstantiated variables,
// quantify result type with them
mt = new MethodType(mt.argtypes,
new ForAll(restvars.toList(), mt.restype),
mt.thrown, syms.methodClass);
final List<Type> inferredTypes = insttypes.toList();
final List<Type> all_tvars = tvars; //this is the wrong tvars
final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass);
mt2.restype = new ForAll(restvars.toList(), mt.restype) {
@Override
public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
if (!rs.argumentsAcceptable(capturedArgs, formals,
allowBoxing, useVarargs, warn)) {
// inferred method is not applicable
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
}
// check that inferred bounds conform to their bounds
checkWithinBounds(all_tvars,
types.subst(inferredTypes, tvars, inferred), warn);
return super.inst(inferred, types);
}};
return mt2;
}
else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
// inferred method is not applicable
throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
}
else {
// return instantiated version of method type
return mt;
}
// return instantiated version of method type
return types.subst(mt, tvars, insttypes.toList());
}
//where
......@@ -371,7 +412,7 @@ public class Infer {
private Type instantiateArg(ForAll that,
Type to,
List<Type> tvars,
Warner warn) throws NoInstanceException {
Warner warn) throws InferenceException {
List<Type> targs;
try {
return instantiateExpr(that, to, warn);
......@@ -388,16 +429,16 @@ public class Infer {
private void checkWithinBounds(List<Type> tvars,
List<Type> arguments,
Warner warn)
throws NoInstanceException {
throws InvalidInstanceException {
for (List<Type> tvs = tvars, args = arguments;
tvs.nonEmpty();
tvs = tvs.tail, args = args.tail) {
if (args.head instanceof UndetVar) continue;
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
throw unambiguousNoInstanceException
throw invalidInstanceException
.setMessage("inferred.do.not.conform.to.bounds",
arguments, tvars);
args.head, bounds);
}
}
}
......@@ -299,7 +299,7 @@ public class Resolve {
boolean allowBoxing,
boolean useVarargs,
Warner warn)
throws Infer.NoInstanceException {
throws Infer.InferenceException {
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
Type mt = types.memberType(site, m);
......@@ -370,7 +370,7 @@ public class Resolve {
try {
return rawInstantiate(env, site, m, argtypes, typeargtypes,
allowBoxing, useVarargs, warn);
} catch (Infer.NoInstanceException ex) {
} catch (Infer.InferenceException ex) {
return null;
}
}
......@@ -584,7 +584,7 @@ public class Resolve {
default: return bestSoFar;
}
}
} catch (Infer.NoInstanceException ex) {
} catch (Infer.InferenceException ex) {
switch (bestSoFar.kind) {
case ABSENT_MTH:
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
......
......@@ -1521,9 +1521,9 @@ public class ClassWriter extends ClassFile {
int acount = 0;
boolean sigReq =
typarams.length() != 0 || supertype.getTypeArguments().length() != 0;
typarams.length() != 0 || supertype.allparams().length() != 0;
for (List<Type> l = interfaces; !sigReq && l.nonEmpty(); l = l.tail)
sigReq = l.head.getTypeArguments().length() != 0;
sigReq = l.head.allparams().length() != 0;
if (sigReq) {
assert source.allowGenerics();
int alenIdx = writeAttr(names.Signature);
......
......@@ -84,7 +84,7 @@ compiler.err.cant.apply.symbol=\
{0} {1} in {4} {5} cannot be applied to given types\n\
required: {2}\n\
found: {3}
compiler.err.cant.apply.symbol.1=\
compiler.err.cant.apply.symbol.1=\
{0} {1} in {4} {5} cannot be applied to given types;\n\
required: {2}\n\
found: {3}\n\
......@@ -469,6 +469,8 @@ compiler.err.undetermined.type=\
type parameters of {0} cannot be determined
compiler.err.undetermined.type.1=\
type parameters of {0} cannot be determined; {1}
compiler.err.invalid.inferred.types=\
invalid inferred types for {0}; {1}
compiler.err.unreachable.stmt=\
unreachable statement
compiler.err.initializer.must.be.able.to.complete.normally=\
......@@ -995,7 +997,13 @@ compiler.misc.no.conforming.assignment.exists=\
compiler.misc.arg.length.mismatch=\
cannot instantiate from arguments because actual and formal argument lists differ in length
compiler.misc.inferred.do.not.conform.to.bounds=\
inferred type argument(s) {0} do not conform to bounds of type variable(s) {1}
inferred type does not conform to declared bound(s)\n\
inferred: {0}\n\
bound(s): {1}
compiler.misc.inferred.do.not.conform.to.params=\
actual arguments do not conforms to inferred formal arguments\n\
required: {0}\n\
found: {1}
#####
......
......@@ -172,9 +172,6 @@ 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) {
......@@ -482,5 +479,12 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
protected String capturedVarId(CapturedType t, Locale locale) {
return "" + (allCaptured.indexOf(t) + 1);
}
@Override
public String visitCapturedType(CapturedType t, Locale locale) {
if (!allCaptured.contains(t)) {
allCaptured = allCaptured.append(t);
}
return super.visitCapturedType(t, locale);
}
};
}
......@@ -74,7 +74,7 @@ import static com.sun.tools.classfile.AccessFlags.*;
public class AttributeWriter extends BasicWriter
implements Attribute.Visitor<Void,Void>
{
static AttributeWriter instance(Context context) {
public static AttributeWriter instance(Context context) {
AttributeWriter instance = context.get(AttributeWriter.class);
if (instance == null)
instance = new AttributeWriter(context);
......
......@@ -93,17 +93,25 @@ public class ClassWriter extends BasicWriter {
this.lastModified = lastModified;
}
ClassFile getClassFile() {
protected ClassFile getClassFile() {
return classFile;
}
Method getMethod() {
protected void setClassFile(ClassFile cf) {
classFile = cf;
constant_pool = classFile.constant_pool;
}
protected Method getMethod() {
return method;
}
protected void setMethod(Method m) {
method = m;
}
public void write(ClassFile cf) {
classFile = cf;
constant_pool = classFile.constant_pool;
setClassFile(cf);
if ((options.sysInfo || options.verbose) && !options.compat) {
if (uri != null) {
......@@ -197,13 +205,13 @@ public class ClassWriter extends BasicWriter {
println();
}
void writeFields() {
protected void writeFields() {
for (Field f: classFile.fields) {
writeField(f);
}
}
void writeField(Field f) {
protected void writeField(Field f) {
if (!options.checkAccess(f.access_flags))
return;
......@@ -259,12 +267,12 @@ public class ClassWriter extends BasicWriter {
println();
}
void writeMethods() {
protected void writeMethods() {
for (Method m: classFile.methods)
writeMethod(m);
}
void writeMethod(Method m) {
protected void writeMethod(Method m) {
if (!options.checkAccess(m.access_flags))
return;
......
......@@ -40,7 +40,7 @@ import static com.sun.tools.classfile.ConstantPool.*;
* deletion without notice.</b>
*/
public class ConstantWriter extends BasicWriter {
static ConstantWriter instance(Context context) {
public static ConstantWriter instance(Context context) {
ConstantWriter instance = context.get(ConstantWriter.class);
if (instance == null)
instance = new ConstantWriter(context);
......@@ -54,7 +54,12 @@ public class ConstantWriter extends BasicWriter {
options = Options.instance(context);
}
void writeConstantPool() {
protected void writeConstantPool() {
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
writeConstantPool(constant_pool);
}
protected void writeConstantPool(ConstantPool constant_pool) {
ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
public Integer visitClass(CONSTANT_Class_info info, Void p) {
println("#" + info.name_index + ";\t// " + stringValue(info));
......@@ -114,7 +119,6 @@ public class ConstantWriter extends BasicWriter {
};
println(" Constant pool:");
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
int cpx = 1;
while (cpx < constant_pool.size()) {
try {
......@@ -127,7 +131,7 @@ public class ConstantWriter extends BasicWriter {
}
}
void write(int cpx) {
protected void write(int cpx) {
ClassFile classFile = classWriter.getClassFile();
if (cpx == 0) {
print("#0");
......
......@@ -36,6 +36,7 @@ import java.io.StringWriter;
import java.io.Writer;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -298,21 +299,28 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
};
JavapTask() {
public JavapTask() {
context = new Context();
context.put(Messages.class, this);
options = Options.instance(context);
attributeFactory = new Attribute.Factory();
}
JavapTask(Writer out,
public JavapTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
DiagnosticListener<? super JavaFileObject> diagnosticListener) {
this();
this.log = getPrintWriterForWriter(out);
this.fileManager = fileManager;
this.diagnosticListener = diagnosticListener;
}
public JavapTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
this(out, fileManager, diagnosticListener);
try {
handleOptions(options, false);
......@@ -553,29 +561,10 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
continue;
}
}
Attribute.Factory attributeFactory = new Attribute.Factory();
attributeFactory.setCompat(options.compat);
attributeFactory.setJSR277(options.jsr277);
InputStream in = fo.openInputStream();
SizeInputStream sizeIn = null;
MessageDigest md = null;
if (options.sysInfo || options.verbose) {
md = MessageDigest.getInstance("MD5");
in = new DigestInputStream(in, md);
in = sizeIn = new SizeInputStream(in);
}
ClassFile cf = ClassFile.read(in, attributeFactory);
if (options.sysInfo || options.verbose) {
classWriter.setFile(fo.toUri());
classWriter.setLastModified(fo.getLastModified());
classWriter.setDigest("MD5", md.digest());
classWriter.setFileSize(sizeIn.size());
}
classWriter.write(cf);
write(read(fo));
} catch (ConstantPoolException e) {
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
......@@ -606,6 +595,103 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
return ok;
}
public static class ClassFileInfo {
ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
this.fo = fo;
this.cf = cf;
this.digest = digest;
this.size = size;
}
public final JavaFileObject fo;
public final ClassFile cf;
public final byte[] digest;
public final int size;
}
public ClassFileInfo read(JavaFileObject fo) throws IOException, ConstantPoolException {
InputStream in = fo.openInputStream();
try {
SizeInputStream sizeIn = null;
MessageDigest md = null;
if (options.sysInfo || options.verbose) {
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ignore) {
}
in = new DigestInputStream(in, md);
in = sizeIn = new SizeInputStream(in);
}
ClassFile cf = ClassFile.read(in, attributeFactory);
byte[] digest = (md == null) ? null : md.digest();
int size = (sizeIn == null) ? -1 : sizeIn.size();
return new ClassFileInfo(fo, cf, digest, size);
} finally {
in.close();
}
}
public void write(ClassFileInfo info) {
ClassWriter classWriter = ClassWriter.instance(context);
if (options.sysInfo || options.verbose) {
classWriter.setFile(info.fo.toUri());
classWriter.setLastModified(info.fo.getLastModified());
classWriter.setDigest("MD5", info.digest);
classWriter.setFileSize(info.size);
}
classWriter.write(info.cf);
}
protected void setClassFile(ClassFile classFile) {
ClassWriter classWriter = ClassWriter.instance(context);
classWriter.setClassFile(classFile);
}
protected void setMethod(Method enclosingMethod) {
ClassWriter classWriter = ClassWriter.instance(context);
classWriter.setMethod(enclosingMethod);
}
protected void write(Attribute value) {
AttributeWriter attrWriter = AttributeWriter.instance(context);
ClassWriter classWriter = ClassWriter.instance(context);
ClassFile cf = classWriter.getClassFile();
attrWriter.write(cf, value, cf.constant_pool);
}
protected void write(Attributes attrs) {
AttributeWriter attrWriter = AttributeWriter.instance(context);
ClassWriter classWriter = ClassWriter.instance(context);
ClassFile cf = classWriter.getClassFile();
attrWriter.write(cf, attrs, cf.constant_pool);
}
protected void write(ConstantPool constant_pool) {
ConstantWriter constantWriter = ConstantWriter.instance(context);
constantWriter.writeConstantPool(constant_pool);
}
protected void write(ConstantPool constant_pool, int value) {
ConstantWriter constantWriter = ConstantWriter.instance(context);
constantWriter.write(value);
}
protected void write(ConstantPool.CPInfo value) {
ConstantWriter constantWriter = ConstantWriter.instance(context);
constantWriter.println(value);
}
protected void write(Field value) {
ClassWriter classWriter = ClassWriter.instance(context);
classWriter.writeField(value);
}
protected void write(Method value) {
ClassWriter classWriter = ClassWriter.instance(context);
classWriter.writeMethod(value);
}
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
return JavapFileManager.create(dl, log, options);
}
......@@ -735,7 +821,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
}
}
Context context;
protected Context context;
JavaFileManager fileManager;
PrintWriter log;
DiagnosticListener<? super JavaFileObject> diagnosticListener;
......@@ -744,6 +830,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
//ResourceBundle bundle;
Locale task_locale;
Map<Locale, ResourceBundle> bundles;
protected Attribute.Factory attributeFactory;
private static final String progname = "javap";
......
......@@ -134,6 +134,9 @@ public class SourceWriter extends InstructionDetailWriter {
}
private String readSource(ClassFile cf) {
if (fileManager == null)
return null;
Location location;
if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
location = StandardLocation.SOURCE_PATH;
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
class A<T extends A<T>> {
class C {
public T getT() { return null; }
}
}
class B extends A<B> {
public class D extends A<B>.C {}
}
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6835430
* @summary 6835430: javac does not generate signature attributes for classes extending parameterized inner classes
* @author mcimadamore
*
* @compile A.java
* @compile T6835430.java
*/
class T6835430 {
void test(B.D d) {
B b = d.getT();
}
}
......@@ -27,6 +27,7 @@
* @summary Basic/Raw formatters should use type/symbol printer instead of toString()
* @author mcimadamore
* @compile/fail/ref=T6799605.out -XDrawDiagnostics T6799605.java
* @compile/fail/ref=T6799605.out -XDoldDiags -XDrawDiagnostics T6799605.java
*/
class T6799605<X> {
......
T6799605.java:39:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>, kindname.class, T6799605<X>
T6799605.java:40:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>, kindname.class, T6799605<X>
T6799605.java:41:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>, kindname.class, T6799605<X>
T6799605.java:40:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>, kindname.class, T6799605<X>
T6799605.java:41:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>, kindname.class, T6799605<X>
T6799605.java:42:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>, kindname.class, T6799605<X>
3 errors
......@@ -25,6 +25,7 @@
* @test
* @bug 6476073
* @summary Capture using super wildcard of type variables doesn't work
* @ignore awaiting for 6650759 (see bug report for a detailed evaluation)
* @compile T6476073.java
*/
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6638712
* @author mcimadamore
* @summary Inference with wildcard types causes selection of inapplicable method
* @compile/fail/ref=T6638712a.out -XDrawDiagnostics T6638712a.java
*/
import java.util.*;
class T6638712a {
<T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {}
public void test(List<Comparator<?>> x) {
Comparator<String> c3 = compound(x);
}
}
T6638712a.java:39:41: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Iterable<? extends java.util.Comparator<? super java.lang.String>>, java.util.List<java.util.Comparator<?>>)
1 error
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6638712
* @author mcimadamore
* @summary Inference with wildcard types causes selection of inapplicable method
* @compile/fail/ref=T6638712b.out -XDrawDiagnostics T6638712b.java
*/
class T6638712b<X> {
<I extends T6638712b<T>, T> T m(I test) { return null; }
void test(T6638712b<Integer> x) {
String i = m(x);
}
}
T6638712b.java:37:21: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.bounds: T6638712b<java.lang.Integer>, T6638712b<java.lang.String>)
1 error
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6638712 6707034
* @author mcimadamore
* @summary Inference with wildcard types causes selection of inapplicable method
* @compile/fail/ref=T6638712c.out -XDrawDiagnostics T6638712c.java
*/
import java.util.*;
class T6638712c {
<T> T sort(T[] a, Comparator<? super T> c) { return null; }
void test(Enum[] e, Comparator<Enum<?>> comp) {
sort(e, comp);
}
}
T6638712c.java:39:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, null
1 error
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6638712 6730468
* @author mcimadamore
* @summary Inference with wildcard types causes selection of inapplicable method
* @compile/fail/ref=T6638712d.out -XDrawDiagnostics T6638712d.java
*/
import java.util.*;
public class T6638712d {
<U> U m(U u, List<List<U>> list) { return null; }
void test(List<List<String>> lls) {
m(1, lls);
}
}
T6638712d.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, null
1 error
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6638712 6795689
* @author mcimadamore
* @summary Inference with wildcard types causes selection of inapplicable method
* @compile/fail/ref=T6638712e.out -XDrawDiagnostics T6638712e.java
*/
class T6638712e {
static class Foo<A, B> {
<X> Foo<X, B> m(Foo<? super X, ? extends A> foo) { return null;}
}
static class Test {
Foo<Object, String> test(Foo<Boolean, String> foo1, Foo<Boolean, Boolean> foo2) {
return foo1.m(foo2);
}
}
}
T6638712e.java:40:27: compiler.err.invalid.inferred.types: X, (compiler.misc.inferred.do.not.conform.to.params: T6638712e.Foo<? super java.lang.Object,? extends java.lang.Boolean>, T6638712e.Foo<java.lang.Boolean,java.lang.Boolean>)
1 error
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6835428
* @author mcimadamore
* @summary regression: return-type inference rejects valid code
* @compile T6835428.java
*/
class T6835428<T> {
interface X<T> {}
<T extends Comparable<? super T>> T6835428<X<T>> m() { return null; }
<T extends Comparable<? super T>> void test() {
T6835428<X<T>> t = m();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册