Merge
This commit is contained in:
commit
71fcc09e90
@ -58,7 +58,7 @@ public class AccessFlags {
|
|||||||
public static final int ACC_ENUM = 0x4000; // class, inner, field
|
public static final int ACC_ENUM = 0x4000; // class, inner, field
|
||||||
public static final int ACC_MODULE = 0x8000; // class, inner, field, method
|
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 {
|
AccessFlags(ClassReader cr) throws IOException {
|
||||||
this(cr.readUnsignedShort());
|
this(cr.readUnsignedShort());
|
||||||
@ -87,11 +87,11 @@ public class AccessFlags {
|
|||||||
|
|
||||||
public Set<String> getClassModifiers() {
|
public Set<String> getClassModifiers() {
|
||||||
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
|
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() {
|
public Set<String> getClassFlags() {
|
||||||
return getFlags(classFlags, Type.Class);
|
return getFlags(classFlags, Kind.Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int[] innerClassModifiers = {
|
private static final int[] innerClassModifiers = {
|
||||||
@ -106,11 +106,11 @@ public class AccessFlags {
|
|||||||
|
|
||||||
public Set<String> getInnerClassModifiers() {
|
public Set<String> getInnerClassModifiers() {
|
||||||
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
|
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() {
|
public Set<String> getInnerClassFlags() {
|
||||||
return getFlags(innerClassFlags, Type.InnerClass);
|
return getFlags(innerClassFlags, Kind.InnerClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int[] fieldModifiers = {
|
private static final int[] fieldModifiers = {
|
||||||
@ -124,11 +124,11 @@ public class AccessFlags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public Set<String> getFieldModifiers() {
|
public Set<String> getFieldModifiers() {
|
||||||
return getModifiers(fieldModifiers, Type.Field);
|
return getModifiers(fieldModifiers, Kind.Field);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getFieldFlags() {
|
public Set<String> getFieldFlags() {
|
||||||
return getFlags(fieldFlags, Type.Field);
|
return getFlags(fieldFlags, Kind.Field);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int[] methodModifiers = {
|
private static final int[] methodModifiers = {
|
||||||
@ -143,18 +143,18 @@ public class AccessFlags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public Set<String> getMethodModifiers() {
|
public Set<String> getMethodModifiers() {
|
||||||
return getModifiers(methodModifiers, Type.Method);
|
return getModifiers(methodModifiers, Kind.Method);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getMethodFlags() {
|
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);
|
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>();
|
Set<String> s = new LinkedHashSet<String>();
|
||||||
for (int m: modifierFlags) {
|
for (int m: modifierFlags) {
|
||||||
if ((flags & m) != 0)
|
if ((flags & m) != 0)
|
||||||
@ -163,7 +163,7 @@ public class AccessFlags {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getFlags(int[] expectedFlags, Type t) {
|
private Set<String> getFlags(int[] expectedFlags, Kind t) {
|
||||||
Set<String> s = new LinkedHashSet<String>();
|
Set<String> s = new LinkedHashSet<String>();
|
||||||
int f = flags;
|
int f = flags;
|
||||||
for (int e: expectedFlags) {
|
for (int e: expectedFlags) {
|
||||||
@ -180,7 +180,7 @@ public class AccessFlags {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String flagToModifier(int flag, Type t) {
|
private static String flagToModifier(int flag, Kind t) {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case ACC_PUBLIC:
|
case ACC_PUBLIC:
|
||||||
return "public";
|
return "public";
|
||||||
@ -195,7 +195,7 @@ public class AccessFlags {
|
|||||||
case ACC_SYNCHRONIZED:
|
case ACC_SYNCHRONIZED:
|
||||||
return "synchronized";
|
return "synchronized";
|
||||||
case 0x80:
|
case 0x80:
|
||||||
return (t == Type.Field ? "transient" : null);
|
return (t == Kind.Field ? "transient" : null);
|
||||||
case ACC_VOLATILE:
|
case ACC_VOLATILE:
|
||||||
return "volatile";
|
return "volatile";
|
||||||
case ACC_NATIVE:
|
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) {
|
switch (flag) {
|
||||||
case ACC_PUBLIC:
|
case ACC_PUBLIC:
|
||||||
return "ACC_PUBLIC";
|
return "ACC_PUBLIC";
|
||||||
@ -224,11 +224,11 @@ public class AccessFlags {
|
|||||||
case ACC_FINAL:
|
case ACC_FINAL:
|
||||||
return "ACC_FINAL";
|
return "ACC_FINAL";
|
||||||
case 0x20:
|
case 0x20:
|
||||||
return (t == Type.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
|
return (t == Kind.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
|
||||||
case 0x40:
|
case 0x40:
|
||||||
return (t == Type.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
|
return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
|
||||||
case 0x80:
|
case 0x80:
|
||||||
return (t == Type.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
|
return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
|
||||||
case ACC_NATIVE:
|
case ACC_NATIVE:
|
||||||
return "ACC_NATIVE";
|
return "ACC_NATIVE";
|
||||||
case ACC_INTERFACE:
|
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);
|
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 name_index;
|
||||||
public final int type_index;
|
public final int type_index;
|
||||||
}
|
}
|
||||||
@ -600,6 +605,11 @@ public class ConstantPool {
|
|||||||
return visitor.visitString(this, data);
|
return visitor.visitString(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CONSTANT_String_info[class_index: " + string_index + "]";
|
||||||
|
}
|
||||||
|
|
||||||
public final int string_index;
|
public final int string_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,7 +628,19 @@ public class ConstantPool {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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) {
|
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||||
|
@ -95,6 +95,7 @@ public class Kinds {
|
|||||||
ANNOTATION("kindname.interface"),
|
ANNOTATION("kindname.interface"),
|
||||||
CONSTRUCTOR("kindname.constructor"),
|
CONSTRUCTOR("kindname.constructor"),
|
||||||
INTERFACE("kindname.interface"),
|
INTERFACE("kindname.interface"),
|
||||||
|
ENUM("kindname.enum"),
|
||||||
STATIC("kindname.static"),
|
STATIC("kindname.static"),
|
||||||
TYPEVAR("kindname.type.variable"),
|
TYPEVAR("kindname.type.variable"),
|
||||||
BOUND("kindname.type.variable.bound"),
|
BOUND("kindname.type.variable.bound"),
|
||||||
@ -145,11 +146,15 @@ public class Kinds {
|
|||||||
return KindName.PACKAGE;
|
return KindName.PACKAGE;
|
||||||
|
|
||||||
case ENUM:
|
case ENUM:
|
||||||
|
return KindName.ENUM;
|
||||||
|
|
||||||
case ANNOTATION_TYPE:
|
case ANNOTATION_TYPE:
|
||||||
case INTERFACE:
|
|
||||||
case CLASS:
|
case CLASS:
|
||||||
return KindName.CLASS;
|
return KindName.CLASS;
|
||||||
|
|
||||||
|
case INTERFACE:
|
||||||
|
return KindName.INTERFACE;
|
||||||
|
|
||||||
case TYPE_PARAMETER:
|
case TYPE_PARAMETER:
|
||||||
return KindName.TYPEVAR;
|
return KindName.TYPEVAR;
|
||||||
|
|
||||||
@ -160,8 +165,10 @@ public class Kinds {
|
|||||||
case EXCEPTION_PARAMETER:
|
case EXCEPTION_PARAMETER:
|
||||||
return KindName.VAR;
|
return KindName.VAR;
|
||||||
|
|
||||||
case METHOD:
|
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
|
return KindName.CONSTRUCTOR;
|
||||||
|
|
||||||
|
case METHOD:
|
||||||
case STATIC_INIT:
|
case STATIC_INIT:
|
||||||
case INSTANCE_INIT:
|
case INSTANCE_INIT:
|
||||||
return KindName.METHOD;
|
return KindName.METHOD;
|
||||||
|
@ -1066,6 +1066,21 @@ public class Type implements PrimitiveType {
|
|||||||
return qtype.isErroneous();
|
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) {
|
public Type map(Mapping f) {
|
||||||
return f.apply(qtype);
|
return f.apply(qtype);
|
||||||
}
|
}
|
||||||
|
@ -343,6 +343,14 @@ public class Types {
|
|||||||
if (s.tag >= firstPartialTag)
|
if (s.tag >= firstPartialTag)
|
||||||
return isSuperType(s, t);
|
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);
|
Type lower = lowerBound(s);
|
||||||
if (s != lower)
|
if (s != lower)
|
||||||
return isSubtype(capture ? capture(t) : t, lower, false);
|
return isSubtype(capture ? capture(t) : t, lower, false);
|
||||||
@ -2870,6 +2878,14 @@ public class Types {
|
|||||||
/**
|
/**
|
||||||
* Capture conversion as specified by JLS 3rd Ed.
|
* 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) {
|
public Type capture(Type t) {
|
||||||
if (t.tag != CLASS)
|
if (t.tag != CLASS)
|
||||||
return t;
|
return t;
|
||||||
|
@ -303,7 +303,7 @@ public class Attr extends JCTree.Visitor {
|
|||||||
|
|
||||||
public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
|
public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
|
||||||
breakTree = tree;
|
breakTree = tree;
|
||||||
JavaFileObject prev = log.useSource(null);
|
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
attribExpr(expr, env);
|
attribExpr(expr, env);
|
||||||
} catch (BreakAttr b) {
|
} catch (BreakAttr b) {
|
||||||
@ -317,7 +317,7 @@ public class Attr extends JCTree.Visitor {
|
|||||||
|
|
||||||
public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
|
public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
|
||||||
breakTree = tree;
|
breakTree = tree;
|
||||||
JavaFileObject prev = log.useSource(null);
|
JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
attribStat(stmt, env);
|
attribStat(stmt, env);
|
||||||
} catch (BreakAttr b) {
|
} catch (BreakAttr b) {
|
||||||
|
@ -391,6 +391,10 @@ public class Check {
|
|||||||
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
|
diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
|
||||||
t, pt);
|
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.util.List;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.code.Type.*;
|
import com.sun.tools.javac.code.Type.*;
|
||||||
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic;
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
|
||||||
import static com.sun.tools.javac.code.TypeTags.*;
|
import static com.sun.tools.javac.code.TypeTags.*;
|
||||||
@ -49,6 +50,7 @@ public class Infer {
|
|||||||
|
|
||||||
Symtab syms;
|
Symtab syms;
|
||||||
Types types;
|
Types types;
|
||||||
|
Resolve rs;
|
||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
|
|
||||||
public static Infer instance(Context context) {
|
public static Infer instance(Context context) {
|
||||||
@ -62,48 +64,60 @@ public class Infer {
|
|||||||
context.put(inferKey, this);
|
context.put(inferKey, this);
|
||||||
syms = Symtab.instance(context);
|
syms = Symtab.instance(context);
|
||||||
types = Types.instance(context);
|
types = Types.instance(context);
|
||||||
|
rs = Resolve.instance(context);
|
||||||
diags = JCDiagnostic.Factory.instance(context);
|
diags = JCDiagnostic.Factory.instance(context);
|
||||||
ambiguousNoInstanceException =
|
ambiguousNoInstanceException =
|
||||||
new NoInstanceException(true, diags);
|
new NoInstanceException(true, diags);
|
||||||
unambiguousNoInstanceException =
|
unambiguousNoInstanceException =
|
||||||
new NoInstanceException(false, diags);
|
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;
|
private static final long serialVersionUID = 0;
|
||||||
|
|
||||||
boolean isAmbiguous; // exist several incomparable best instances?
|
|
||||||
|
|
||||||
JCDiagnostic diagnostic;
|
JCDiagnostic diagnostic;
|
||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
|
|
||||||
NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
|
InferenceException(JCDiagnostic.Factory diags) {
|
||||||
this.diagnostic = null;
|
this.diagnostic = null;
|
||||||
this.isAmbiguous = isAmbiguous;
|
|
||||||
this.diags = diags;
|
this.diags = diags;
|
||||||
}
|
}
|
||||||
NoInstanceException setMessage(String key) {
|
|
||||||
this.diagnostic = diags.fragment(key);
|
InferenceException setMessage(String key, Object... args) {
|
||||||
return this;
|
this.diagnostic = diags.fragment(key, args);
|
||||||
}
|
|
||||||
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);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCDiagnostic getDiagnostic() {
|
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 ambiguousNoInstanceException;
|
||||||
private final NoInstanceException unambiguousNoInstanceException;
|
private final NoInstanceException unambiguousNoInstanceException;
|
||||||
|
private final InvalidInstanceException invalidInstanceException;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Auxiliary type values and classes
|
* Auxiliary type values and classes
|
||||||
@ -158,8 +172,7 @@ public class Infer {
|
|||||||
that.inst = types.glb(that.hibounds);
|
that.inst = types.glb(that.hibounds);
|
||||||
}
|
}
|
||||||
if (that.inst == null ||
|
if (that.inst == null ||
|
||||||
that.inst.isErroneous() ||
|
that.inst.isErroneous())
|
||||||
!types.isSubtypeUnchecked(that.inst, that.hibounds, warn))
|
|
||||||
throw ambiguousNoInstanceException
|
throw ambiguousNoInstanceException
|
||||||
.setMessage("no.unique.maximal.instance.exists",
|
.setMessage("no.unique.maximal.instance.exists",
|
||||||
that.qtype, that.hibounds);
|
that.qtype, that.hibounds);
|
||||||
@ -234,7 +247,7 @@ public class Infer {
|
|||||||
*/
|
*/
|
||||||
public Type instantiateExpr(ForAll that,
|
public Type instantiateExpr(ForAll that,
|
||||||
Type to,
|
Type to,
|
||||||
Warner warn) throws NoInstanceException {
|
Warner warn) throws InferenceException {
|
||||||
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
|
List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
|
||||||
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
|
for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
|
||||||
UndetVar v = (UndetVar) l.head;
|
UndetVar v = (UndetVar) l.head;
|
||||||
@ -260,8 +273,7 @@ public class Infer {
|
|||||||
List<Type> targs = Type.map(undetvars, getInstFun);
|
List<Type> targs = Type.map(undetvars, getInstFun);
|
||||||
targs = types.subst(targs, that.tvars, targs);
|
targs = types.subst(targs, that.tvars, targs);
|
||||||
checkWithinBounds(that.tvars, targs, warn);
|
checkWithinBounds(that.tvars, targs, warn);
|
||||||
|
return that.inst(targs, types);
|
||||||
return getInstFun.apply(qtype1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Instantiate method type `mt' by finding instantiations of
|
/** Instantiate method type `mt' by finding instantiations of
|
||||||
@ -269,36 +281,42 @@ public class Infer {
|
|||||||
*/
|
*/
|
||||||
public Type instantiateMethod(List<Type> tvars,
|
public Type instantiateMethod(List<Type> tvars,
|
||||||
MethodType mt,
|
MethodType mt,
|
||||||
List<Type> argtypes,
|
final List<Type> argtypes,
|
||||||
boolean allowBoxing,
|
final boolean allowBoxing,
|
||||||
boolean useVarargs,
|
final boolean useVarargs,
|
||||||
Warner warn) throws NoInstanceException {
|
final Warner warn) throws InferenceException {
|
||||||
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
//-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
|
||||||
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
|
||||||
List<Type> formals = mt.argtypes;
|
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
|
// instantiate all polymorphic argument types and
|
||||||
// set up lower bounds constraints for undetvars
|
// set up lower bounds constraints for undetvars
|
||||||
Type varargsFormal = useVarargs ? formals.last() : null;
|
Type varargsFormal = useVarargs ? formals.last() : null;
|
||||||
while (argtypes.nonEmpty() && formals.head != varargsFormal) {
|
while (actuals.nonEmpty() && formals.head != varargsFormal) {
|
||||||
Type ft = formals.head;
|
Type formal = formals.head;
|
||||||
Type at = argtypes.head.baseType();
|
Type actual = actuals.head.baseType();
|
||||||
if (at.tag == FORALL)
|
Type actualNoCapture = actualsNoCapture.head.baseType();
|
||||||
at = instantiateArg((ForAll) at, ft, tvars, warn);
|
if (actual.tag == FORALL)
|
||||||
Type sft = types.subst(ft, tvars, undetvars);
|
actual = instantiateArg((ForAll)actual, formal, tvars, warn);
|
||||||
|
Type undetFormal = types.subst(formal, tvars, undetvars);
|
||||||
boolean works = allowBoxing
|
boolean works = allowBoxing
|
||||||
? types.isConvertible(at, sft, warn)
|
? types.isConvertible(actual, undetFormal, warn)
|
||||||
: types.isSubtypeUnchecked(at, sft, warn);
|
: types.isSubtypeUnchecked(actual, undetFormal, warn);
|
||||||
if (!works) {
|
if (!works) {
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("no.conforming.assignment.exists",
|
.setMessage("no.conforming.assignment.exists",
|
||||||
tvars, at, ft);
|
tvars, actualNoCapture, formal);
|
||||||
}
|
}
|
||||||
formals = formals.tail;
|
formals = formals.tail;
|
||||||
argtypes = argtypes.tail;
|
actuals = actuals.tail;
|
||||||
|
actualsNoCapture = actualsNoCapture.tail;
|
||||||
}
|
}
|
||||||
if (formals.head != varargsFormal || // not enough args
|
if (formals.head != varargsFormal || // not enough args
|
||||||
!useVarargs && argtypes.nonEmpty()) { // too many args
|
!useVarargs && actuals.nonEmpty()) { // too many args
|
||||||
// argument lists differ in length
|
// argument lists differ in length
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("arg.length.mismatch");
|
.setMessage("arg.length.mismatch");
|
||||||
@ -306,20 +324,21 @@ public class Infer {
|
|||||||
|
|
||||||
// for varargs arguments as well
|
// for varargs arguments as well
|
||||||
if (useVarargs) {
|
if (useVarargs) {
|
||||||
Type elt = types.elemtype(varargsFormal);
|
Type elemType = types.elemtype(varargsFormal);
|
||||||
Type sft = types.subst(elt, tvars, undetvars);
|
Type elemUndet = types.subst(elemType, tvars, undetvars);
|
||||||
while (argtypes.nonEmpty()) {
|
while (actuals.nonEmpty()) {
|
||||||
Type ft = sft;
|
Type actual = actuals.head.baseType();
|
||||||
Type at = argtypes.head.baseType();
|
Type actualNoCapture = actualsNoCapture.head.baseType();
|
||||||
if (at.tag == FORALL)
|
if (actual.tag == FORALL)
|
||||||
at = instantiateArg((ForAll) at, ft, tvars, warn);
|
actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
|
||||||
boolean works = types.isConvertible(at, sft, warn);
|
boolean works = types.isConvertible(actual, elemUndet, warn);
|
||||||
if (!works) {
|
if (!works) {
|
||||||
throw unambiguousNoInstanceException
|
throw unambiguousNoInstanceException
|
||||||
.setMessage("no.conforming.assignment.exists",
|
.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);
|
checkWithinBounds(tvars, undettypes.toList(), warn);
|
||||||
|
|
||||||
|
mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
|
||||||
|
|
||||||
if (!restvars.isEmpty()) {
|
if (!restvars.isEmpty()) {
|
||||||
// if there are uninstantiated variables,
|
// if there are uninstantiated variables,
|
||||||
// quantify result type with them
|
// quantify result type with them
|
||||||
mt = new MethodType(mt.argtypes,
|
final List<Type> inferredTypes = insttypes.toList();
|
||||||
new ForAll(restvars.toList(), mt.restype),
|
final List<Type> all_tvars = tvars; //this is the wrong tvars
|
||||||
mt.thrown, syms.methodClass);
|
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
|
//where
|
||||||
|
|
||||||
@ -371,7 +412,7 @@ public class Infer {
|
|||||||
private Type instantiateArg(ForAll that,
|
private Type instantiateArg(ForAll that,
|
||||||
Type to,
|
Type to,
|
||||||
List<Type> tvars,
|
List<Type> tvars,
|
||||||
Warner warn) throws NoInstanceException {
|
Warner warn) throws InferenceException {
|
||||||
List<Type> targs;
|
List<Type> targs;
|
||||||
try {
|
try {
|
||||||
return instantiateExpr(that, to, warn);
|
return instantiateExpr(that, to, warn);
|
||||||
@ -388,16 +429,16 @@ public class Infer {
|
|||||||
private void checkWithinBounds(List<Type> tvars,
|
private void checkWithinBounds(List<Type> tvars,
|
||||||
List<Type> arguments,
|
List<Type> arguments,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws NoInstanceException {
|
throws InvalidInstanceException {
|
||||||
for (List<Type> tvs = tvars, args = arguments;
|
for (List<Type> tvs = tvars, args = arguments;
|
||||||
tvs.nonEmpty();
|
tvs.nonEmpty();
|
||||||
tvs = tvs.tail, args = args.tail) {
|
tvs = tvs.tail, args = args.tail) {
|
||||||
if (args.head instanceof UndetVar) continue;
|
if (args.head instanceof UndetVar) continue;
|
||||||
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
|
List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
|
||||||
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
|
if (!types.isSubtypeUnchecked(args.head, bounds, warn))
|
||||||
throw unambiguousNoInstanceException
|
throw invalidInstanceException
|
||||||
.setMessage("inferred.do.not.conform.to.bounds",
|
.setMessage("inferred.do.not.conform.to.bounds",
|
||||||
arguments, tvars);
|
args.head, bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,15 +82,15 @@ public class Resolve {
|
|||||||
syms = Symtab.instance(context);
|
syms = Symtab.instance(context);
|
||||||
|
|
||||||
varNotFound = new
|
varNotFound = new
|
||||||
ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found");
|
SymbolNotFoundError(ABSENT_VAR);
|
||||||
wrongMethod = new
|
wrongMethod = new
|
||||||
ResolveError(WRONG_MTH, syms.errSymbol, "method not found");
|
InapplicableSymbolError(syms.errSymbol);
|
||||||
wrongMethods = new
|
wrongMethods = new
|
||||||
ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods");
|
InapplicableSymbolsError(syms.errSymbol);
|
||||||
methodNotFound = new
|
methodNotFound = new
|
||||||
ResolveError(ABSENT_MTH, syms.errSymbol, "method not found");
|
SymbolNotFoundError(ABSENT_MTH);
|
||||||
typeNotFound = new
|
typeNotFound = new
|
||||||
ResolveError(ABSENT_TYP, syms.errSymbol, "type not found");
|
SymbolNotFoundError(ABSENT_TYP);
|
||||||
|
|
||||||
names = Names.instance(context);
|
names = Names.instance(context);
|
||||||
log = Log.instance(context);
|
log = Log.instance(context);
|
||||||
@ -110,11 +110,11 @@ public class Resolve {
|
|||||||
|
|
||||||
/** error symbols, which are returned when resolution fails
|
/** error symbols, which are returned when resolution fails
|
||||||
*/
|
*/
|
||||||
final ResolveError varNotFound;
|
final SymbolNotFoundError varNotFound;
|
||||||
final ResolveError wrongMethod;
|
final InapplicableSymbolError wrongMethod;
|
||||||
final ResolveError wrongMethods;
|
final InapplicableSymbolsError wrongMethods;
|
||||||
final ResolveError methodNotFound;
|
final SymbolNotFoundError methodNotFound;
|
||||||
final ResolveError typeNotFound;
|
final SymbolNotFoundError typeNotFound;
|
||||||
|
|
||||||
/* ************************************************************************
|
/* ************************************************************************
|
||||||
* Identifier resolution
|
* Identifier resolution
|
||||||
@ -299,7 +299,7 @@ public class Resolve {
|
|||||||
boolean allowBoxing,
|
boolean allowBoxing,
|
||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws Infer.NoInstanceException {
|
throws Infer.InferenceException {
|
||||||
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
||||||
Type mt = types.memberType(site, m);
|
Type mt = types.memberType(site, m);
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ public class Resolve {
|
|||||||
try {
|
try {
|
||||||
return rawInstantiate(env, site, m, argtypes, typeargtypes,
|
return rawInstantiate(env, site, m, argtypes, typeargtypes,
|
||||||
allowBoxing, useVarargs, warn);
|
allowBoxing, useVarargs, warn);
|
||||||
} catch (Infer.NoInstanceException ex) {
|
} catch (Infer.InferenceException ex) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -584,7 +584,7 @@ public class Resolve {
|
|||||||
default: return bestSoFar;
|
default: return bestSoFar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Infer.NoInstanceException ex) {
|
} catch (Infer.InferenceException ex) {
|
||||||
switch (bestSoFar.kind) {
|
switch (bestSoFar.kind) {
|
||||||
case ABSENT_MTH:
|
case ABSENT_MTH:
|
||||||
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
|
return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
|
||||||
@ -710,13 +710,13 @@ public class Resolve {
|
|||||||
return new AmbiguityError(m1, m2);
|
return new AmbiguityError(m1, m2);
|
||||||
case AMBIGUOUS:
|
case AMBIGUOUS:
|
||||||
AmbiguityError e = (AmbiguityError)m2;
|
AmbiguityError e = (AmbiguityError)m2;
|
||||||
Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs);
|
Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
|
||||||
Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
|
Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
|
||||||
if (err1 == err2) return err1;
|
if (err1 == err2) return err1;
|
||||||
if (err1 == e.sym1 && err2 == e.sym2) return m2;
|
if (err1 == e.sym && err2 == e.sym2) return m2;
|
||||||
if (err1 instanceof AmbiguityError &&
|
if (err1 instanceof AmbiguityError &&
|
||||||
err2 instanceof AmbiguityError &&
|
err2 instanceof AmbiguityError &&
|
||||||
((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1)
|
((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
|
||||||
return new AmbiguityError(m1, m2);
|
return new AmbiguityError(m1, m2);
|
||||||
else
|
else
|
||||||
return new AmbiguityError(err1, err2);
|
return new AmbiguityError(err1, err2);
|
||||||
@ -1192,18 +1192,12 @@ public class Resolve {
|
|||||||
List<Type> argtypes,
|
List<Type> argtypes,
|
||||||
List<Type> typeargtypes) {
|
List<Type> typeargtypes) {
|
||||||
if (sym.kind >= AMBIGUOUS) {
|
if (sym.kind >= AMBIGUOUS) {
|
||||||
// printscopes(site.tsym.members());//DEBUG
|
ResolveError errSym = (ResolveError)sym;
|
||||||
if (!site.isErroneous() &&
|
if (!site.isErroneous() &&
|
||||||
!Type.isErroneous(argtypes) &&
|
!Type.isErroneous(argtypes) &&
|
||||||
(typeargtypes==null || !Type.isErroneous(typeargtypes)))
|
(typeargtypes==null || !Type.isErroneous(typeargtypes)))
|
||||||
((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes);
|
logResolveError(errSym, pos, site, name, argtypes, typeargtypes);
|
||||||
do {
|
sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
|
||||||
sym = ((ResolveError)sym).sym;
|
|
||||||
} while (sym.kind >= AMBIGUOUS);
|
|
||||||
if (sym == syms.errSymbol // preserve the symbol name through errors
|
|
||||||
|| ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned
|
|
||||||
&& (sym.kind & TYP) != 0))
|
|
||||||
sym = types.createErrorType(name, qualified ? site.tsym : syms.noSymbol, sym.type).tsym;
|
|
||||||
}
|
}
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
@ -1583,7 +1577,19 @@ public class Resolve {
|
|||||||
|
|
||||||
public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
|
public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
|
||||||
AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
|
AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
|
||||||
error.report(log, tree.pos(), type.getEnclosingType(), null, null, null);
|
logResolveError(error, tree.pos(), type.getEnclosingType(), null, null, null);
|
||||||
|
}
|
||||||
|
//where
|
||||||
|
private void logResolveError(ResolveError error,
|
||||||
|
DiagnosticPosition pos,
|
||||||
|
Type site,
|
||||||
|
Name name,
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
|
||||||
|
pos, site, name, argtypes, typeargtypes);
|
||||||
|
if (d != null)
|
||||||
|
log.report(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
|
private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
|
||||||
@ -1592,152 +1598,71 @@ public class Resolve {
|
|||||||
return argtypes.isEmpty() ? noArgs : argtypes;
|
return argtypes.isEmpty() ? noArgs : argtypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Root class for resolve errors.
|
/**
|
||||||
* Instances of this class indicate "Symbol not found".
|
* Root class for resolution errors. Subclass of ResolveError
|
||||||
* Instances of subclass indicate other errors.
|
* represent a different kinds of resolution error - as such they must
|
||||||
|
* specify how they map into concrete compiler diagnostics.
|
||||||
*/
|
*/
|
||||||
private class ResolveError extends Symbol {
|
private abstract class ResolveError extends Symbol {
|
||||||
|
|
||||||
ResolveError(int kind, Symbol sym, String debugName) {
|
/** The name of the kind of error, for debugging only. */
|
||||||
super(kind, 0, null, null, null);
|
|
||||||
this.debugName = debugName;
|
|
||||||
this.sym = sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The name of the kind of error, for debugging only.
|
|
||||||
*/
|
|
||||||
final String debugName;
|
final String debugName;
|
||||||
|
|
||||||
/** The symbol that was determined by resolution, or errSymbol if none
|
ResolveError(int kind, String debugName) {
|
||||||
* was found.
|
super(kind, 0, null, null, null);
|
||||||
*/
|
this.debugName = debugName;
|
||||||
final Symbol sym;
|
}
|
||||||
|
|
||||||
/** The symbol that was a close mismatch, or null if none was found.
|
|
||||||
* wrongSym is currently set if a simgle method with the correct name, but
|
|
||||||
* the wrong parameters was found.
|
|
||||||
*/
|
|
||||||
Symbol wrongSym;
|
|
||||||
|
|
||||||
/** An auxiliary explanation set in case of instantiation errors.
|
|
||||||
*/
|
|
||||||
JCDiagnostic explanation;
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Print the (debug only) name of the kind of error.
|
@Override
|
||||||
*/
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation;
|
return debugName;
|
||||||
}
|
|
||||||
|
|
||||||
/** Update wrongSym and explanation and return this.
|
|
||||||
*/
|
|
||||||
ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) {
|
|
||||||
this.wrongSym = sym;
|
|
||||||
this.explanation = explanation;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update wrongSym and return this.
|
|
||||||
*/
|
|
||||||
ResolveError setWrongSym(Symbol sym) {
|
|
||||||
this.wrongSym = sym;
|
|
||||||
this.explanation = null;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
switch (kind) {
|
return false;
|
||||||
case HIDDEN:
|
|
||||||
case ABSENT_VAR:
|
|
||||||
case ABSENT_MTH:
|
|
||||||
case ABSENT_TYP:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Report error.
|
/**
|
||||||
* @param log The error log to be used for error reporting.
|
* Create an external representation for this erroneous symbol to be
|
||||||
* @param pos The position to be used for error reporting.
|
* used during attribution - by default this returns the symbol of a
|
||||||
* @param site The original type from where the selection took place.
|
* brand new error type which stores the original type found
|
||||||
* @param name The name of the symbol to be resolved.
|
* during resolution.
|
||||||
* @param argtypes The invocation's value arguments,
|
*
|
||||||
* if we looked for a method.
|
* @param name the name used during resolution
|
||||||
* @param typeargtypes The invocation's type arguments,
|
* @param location the location from which the symbol is accessed
|
||||||
* if we looked for a method.
|
|
||||||
*/
|
*/
|
||||||
void report(Log log, DiagnosticPosition pos, Type site, Name name,
|
protected Symbol access(Name name, TypeSymbol location) {
|
||||||
List<Type> argtypes, List<Type> typeargtypes) {
|
return types.createErrorType(name, location, syms.errSymbol.type).tsym;
|
||||||
if (argtypes == null)
|
|
||||||
argtypes = List.nil();
|
|
||||||
if (typeargtypes == null)
|
|
||||||
typeargtypes = List.nil();
|
|
||||||
if (name != names.error) {
|
|
||||||
KindName kindname = absentKind(kind);
|
|
||||||
Name idname = name;
|
|
||||||
if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
|
|
||||||
if (isOperator(name)) {
|
|
||||||
log.error(pos, "operator.cant.be.applied",
|
|
||||||
name, argtypes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (name == names.init) {
|
|
||||||
kindname = KindName.CONSTRUCTOR;
|
|
||||||
idname = site.tsym.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (kind == WRONG_MTH) {
|
|
||||||
Symbol ws = wrongSym.asMemberOf(site, types);
|
|
||||||
log.error(pos,
|
|
||||||
"cant.apply.symbol" + (explanation != null ? ".1" : ""),
|
|
||||||
kindname,
|
|
||||||
ws.name == names.init ? ws.owner.name : ws.name,
|
|
||||||
methodArguments(ws.type.getParameterTypes()),
|
|
||||||
methodArguments(argtypes),
|
|
||||||
kindName(ws.owner),
|
|
||||||
ws.owner.type,
|
|
||||||
explanation);
|
|
||||||
} else if (!site.tsym.name.isEmpty()) {
|
|
||||||
if (site.tsym.kind == PCK && !site.tsym.exists())
|
|
||||||
log.error(pos, "doesnt.exist", site.tsym);
|
|
||||||
else {
|
|
||||||
String errKey = getErrorKey("cant.resolve.location",
|
|
||||||
argtypes, typeargtypes,
|
|
||||||
kindname);
|
|
||||||
log.error(pos, errKey, kindname, idname, //symbol kindname, name
|
|
||||||
typeargtypes, argtypes, //type parameters and arguments (if any)
|
|
||||||
typeKindName(site), site); //location kindname, type
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String errKey = getErrorKey("cant.resolve",
|
|
||||||
argtypes, typeargtypes,
|
|
||||||
kindname);
|
|
||||||
log.error(pos, errKey, kindname, idname, //symbol kindname, name
|
|
||||||
typeargtypes, argtypes); //type parameters and arguments (if any)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//where
|
|
||||||
String getErrorKey(String key, List<Type> argtypes, List<Type> typeargtypes, KindName kindname) {
|
|
||||||
String suffix = "";
|
|
||||||
switch (kindname) {
|
|
||||||
case METHOD:
|
|
||||||
case CONSTRUCTOR: {
|
|
||||||
suffix += ".args";
|
|
||||||
suffix += typeargtypes.nonEmpty() ? ".params" : "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return key + suffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A name designates an operator if it consists
|
/**
|
||||||
* of a non-empty sequence of operator symbols +-~!/*%&|^<>=
|
* Create a diagnostic representing this resolution error.
|
||||||
|
*
|
||||||
|
* @param dkind The kind of the diagnostic to be created (e.g error).
|
||||||
|
* @param pos The position to be used for error reporting.
|
||||||
|
* @param site The original type from where the selection took place.
|
||||||
|
* @param name The name of the symbol to be resolved.
|
||||||
|
* @param argtypes The invocation's value arguments,
|
||||||
|
* if we looked for a method.
|
||||||
|
* @param typeargtypes The invocation's type arguments,
|
||||||
|
* if we looked for a method.
|
||||||
|
*/
|
||||||
|
abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
|
DiagnosticPosition pos,
|
||||||
|
Type site,
|
||||||
|
Name name,
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A name designates an operator if it consists
|
||||||
|
* of a non-empty sequence of operator symbols +-~!/*%&|^<>=
|
||||||
*/
|
*/
|
||||||
boolean isOperator(Name name) {
|
boolean isOperator(Name name) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -1747,9 +1672,206 @@ public class Resolve {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve error class indicating that a symbol is not accessible.
|
/**
|
||||||
|
* This class is the root class of all resolution errors caused by
|
||||||
|
* an invalid symbol being found during resolution.
|
||||||
*/
|
*/
|
||||||
class AccessError extends ResolveError {
|
abstract class InvalidSymbolError extends ResolveError {
|
||||||
|
|
||||||
|
/** The invalid symbol found during resolution */
|
||||||
|
Symbol sym;
|
||||||
|
|
||||||
|
InvalidSymbolError(int kind, Symbol sym, String debugName) {
|
||||||
|
super(kind, debugName);
|
||||||
|
this.sym = sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " wrongSym=" + sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Symbol access(Name name, TypeSymbol location) {
|
||||||
|
if (sym.kind >= AMBIGUOUS)
|
||||||
|
return ((ResolveError)sym).access(name, location);
|
||||||
|
else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
|
||||||
|
return types.createErrorType(name, location, sym.type).tsym;
|
||||||
|
else
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InvalidSymbolError error class indicating that a symbol matching a
|
||||||
|
* given name does not exists in a given site.
|
||||||
|
*/
|
||||||
|
class SymbolNotFoundError extends ResolveError {
|
||||||
|
|
||||||
|
SymbolNotFoundError(int kind) {
|
||||||
|
super(kind, "symbol not found error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
|
DiagnosticPosition pos,
|
||||||
|
Type site,
|
||||||
|
Name name,
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
argtypes = argtypes == null ? List.<Type>nil() : argtypes;
|
||||||
|
typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
|
||||||
|
if (name == names.error)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (isOperator(name)) {
|
||||||
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
|
"operator.cant.be.applied", name, argtypes);
|
||||||
|
}
|
||||||
|
boolean hasLocation = false;
|
||||||
|
if (!site.tsym.name.isEmpty()) {
|
||||||
|
if (site.tsym.kind == PCK && !site.tsym.exists()) {
|
||||||
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
|
"doesnt.exist", site.tsym);
|
||||||
|
}
|
||||||
|
hasLocation = true;
|
||||||
|
}
|
||||||
|
boolean isConstructor = kind == ABSENT_MTH &&
|
||||||
|
name == names.table.names.init;
|
||||||
|
KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
|
||||||
|
Name idname = isConstructor ? site.tsym.name : name;
|
||||||
|
String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
|
||||||
|
if (hasLocation) {
|
||||||
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
|
errKey, kindname, idname, //symbol kindname, name
|
||||||
|
typeargtypes, argtypes, //type parameters and arguments (if any)
|
||||||
|
typeKindName(site), site); //location kindname, type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
|
errKey, kindname, idname, //symbol kindname, name
|
||||||
|
typeargtypes, argtypes); //type parameters and arguments (if any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//where
|
||||||
|
private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
|
||||||
|
String key = "cant.resolve";
|
||||||
|
String suffix = hasLocation ? ".location" : "";
|
||||||
|
switch (kindname) {
|
||||||
|
case METHOD:
|
||||||
|
case CONSTRUCTOR: {
|
||||||
|
suffix += ".args";
|
||||||
|
suffix += hasTypeArgs ? ".params" : "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return key + suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* InvalidSymbolError error class indicating that a given symbol
|
||||||
|
* (either a method, a constructor or an operand) is not applicable
|
||||||
|
* given an actual arguments/type argument list.
|
||||||
|
*/
|
||||||
|
class InapplicableSymbolError extends InvalidSymbolError {
|
||||||
|
|
||||||
|
/** An auxiliary explanation set in case of instantiation errors. */
|
||||||
|
JCDiagnostic explanation;
|
||||||
|
|
||||||
|
InapplicableSymbolError(Symbol sym) {
|
||||||
|
super(WRONG_MTH, sym, "inapplicable symbol error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update sym and explanation and return this.
|
||||||
|
*/
|
||||||
|
InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) {
|
||||||
|
this.sym = sym;
|
||||||
|
this.explanation = explanation;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update sym and return this.
|
||||||
|
*/
|
||||||
|
InapplicableSymbolError setWrongSym(Symbol sym) {
|
||||||
|
this.sym = sym;
|
||||||
|
this.explanation = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " explanation=" + explanation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
|
DiagnosticPosition pos,
|
||||||
|
Type site,
|
||||||
|
Name name,
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
if (name == names.error)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (isOperator(name)) {
|
||||||
|
return diags.create(dkind, false, log.currentSource(),
|
||||||
|
pos, "operator.cant.be.applied", name, argtypes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Symbol ws = sym.asMemberOf(site, types);
|
||||||
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
|
"cant.apply.symbol" + (explanation != null ? ".1" : ""),
|
||||||
|
kindName(ws),
|
||||||
|
ws.name == names.init ? ws.owner.name : ws.name,
|
||||||
|
methodArguments(ws.type.getParameterTypes()),
|
||||||
|
methodArguments(argtypes),
|
||||||
|
kindName(ws.owner),
|
||||||
|
ws.owner.type,
|
||||||
|
explanation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Symbol access(Name name, TypeSymbol location) {
|
||||||
|
return types.createErrorType(name, location, syms.errSymbol.type).tsym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResolveError error class indicating that a set of symbols
|
||||||
|
* (either methods, constructors or operands) is not applicable
|
||||||
|
* given an actual arguments/type argument list.
|
||||||
|
*/
|
||||||
|
class InapplicableSymbolsError extends ResolveError {
|
||||||
|
InapplicableSymbolsError(Symbol sym) {
|
||||||
|
super(WRONG_MTHS, "inapplicable symbols");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
|
DiagnosticPosition pos,
|
||||||
|
Type site,
|
||||||
|
Name name,
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
|
||||||
|
site, name, argtypes, typeargtypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An InvalidSymbolError error class indicating that a symbol is not
|
||||||
|
* accessible from a given site
|
||||||
|
*/
|
||||||
|
class AccessError extends InvalidSymbolError {
|
||||||
|
|
||||||
|
private Env<AttrContext> env;
|
||||||
|
private Type site;
|
||||||
|
|
||||||
AccessError(Symbol sym) {
|
AccessError(Symbol sym) {
|
||||||
this(null, null, sym);
|
this(null, null, sym);
|
||||||
@ -1763,111 +1885,107 @@ public class Resolve {
|
|||||||
log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
|
log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Env<AttrContext> env;
|
@Override
|
||||||
private Type site;
|
public boolean exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Report error.
|
@Override
|
||||||
* @param log The error log to be used for error reporting.
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
* @param pos The position to be used for error reporting.
|
DiagnosticPosition pos,
|
||||||
* @param site The original type from where the selection took place.
|
Type site,
|
||||||
* @param name The name of the symbol to be resolved.
|
Name name,
|
||||||
* @param argtypes The invocation's value arguments,
|
List<Type> argtypes,
|
||||||
* if we looked for a method.
|
List<Type> typeargtypes) {
|
||||||
* @param typeargtypes The invocation's type arguments,
|
if (sym.owner.type.tag == ERROR)
|
||||||
* if we looked for a method.
|
return null;
|
||||||
*/
|
|
||||||
void report(Log log, DiagnosticPosition pos, Type site, Name name,
|
if (sym.name == names.init && sym.owner != site.tsym) {
|
||||||
List<Type> argtypes, List<Type> typeargtypes) {
|
return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
|
||||||
if (sym.owner.type.tag != ERROR) {
|
pos, site, name, argtypes, typeargtypes);
|
||||||
if (sym.name == names.init && sym.owner != site.tsym)
|
}
|
||||||
new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report(
|
else if ((sym.flags() & PUBLIC) != 0
|
||||||
log, pos, site, name, argtypes, typeargtypes);
|
|| (env != null && this.site != null
|
||||||
if ((sym.flags() & PUBLIC) != 0
|
&& !isAccessible(env, this.site))) {
|
||||||
|| (env != null && this.site != null
|
return diags.create(dkind, false, log.currentSource(),
|
||||||
&& !isAccessible(env, this.site)))
|
pos, "not.def.access.class.intf.cant.access",
|
||||||
log.error(pos, "not.def.access.class.intf.cant.access",
|
sym, sym.location());
|
||||||
sym, sym.location());
|
}
|
||||||
else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
|
else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
|
||||||
log.error(pos, "report.access", sym,
|
return diags.create(dkind, false, log.currentSource(),
|
||||||
asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
|
pos, "report.access", sym,
|
||||||
sym.location());
|
asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
|
||||||
else
|
sym.location());
|
||||||
log.error(pos, "not.def.public.cant.access",
|
}
|
||||||
sym, sym.location());
|
else {
|
||||||
|
return diags.create(dkind, false, log.currentSource(),
|
||||||
|
pos, "not.def.public.cant.access", sym, sym.location());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve error class indicating that an instance member was accessed
|
/**
|
||||||
* from a static context.
|
* InvalidSymbolError error class indicating that an instance member
|
||||||
|
* has erroneously been accessed from a static context.
|
||||||
*/
|
*/
|
||||||
class StaticError extends ResolveError {
|
class StaticError extends InvalidSymbolError {
|
||||||
|
|
||||||
StaticError(Symbol sym) {
|
StaticError(Symbol sym) {
|
||||||
super(STATICERR, sym, "static error");
|
super(STATICERR, sym, "static error");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Report error.
|
@Override
|
||||||
* @param log The error log to be used for error reporting.
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
* @param pos The position to be used for error reporting.
|
DiagnosticPosition pos,
|
||||||
* @param site The original type from where the selection took place.
|
Type site,
|
||||||
* @param name The name of the symbol to be resolved.
|
Name name,
|
||||||
* @param argtypes The invocation's value arguments,
|
List<Type> argtypes,
|
||||||
* if we looked for a method.
|
List<Type> typeargtypes) {
|
||||||
* @param typeargtypes The invocation's type arguments,
|
|
||||||
* if we looked for a method.
|
|
||||||
*/
|
|
||||||
void report(Log log,
|
|
||||||
DiagnosticPosition pos,
|
|
||||||
Type site,
|
|
||||||
Name name,
|
|
||||||
List<Type> argtypes,
|
|
||||||
List<Type> typeargtypes) {
|
|
||||||
Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
|
Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
|
||||||
? types.erasure(sym.type).tsym
|
? types.erasure(sym.type).tsym
|
||||||
: sym);
|
: sym);
|
||||||
log.error(pos, "non-static.cant.be.ref",
|
return diags.create(dkind, false, log.currentSource(), pos,
|
||||||
kindName(sym), errSym);
|
"non-static.cant.be.ref", kindName(sym), errSym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve error class indicating an ambiguous reference.
|
/**
|
||||||
|
* InvalidSymbolError error class indicating that a pair of symbols
|
||||||
|
* (either methods, constructors or operands) are ambiguous
|
||||||
|
* given an actual arguments/type argument list.
|
||||||
*/
|
*/
|
||||||
class AmbiguityError extends ResolveError {
|
class AmbiguityError extends InvalidSymbolError {
|
||||||
Symbol sym1;
|
|
||||||
|
/** The other maximally specific symbol */
|
||||||
Symbol sym2;
|
Symbol sym2;
|
||||||
|
|
||||||
AmbiguityError(Symbol sym1, Symbol sym2) {
|
AmbiguityError(Symbol sym1, Symbol sym2) {
|
||||||
super(AMBIGUOUS, sym1, "ambiguity error");
|
super(AMBIGUOUS, sym1, "ambiguity error");
|
||||||
this.sym1 = sym1;
|
|
||||||
this.sym2 = sym2;
|
this.sym2 = sym2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Report error.
|
@Override
|
||||||
* @param log The error log to be used for error reporting.
|
JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
|
||||||
* @param pos The position to be used for error reporting.
|
DiagnosticPosition pos,
|
||||||
* @param site The original type from where the selection took place.
|
Type site,
|
||||||
* @param name The name of the symbol to be resolved.
|
Name name,
|
||||||
* @param argtypes The invocation's value arguments,
|
List<Type> argtypes,
|
||||||
* if we looked for a method.
|
List<Type> typeargtypes) {
|
||||||
* @param typeargtypes The invocation's type arguments,
|
|
||||||
* if we looked for a method.
|
|
||||||
*/
|
|
||||||
void report(Log log, DiagnosticPosition pos, Type site, Name name,
|
|
||||||
List<Type> argtypes, List<Type> typeargtypes) {
|
|
||||||
AmbiguityError pair = this;
|
AmbiguityError pair = this;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (pair.sym1.kind == AMBIGUOUS)
|
if (pair.sym.kind == AMBIGUOUS)
|
||||||
pair = (AmbiguityError)pair.sym1;
|
pair = (AmbiguityError)pair.sym;
|
||||||
else if (pair.sym2.kind == AMBIGUOUS)
|
else if (pair.sym2.kind == AMBIGUOUS)
|
||||||
pair = (AmbiguityError)pair.sym2;
|
pair = (AmbiguityError)pair.sym2;
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
Name sname = pair.sym1.name;
|
Name sname = pair.sym.name;
|
||||||
if (sname == names.init) sname = pair.sym1.owner.name;
|
if (sname == names.init) sname = pair.sym.owner.name;
|
||||||
log.error(pos, "ref.ambiguous", sname,
|
return diags.create(dkind, false, log.currentSource(),
|
||||||
kindName(pair.sym1),
|
pos, "ref.ambiguous", sname,
|
||||||
pair.sym1,
|
kindName(pair.sym),
|
||||||
pair.sym1.location(site, types),
|
pair.sym,
|
||||||
|
pair.sym.location(site, types),
|
||||||
kindName(pair.sym2),
|
kindName(pair.sym2),
|
||||||
pair.sym2,
|
pair.sym2,
|
||||||
pair.sym2.location(site, types));
|
pair.sym2.location(site, types));
|
||||||
|
@ -1521,9 +1521,9 @@ public class ClassWriter extends ClassFile {
|
|||||||
int acount = 0;
|
int acount = 0;
|
||||||
|
|
||||||
boolean sigReq =
|
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)
|
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) {
|
if (sigReq) {
|
||||||
assert source.allowGenerics();
|
assert source.allowGenerics();
|
||||||
int alenIdx = writeAttr(names.Signature);
|
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\
|
{0} {1} in {4} {5} cannot be applied to given types\n\
|
||||||
required: {2}\n\
|
required: {2}\n\
|
||||||
found: {3}
|
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\
|
{0} {1} in {4} {5} cannot be applied to given types;\n\
|
||||||
required: {2}\n\
|
required: {2}\n\
|
||||||
found: {3}\n\
|
found: {3}\n\
|
||||||
@ -469,6 +469,8 @@ compiler.err.undetermined.type=\
|
|||||||
type parameters of {0} cannot be determined
|
type parameters of {0} cannot be determined
|
||||||
compiler.err.undetermined.type.1=\
|
compiler.err.undetermined.type.1=\
|
||||||
type parameters of {0} cannot be determined; {1}
|
type parameters of {0} cannot be determined; {1}
|
||||||
|
compiler.err.invalid.inferred.types=\
|
||||||
|
invalid inferred types for {0}; {1}
|
||||||
compiler.err.unreachable.stmt=\
|
compiler.err.unreachable.stmt=\
|
||||||
unreachable statement
|
unreachable statement
|
||||||
compiler.err.initializer.must.be.able.to.complete.normally=\
|
compiler.err.initializer.must.be.able.to.complete.normally=\
|
||||||
@ -995,7 +997,13 @@ compiler.misc.no.conforming.assignment.exists=\
|
|||||||
compiler.misc.arg.length.mismatch=\
|
compiler.misc.arg.length.mismatch=\
|
||||||
cannot instantiate from arguments because actual and formal argument lists differ in length
|
cannot instantiate from arguments because actual and formal argument lists differ in length
|
||||||
compiler.misc.inferred.do.not.conform.to.bounds=\
|
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}
|
||||||
|
|
||||||
#####
|
#####
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
return formatDiagnostic(d, locale);
|
return formatDiagnostic(d, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
|
protected abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
|
||||||
|
|
||||||
public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
|
public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
|
||||||
assert (d.getPosition() != Position.NOPOS);
|
assert (d.getPosition() != Position.NOPOS);
|
||||||
@ -172,9 +172,6 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
return formatIterable(d, (Iterable<?>)arg, l);
|
return formatIterable(d, (Iterable<?>)arg, l);
|
||||||
}
|
}
|
||||||
else if (arg instanceof Type) {
|
else if (arg instanceof Type) {
|
||||||
if (!allCaptured.contains(arg)) {
|
|
||||||
allCaptured = allCaptured.append((Type)arg);
|
|
||||||
}
|
|
||||||
return printer.visit((Type)arg, l);
|
return printer.visit((Type)arg, l);
|
||||||
}
|
}
|
||||||
else if (arg instanceof Symbol) {
|
else if (arg instanceof Symbol) {
|
||||||
@ -482,5 +479,12 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
protected String capturedVarId(CapturedType t, Locale locale) {
|
protected String capturedVarId(CapturedType t, Locale locale) {
|
||||||
return "" + (allCaptured.indexOf(t) + 1);
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public abstract class AbstractLog {
|
|||||||
|
|
||||||
protected DiagnosticSource getSource(JavaFileObject file) {
|
protected DiagnosticSource getSource(JavaFileObject file) {
|
||||||
if (file == null)
|
if (file == null)
|
||||||
return null;
|
return DiagnosticSource.NO_SOURCE;
|
||||||
DiagnosticSource s = sourceMap.get(file);
|
DiagnosticSource s = sourceMap.get(file);
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
s = new DiagnosticSource(file, this);
|
s = new DiagnosticSource(file, this);
|
||||||
|
@ -46,11 +46,22 @@ import static com.sun.tools.javac.util.LayoutCharacters.*;
|
|||||||
* deletion without notice.</b>
|
* deletion without notice.</b>
|
||||||
*/
|
*/
|
||||||
public class DiagnosticSource {
|
public class DiagnosticSource {
|
||||||
|
|
||||||
|
/* constant DiagnosticSource to be used when sourcefile is missing */
|
||||||
|
public static final DiagnosticSource NO_SOURCE = new DiagnosticSource() {
|
||||||
|
@Override
|
||||||
|
protected boolean findLine(int pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
|
public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
|
||||||
this.fileObject = fo;
|
this.fileObject = fo;
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DiagnosticSource() {}
|
||||||
|
|
||||||
/** Return the underlying file object handled by this
|
/** Return the underlying file object handled by this
|
||||||
* DiagnosticSource object.
|
* DiagnosticSource object.
|
||||||
*/
|
*/
|
||||||
@ -134,7 +145,7 @@ public class DiagnosticSource {
|
|||||||
/** Find the line in the buffer that contains the current position
|
/** Find the line in the buffer that contains the current position
|
||||||
* @param pos Character offset into the buffer
|
* @param pos Character offset into the buffer
|
||||||
*/
|
*/
|
||||||
private boolean findLine(int pos) {
|
protected boolean findLine(int pos) {
|
||||||
if (pos == Position.NOPOS)
|
if (pos == Position.NOPOS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
*/
|
*/
|
||||||
public JCDiagnostic error(
|
public JCDiagnostic error(
|
||||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, ERROR, true, source, pos, qualify(ERROR, key), args);
|
return create(ERROR, true, source, pos, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +96,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
*/
|
*/
|
||||||
public JCDiagnostic mandatoryWarning(
|
public JCDiagnostic mandatoryWarning(
|
||||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, WARNING, true, source, pos, qualify(WARNING, key), args);
|
return create(WARNING, true, source, pos, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +108,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
*/
|
*/
|
||||||
public JCDiagnostic warning(
|
public JCDiagnostic warning(
|
||||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, WARNING, false, source, pos, qualify(WARNING, key), args);
|
return create(WARNING, false, source, pos, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,7 +118,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
* @see MandatoryWarningHandler
|
* @see MandatoryWarningHandler
|
||||||
*/
|
*/
|
||||||
public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) {
|
public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, NOTE, true, source, null, qualify(NOTE, key), args);
|
return create(NOTE, true, source, null, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +127,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
* @param args Fields of the error message.
|
* @param args Fields of the error message.
|
||||||
*/
|
*/
|
||||||
public JCDiagnostic note(String key, Object... args) {
|
public JCDiagnostic note(String key, Object... args) {
|
||||||
return note(null, null, key, args);
|
return create(NOTE, false, null, null, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,7 +139,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
*/
|
*/
|
||||||
public JCDiagnostic note(
|
public JCDiagnostic note(
|
||||||
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, NOTE, false, source, pos, qualify(NOTE, key), args);
|
return create(NOTE, false, source, pos, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +148,21 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
|
|||||||
* @param args Fields of the error message.
|
* @param args Fields of the error message.
|
||||||
*/
|
*/
|
||||||
public JCDiagnostic fragment(String key, Object... args) {
|
public JCDiagnostic fragment(String key, Object... args) {
|
||||||
return new JCDiagnostic(formatter, FRAGMENT, false, null, null, qualify(FRAGMENT, key), args);
|
return create(FRAGMENT, false, null, null, key, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new diagnostic of the given kind.
|
||||||
|
* @param kind The diagnostic kind
|
||||||
|
* @param isMandatory is diagnostic mandatory?
|
||||||
|
* @param source The source of the compilation unit, if any, in which to report the note.
|
||||||
|
* @param pos The source position at which to report the note.
|
||||||
|
* @param key The key for the localized error message.
|
||||||
|
* @param args Fields of the error message.
|
||||||
|
*/
|
||||||
|
public JCDiagnostic create(
|
||||||
|
DiagnosticType kind, boolean isMandatory, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
|
||||||
|
return new JCDiagnostic(formatter, kind, isMandatory, source, pos, qualify(kind, key), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String qualify(DiagnosticType t, String key) {
|
protected String qualify(DiagnosticType t, String key) {
|
||||||
|
@ -68,7 +68,10 @@ public class RichDiagnosticFormatter extends
|
|||||||
final JavacMessages messages;
|
final JavacMessages messages;
|
||||||
|
|
||||||
/* name simplifier used by this formatter */
|
/* name simplifier used by this formatter */
|
||||||
ClassNameSimplifier nameSimplifier;
|
protected ClassNameSimplifier nameSimplifier;
|
||||||
|
|
||||||
|
/* type/symbol printer used by this formatter */
|
||||||
|
private RichPrinter printer;
|
||||||
|
|
||||||
/* map for keeping track of a where clause associated to a given type */
|
/* map for keeping track of a where clause associated to a given type */
|
||||||
Map<WhereClauseKind, Map<Type, JCDiagnostic>> whereClauses;
|
Map<WhereClauseKind, Map<Type, JCDiagnostic>> whereClauses;
|
||||||
@ -83,7 +86,7 @@ public class RichDiagnosticFormatter extends
|
|||||||
|
|
||||||
protected RichDiagnosticFormatter(Context context) {
|
protected RichDiagnosticFormatter(Context context) {
|
||||||
super((AbstractDiagnosticFormatter)Log.instance(context).getDiagnosticFormatter());
|
super((AbstractDiagnosticFormatter)Log.instance(context).getDiagnosticFormatter());
|
||||||
this.formatter.setPrinter(printer);
|
setRichPrinter(new RichPrinter());
|
||||||
this.syms = Symtab.instance(context);
|
this.syms = Symtab.instance(context);
|
||||||
this.diags = JCDiagnostic.Factory.instance(context);
|
this.diags = JCDiagnostic.Factory.instance(context);
|
||||||
this.types = Types.instance(context);
|
this.types = Types.instance(context);
|
||||||
@ -116,6 +119,23 @@ public class RichDiagnosticFormatter extends
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type/symbol printer used by this formatter.
|
||||||
|
* @param printer the rich printer to be set
|
||||||
|
*/
|
||||||
|
protected void setRichPrinter(RichPrinter printer) {
|
||||||
|
this.printer = printer;
|
||||||
|
formatter.setPrinter(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type/symbol printer used by this formatter.
|
||||||
|
* @return type/symbol rich printer
|
||||||
|
*/
|
||||||
|
protected RichPrinter getRichPrinter() {
|
||||||
|
return printer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preprocess a given diagnostic by looking both into its arguments and into
|
* Preprocess a given diagnostic by looking both into its arguments and into
|
||||||
* its subdiagnostics (if any). This preprocessing is responsible for
|
* its subdiagnostics (if any). This preprocessing is responsible for
|
||||||
@ -217,7 +237,7 @@ public class RichDiagnosticFormatter extends
|
|||||||
* name belong to different packages - in this case the formatter reverts
|
* name belong to different packages - in this case the formatter reverts
|
||||||
* to fullnames as compact names might lead to a confusing diagnostic.
|
* to fullnames as compact names might lead to a confusing diagnostic.
|
||||||
*/
|
*/
|
||||||
class ClassNameSimplifier {
|
protected class ClassNameSimplifier {
|
||||||
|
|
||||||
/* table for keeping track of all short name usages */
|
/* table for keeping track of all short name usages */
|
||||||
Map<Name, List<Symbol>> nameClashes = new HashMap<Name, List<Symbol>>();
|
Map<Name, List<Symbol>> nameClashes = new HashMap<Name, List<Symbol>>();
|
||||||
@ -272,7 +292,7 @@ public class RichDiagnosticFormatter extends
|
|||||||
* discovered during type/symbol preprocessing. This printer is set on the delegate
|
* discovered during type/symbol preprocessing. This printer is set on the delegate
|
||||||
* formatter so that rich type/symbol info can be properly rendered.
|
* formatter so that rich type/symbol info can be properly rendered.
|
||||||
*/
|
*/
|
||||||
protected Printer printer = new Printer() {
|
protected class RichPrinter extends Printer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String localize(Locale locale, String key, Object... args) {
|
public String localize(Locale locale, String key, Object... args) {
|
||||||
|
@ -74,7 +74,7 @@ import static com.sun.tools.classfile.AccessFlags.*;
|
|||||||
public class AttributeWriter extends BasicWriter
|
public class AttributeWriter extends BasicWriter
|
||||||
implements Attribute.Visitor<Void,Void>
|
implements Attribute.Visitor<Void,Void>
|
||||||
{
|
{
|
||||||
static AttributeWriter instance(Context context) {
|
public static AttributeWriter instance(Context context) {
|
||||||
AttributeWriter instance = context.get(AttributeWriter.class);
|
AttributeWriter instance = context.get(AttributeWriter.class);
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
instance = new AttributeWriter(context);
|
instance = new AttributeWriter(context);
|
||||||
|
@ -93,17 +93,25 @@ public class ClassWriter extends BasicWriter {
|
|||||||
this.lastModified = lastModified;
|
this.lastModified = lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassFile getClassFile() {
|
protected ClassFile getClassFile() {
|
||||||
return classFile;
|
return classFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Method getMethod() {
|
protected void setClassFile(ClassFile cf) {
|
||||||
|
classFile = cf;
|
||||||
|
constant_pool = classFile.constant_pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Method getMethod() {
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setMethod(Method m) {
|
||||||
|
method = m;
|
||||||
|
}
|
||||||
|
|
||||||
public void write(ClassFile cf) {
|
public void write(ClassFile cf) {
|
||||||
classFile = cf;
|
setClassFile(cf);
|
||||||
constant_pool = classFile.constant_pool;
|
|
||||||
|
|
||||||
if ((options.sysInfo || options.verbose) && !options.compat) {
|
if ((options.sysInfo || options.verbose) && !options.compat) {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
@ -197,13 +205,13 @@ public class ClassWriter extends BasicWriter {
|
|||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeFields() {
|
protected void writeFields() {
|
||||||
for (Field f: classFile.fields) {
|
for (Field f: classFile.fields) {
|
||||||
writeField(f);
|
writeField(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeField(Field f) {
|
protected void writeField(Field f) {
|
||||||
if (!options.checkAccess(f.access_flags))
|
if (!options.checkAccess(f.access_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -259,12 +267,12 @@ public class ClassWriter extends BasicWriter {
|
|||||||
println();
|
println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMethods() {
|
protected void writeMethods() {
|
||||||
for (Method m: classFile.methods)
|
for (Method m: classFile.methods)
|
||||||
writeMethod(m);
|
writeMethod(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMethod(Method m) {
|
protected void writeMethod(Method m) {
|
||||||
if (!options.checkAccess(m.access_flags))
|
if (!options.checkAccess(m.access_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import static com.sun.tools.classfile.ConstantPool.*;
|
|||||||
* deletion without notice.</b>
|
* deletion without notice.</b>
|
||||||
*/
|
*/
|
||||||
public class ConstantWriter extends BasicWriter {
|
public class ConstantWriter extends BasicWriter {
|
||||||
static ConstantWriter instance(Context context) {
|
public static ConstantWriter instance(Context context) {
|
||||||
ConstantWriter instance = context.get(ConstantWriter.class);
|
ConstantWriter instance = context.get(ConstantWriter.class);
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
instance = new ConstantWriter(context);
|
instance = new ConstantWriter(context);
|
||||||
@ -54,7 +54,12 @@ public class ConstantWriter extends BasicWriter {
|
|||||||
options = Options.instance(context);
|
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>() {
|
ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
|
||||||
public Integer visitClass(CONSTANT_Class_info info, Void p) {
|
public Integer visitClass(CONSTANT_Class_info info, Void p) {
|
||||||
println("#" + info.name_index + ";\t// " + stringValue(info));
|
println("#" + info.name_index + ";\t// " + stringValue(info));
|
||||||
@ -114,7 +119,6 @@ public class ConstantWriter extends BasicWriter {
|
|||||||
|
|
||||||
};
|
};
|
||||||
println(" Constant pool:");
|
println(" Constant pool:");
|
||||||
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
|
|
||||||
int cpx = 1;
|
int cpx = 1;
|
||||||
while (cpx < constant_pool.size()) {
|
while (cpx < constant_pool.size()) {
|
||||||
try {
|
try {
|
||||||
@ -127,7 +131,7 @@ public class ConstantWriter extends BasicWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(int cpx) {
|
protected void write(int cpx) {
|
||||||
ClassFile classFile = classWriter.getClassFile();
|
ClassFile classFile = classWriter.getClassFile();
|
||||||
if (cpx == 0) {
|
if (cpx == 0) {
|
||||||
print("#0");
|
print("#0");
|
||||||
|
@ -36,6 +36,7 @@ import java.io.StringWriter;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -298,21 +299,28 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
JavapTask() {
|
public JavapTask() {
|
||||||
context = new Context();
|
context = new Context();
|
||||||
context.put(Messages.class, this);
|
context.put(Messages.class, this);
|
||||||
options = Options.instance(context);
|
options = Options.instance(context);
|
||||||
|
attributeFactory = new Attribute.Factory();
|
||||||
}
|
}
|
||||||
|
|
||||||
JavapTask(Writer out,
|
public JavapTask(Writer out,
|
||||||
JavaFileManager fileManager,
|
JavaFileManager fileManager,
|
||||||
DiagnosticListener<? super JavaFileObject> diagnosticListener,
|
DiagnosticListener<? super JavaFileObject> diagnosticListener) {
|
||||||
Iterable<String> options,
|
|
||||||
Iterable<String> classes) {
|
|
||||||
this();
|
this();
|
||||||
this.log = getPrintWriterForWriter(out);
|
this.log = getPrintWriterForWriter(out);
|
||||||
this.fileManager = fileManager;
|
this.fileManager = fileManager;
|
||||||
this.diagnosticListener = diagnosticListener;
|
this.diagnosticListener = diagnosticListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JavapTask(Writer out,
|
||||||
|
JavaFileManager fileManager,
|
||||||
|
DiagnosticListener<? super JavaFileObject> diagnosticListener,
|
||||||
|
Iterable<String> options,
|
||||||
|
Iterable<String> classes) {
|
||||||
|
this(out, fileManager, diagnosticListener);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
handleOptions(options, false);
|
handleOptions(options, false);
|
||||||
@ -553,29 +561,10 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Attribute.Factory attributeFactory = new Attribute.Factory();
|
|
||||||
attributeFactory.setCompat(options.compat);
|
attributeFactory.setCompat(options.compat);
|
||||||
attributeFactory.setJSR277(options.jsr277);
|
attributeFactory.setJSR277(options.jsr277);
|
||||||
|
|
||||||
InputStream in = fo.openInputStream();
|
write(read(fo));
|
||||||
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);
|
|
||||||
|
|
||||||
} catch (ConstantPoolException e) {
|
} catch (ConstantPoolException e) {
|
||||||
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
|
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
|
||||||
@ -606,6 +595,103 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||||||
return ok;
|
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) {
|
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
|
||||||
return JavapFileManager.create(dl, log, options);
|
return JavapFileManager.create(dl, log, options);
|
||||||
}
|
}
|
||||||
@ -735,7 +821,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Context context;
|
protected Context context;
|
||||||
JavaFileManager fileManager;
|
JavaFileManager fileManager;
|
||||||
PrintWriter log;
|
PrintWriter log;
|
||||||
DiagnosticListener<? super JavaFileObject> diagnosticListener;
|
DiagnosticListener<? super JavaFileObject> diagnosticListener;
|
||||||
@ -744,6 +830,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
|
|||||||
//ResourceBundle bundle;
|
//ResourceBundle bundle;
|
||||||
Locale task_locale;
|
Locale task_locale;
|
||||||
Map<Locale, ResourceBundle> bundles;
|
Map<Locale, ResourceBundle> bundles;
|
||||||
|
protected Attribute.Factory attributeFactory;
|
||||||
|
|
||||||
private static final String progname = "javap";
|
private static final String progname = "javap";
|
||||||
|
|
||||||
|
@ -134,6 +134,9 @@ public class SourceWriter extends InstructionDetailWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String readSource(ClassFile cf) {
|
private String readSource(ClassFile cf) {
|
||||||
|
if (fileManager == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
Location location;
|
Location location;
|
||||||
if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
|
if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
|
||||||
location = StandardLocation.SOURCE_PATH;
|
location = StandardLocation.SOURCE_PATH;
|
||||||
|
32
langtools/test/tools/javac/6835430/A.java
Normal file
32
langtools/test/tools/javac/6835430/A.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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 {}
|
||||||
|
}
|
38
langtools/test/tools/javac/6835430/T6835430.java
Normal file
38
langtools/test/tools/javac/6835430/T6835430.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 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()
|
* @summary Basic/Raw formatters should use type/symbol printer instead of toString()
|
||||||
* @author mcimadamore
|
* @author mcimadamore
|
||||||
* @compile/fail/ref=T6799605.out -XDrawDiagnostics T6799605.java
|
* @compile/fail/ref=T6799605.out -XDrawDiagnostics T6799605.java
|
||||||
|
* @compile/fail/ref=T6799605.out -XDoldDiags -XDrawDiagnostics T6799605.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class T6799605<X> {
|
class T6799605<X> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
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, ?>, 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, ?>, 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: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
|
3 errors
|
||||||
|
66
langtools/test/tools/javac/api/6852595/T6852595.java
Normal file
66
langtools/test/tools/javac/api/6852595/T6852595.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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 6852595
|
||||||
|
* @summary Accessing scope using JSR199 API on erroneous tree causes Illegal Argument Exception
|
||||||
|
* @author mcimadamore
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.source.tree.*;
|
||||||
|
import com.sun.source.util.TreePath;
|
||||||
|
import com.sun.source.util.Trees;
|
||||||
|
import com.sun.tools.javac.api.JavacTrees;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.*;
|
||||||
|
|
||||||
|
import static javax.tools.JavaFileObject.Kind;
|
||||||
|
|
||||||
|
public class T6852595 {
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
JavaFileObject sfo = new SimpleJavaFileObject(URI.create("myfo:/Test.java"),Kind.SOURCE) {
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return "class BadName { Object o = j; }";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
List<? extends JavaFileObject> files = Arrays.asList(sfo);
|
||||||
|
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
|
JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, files);
|
||||||
|
Iterable<? extends CompilationUnitTree> compUnits = ct.parse();
|
||||||
|
CompilationUnitTree cu = compUnits.iterator().next();
|
||||||
|
ClassTree cdef = (ClassTree)cu.getTypeDecls().get(0);
|
||||||
|
JCVariableDecl vdef = (JCVariableDecl)cdef.getMembers().get(0);
|
||||||
|
TreePath path = TreePath.getPath(cu, vdef.init);
|
||||||
|
Trees.instance(ct).getScope(path);
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 6476073
|
* @bug 6476073
|
||||||
* @summary Capture using super wildcard of type variables doesn't work
|
* @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
|
* @compile T6476073.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
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
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
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
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
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
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
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
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
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
|
38
langtools/test/tools/javac/generics/inference/T6835428.java
Normal file
38
langtools/test/tools/javac/generics/inference/T6835428.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user