8017104: javac should have a class for primitive types that inherits from Type

Reviewed-by: jjg
This commit is contained in:
Vicente Romero 2013-06-25 16:12:53 +01:00
parent 17f5808828
commit d7fff903e8
14 changed files with 517 additions and 292 deletions

View file

@ -69,6 +69,7 @@ import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Type.ErrorType; import com.sun.tools.javac.code.Type.ErrorType;
import com.sun.tools.javac.code.Type.UnionClassType; import com.sun.tools.javac.code.Type.UnionClassType;
import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Types.TypeRelation; import com.sun.tools.javac.code.Types.TypeRelation;
import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
@ -653,8 +654,7 @@ public class JavacTrees extends DocTrees {
switch (t.getTag()) { switch (t.getTag()) {
case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
return t.getTag() == s.getTag(); return t.hasTag(s.getTag());
default: default:
throw new AssertionError("fuzzyMatcher " + t.getTag()); throw new AssertionError("fuzzyMatcher " + t.getTag());
} }
@ -668,7 +668,7 @@ public class JavacTrees extends DocTrees {
if (s.isPartial()) if (s.isPartial())
return visit(s, t); return visit(s, t);
return s.getTag() == ARRAY return s.hasTag(ARRAY)
&& visit(t.elemtype, types.elemtype(s)); && visit(t.elemtype, types.elemtype(s));
} }
@ -685,7 +685,7 @@ public class JavacTrees extends DocTrees {
@Override @Override
public Boolean visitErrorType(ErrorType t, Type s) { public Boolean visitErrorType(ErrorType t, Type s) {
return s.getTag() == CLASS return s.hasTag(CLASS)
&& t.tsym.name == ((ClassType) s).tsym.name; && t.tsym.name == ((ClassType) s).tsym.name;
} }
}; };

View file

@ -83,7 +83,7 @@ public abstract class Attribute implements AnnotationValue {
return v.visitString((String) value, p); return v.visitString((String) value, p);
if (value instanceof Integer) { if (value instanceof Integer) {
int i = (Integer) value; int i = (Integer) value;
switch (type.tag) { switch (type.getTag()) {
case BOOLEAN: return v.visitBoolean(i != 0, p); case BOOLEAN: return v.visitBoolean(i != 0, p);
case CHAR: return v.visitChar((char) i, p); case CHAR: return v.visitChar((char) i, p);
case BYTE: return v.visitByte((byte) i, p); case BYTE: return v.visitByte((byte) i, p);
@ -91,7 +91,7 @@ public abstract class Attribute implements AnnotationValue {
case INT: return v.visitInt(i, p); case INT: return v.visitInt(i, p);
} }
} }
switch (type.tag) { switch (type.getTag()) {
case LONG: return v.visitLong((Long) value, p); case LONG: return v.visitLong((Long) value, p);
case FLOAT: return v.visitFloat((Float) value, p); case FLOAT: return v.visitFloat((Float) value, p);
case DOUBLE: return v.visitDouble((Double) value, p); case DOUBLE: return v.visitDouble((Double) value, p);

View file

@ -218,10 +218,10 @@ public class Kinds {
/** A KindName representing the kind of a given class/interface type. /** A KindName representing the kind of a given class/interface type.
*/ */
public static KindName typeKindName(Type t) { public static KindName typeKindName(Type t) {
if (t.tag == TYPEVAR || if (t.hasTag(TYPEVAR) ||
t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0) t.hasTag(CLASS) && (t.tsym.flags() & COMPOUND) != 0)
return KindName.BOUND; return KindName.BOUND;
else if (t.tag == PACKAGE) else if (t.hasTag(PACKAGE))
return KindName.PACKAGE; return KindName.PACKAGE;
else if ((t.tsym.flags_field & ANNOTATION) != 0) else if ((t.tsym.flags_field & ANNOTATION) != 0)
return KindName.ANNOTATION; return KindName.ANNOTATION;

View file

@ -215,7 +215,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
@Override @Override
public String visitClassType(ClassType t, Locale locale) { public String visitClassType(ClassType t, Locale locale) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) { if (t.getEnclosingType().hasTag(CLASS) && t.tsym.owner.kind == Kinds.TYP) {
buf.append(visit(t.getEnclosingType(), locale)); buf.append(visit(t.getEnclosingType(), locale));
buf.append('.'); buf.append('.');
buf.append(className(t, false, locale)); buf.append(className(t, false, locale));
@ -379,7 +379,7 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
? s.owner.name.toString() ? s.owner.name.toString()
: s.name.toString(); : s.name.toString();
if (s.type != null) { if (s.type != null) {
if (s.type.tag == FORALL) { if (s.type.hasTag(FORALL)) {
ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms; ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms;
} }
ms += "(" + printMethodArgs( ms += "(" + printMethodArgs(

View file

@ -699,17 +699,17 @@ public abstract class Symbol implements Element {
public final boolean precedes(TypeSymbol that, Types types) { public final boolean precedes(TypeSymbol that, Types types) {
if (this == that) if (this == that)
return false; return false;
if (this.type.tag == that.type.tag) { if (type.hasTag(that.type.getTag())) {
if (this.type.hasTag(CLASS)) { if (type.hasTag(CLASS)) {
return return
types.rank(that.type) < types.rank(this.type) || types.rank(that.type) < types.rank(this.type) ||
types.rank(that.type) == types.rank(this.type) && types.rank(that.type) == types.rank(this.type) &&
that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
} else if (this.type.hasTag(TYPEVAR)) { } else if (type.hasTag(TYPEVAR)) {
return types.isSubtype(this.type, that.type); return types.isSubtype(this.type, that.type);
} }
} }
return this.type.hasTag(TYPEVAR); return type.hasTag(TYPEVAR);
} }
@Override @Override

View file

@ -28,7 +28,6 @@ package com.sun.tools.javac.code;
import java.util.*; import java.util.*;
import javax.lang.model.element.ElementVisitor; import javax.lang.model.element.ElementVisitor;
import javax.lang.model.type.TypeVisitor;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
@ -65,16 +64,16 @@ public class Symtab {
/** Builtin types. /** Builtin types.
*/ */
public final Type byteType = new Type(BYTE, null); public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null);
public final Type charType = new Type(CHAR, null); public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null);
public final Type shortType = new Type(SHORT, null); public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null);
public final Type intType = new Type(INT, null); public final JCPrimitiveType intType = new JCPrimitiveType(INT, null);
public final Type longType = new Type(LONG, null); public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null);
public final Type floatType = new Type(FLOAT, null); public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null);
public final Type doubleType = new Type(DOUBLE, null); public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null);
public final Type booleanType = new Type(BOOLEAN, null); public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null);
public final Type botType = new BottomType(); public final Type botType = new BottomType();
public final JCNoType voidType = new JCNoType(VOID); public final JCVoidType voidType = new JCVoidType();
private final Names names; private final Names names;
private final ClassReader reader; private final ClassReader reader;
@ -208,7 +207,7 @@ public class Symtab {
public void initType(Type type, ClassSymbol c) { public void initType(Type type, ClassSymbol c) {
type.tsym = c; type.tsym = c;
typeOfTag[type.tag.ordinal()] = type; typeOfTag[type.getTag().ordinal()] = type;
} }
public void initType(Type type, String name) { public void initType(Type type, String name) {
@ -220,7 +219,7 @@ public class Symtab {
public void initType(Type type, String name, String bname) { public void initType(Type type, String name, String bname) {
initType(type, name); initType(type, name);
boxedName[type.tag.ordinal()] = names.fromString("java.lang." + bname); boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname);
} }
/** The class symbol that owns all predefined symbols. /** The class symbol that owns all predefined symbols.
@ -330,7 +329,7 @@ public class Symtab {
} }
public void synthesizeBoxTypeIfMissing(final Type type) { public void synthesizeBoxTypeIfMissing(final Type type) {
ClassSymbol sym = reader.enterClass(boxedName[type.tag.ordinal()]); ClassSymbol sym = reader.enterClass(boxedName[type.getTag().ordinal()]);
final Completer completer = sym.completer; final Completer completer = sym.completer;
if (completer != null) { if (completer != null) {
sym.completer = new Completer() { sym.completer = new Completer() {
@ -388,12 +387,7 @@ public class Symtab {
target = Target.instance(context); target = Target.instance(context);
// Create the unknown type // Create the unknown type
unknownType = new Type(UNKNOWN, null) { unknownType = new UnknownType();
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitUnknown(this, p);
}
};
// create the basic builtin symbols // create the basic builtin symbols
rootPackage = new PackageSymbol(names.empty, null); rootPackage = new PackageSymbol(names.empty, null);

View file

@ -70,25 +70,19 @@ import static com.sun.tools.javac.code.TypeTag.*;
* *
* @see TypeTag * @see TypeTag
*/ */
public class Type implements PrimitiveType { public abstract class Type implements TypeMirror {
/** Constant type: no type at all. */ /** Constant type: no type at all. */
public static final JCNoType noType = new JCNoType(NONE); public static final JCNoType noType = new JCNoType();
/** Constant type: special type to be used during recovery of deferred expressions. */ /** Constant type: special type to be used during recovery of deferred expressions. */
public static final JCNoType recoveryType = new JCNoType(NONE); public static final JCNoType recoveryType = new JCNoType();
/** If this switch is turned on, the names of type variables /** If this switch is turned on, the names of type variables
* and anonymous classes are printed with hashcodes appended. * and anonymous classes are printed with hashcodes appended.
*/ */
public static boolean moreInfo = false; public static boolean moreInfo = false;
/** The tag of this type.
*
* @see TypeTag
*/
protected TypeTag tag;
/** The defining class / interface / package / type variable. /** The defining class / interface / package / type variable.
*/ */
public TypeSymbol tsym; public TypeSymbol tsym;
@ -98,39 +92,37 @@ public class Type implements PrimitiveType {
* @return true if tag is equal to the current type tag. * @return true if tag is equal to the current type tag.
*/ */
public boolean hasTag(TypeTag tag) { public boolean hasTag(TypeTag tag) {
return this.tag == tag; return tag == getTag();
} }
/** /**
* Returns the current type tag. * Returns the current type tag.
* @return the value of the current type tag. * @return the value of the current type tag.
*/ */
public TypeTag getTag() { public abstract TypeTag getTag();
return tag;
}
public boolean isNumeric() { public boolean isNumeric() {
return tag.isNumeric; return false;
} }
public boolean isPrimitive() { public boolean isPrimitive() {
return tag.isPrimitive; return false;
} }
public boolean isPrimitiveOrVoid() { public boolean isPrimitiveOrVoid() {
return tag.isPrimitiveOrVoid; return false;
} }
public boolean isReference() { public boolean isReference() {
return tag.isReference; return false;
} }
public boolean isNullOrReference() { public boolean isNullOrReference() {
return (tag.isReference || tag == BOT); return false;
} }
public boolean isPartial() { public boolean isPartial() {
return tag.isPartial; return false;
} }
/** /**
@ -143,6 +135,18 @@ public class Type implements PrimitiveType {
return null; return null;
} }
/** Is this a constant type whose value is false?
*/
public boolean isFalse() {
return false;
}
/** Is this a constant type whose value is true?
*/
public boolean isTrue() {
return false;
}
/** /**
* Get the representation of this type used for modelling purposes. * Get the representation of this type used for modelling purposes.
* By default, this is itself. For ErrorType, a different value * By default, this is itself. For ErrorType, a different value
@ -153,7 +157,7 @@ public class Type implements PrimitiveType {
} }
public static List<Type> getModelTypes(List<Type> ts) { public static List<Type> getModelTypes(List<Type> ts) {
ListBuffer<Type> lb = new ListBuffer<Type>(); ListBuffer<Type> lb = new ListBuffer<>();
for (Type t: ts) for (Type t: ts)
lb.append(t.getModelType()); lb.append(t.getModelType());
return lb.toList(); return lb.toList();
@ -163,8 +167,7 @@ public class Type implements PrimitiveType {
/** Define a type given its tag and type symbol /** Define a type given its tag and type symbol
*/ */
public Type(TypeTag tag, TypeSymbol tsym) { public Type(TypeSymbol tsym) {
this.tag = tag;
this.tsym = tsym; this.tsym = tsym;
} }
@ -203,18 +206,7 @@ public class Type implements PrimitiveType {
* and with given constant value * and with given constant value
*/ */
public Type constType(Object constValue) { public Type constType(Object constValue) {
final Object value = constValue; throw new AssertionError();
Assert.check(isPrimitive());
return new Type(tag, tsym) {
@Override
public Object constValue() {
return value;
}
@Override
public Type baseType() {
return tsym.type;
}
};
} }
/** /**
@ -272,7 +264,9 @@ public class Type implements PrimitiveType {
String s = (tsym == null || tsym.name == null) String s = (tsym == null || tsym.name == null)
? "<none>" ? "<none>"
: tsym.name.toString(); : tsym.name.toString();
if (moreInfo && tag == TYPEVAR) s = s + hashCode(); if (moreInfo && hasTag(TYPEVAR)) {
s = s + hashCode();
}
return s; return s;
} }
@ -298,12 +292,7 @@ public class Type implements PrimitiveType {
*/ */
public String stringValue() { public String stringValue() {
Object cv = Assert.checkNonNull(constValue()); Object cv = Assert.checkNonNull(constValue());
if (tag == BOOLEAN) return cv.toString();
return ((Integer) cv).intValue() == 0 ? "false" : "true";
else if (tag == CHAR)
return String.valueOf((char) ((Integer) cv).intValue());
else
return cv.toString();
} }
/** /**
@ -321,24 +310,6 @@ public class Type implements PrimitiveType {
return super.hashCode(); return super.hashCode();
} }
/** Is this a constant type whose value is false?
*/
public boolean isFalse() {
return
tag == BOOLEAN &&
constValue() != null &&
((Integer)constValue()).intValue() == 0;
}
/** Is this a constant type whose value is true?
*/
public boolean isTrue() {
return
tag == BOOLEAN &&
constValue() != null &&
((Integer)constValue()).intValue() != 0;
}
public String argtypes(boolean varargs) { public String argtypes(boolean varargs) {
List<Type> args = getParameterTypes(); List<Type> args = getParameterTypes();
if (!varargs) return args.toString(); if (!varargs) return args.toString();
@ -348,7 +319,7 @@ public class Type implements PrimitiveType {
args = args.tail; args = args.tail;
buf.append(','); buf.append(',');
} }
if (args.head.unannotatedType().tag == ARRAY) { if (args.head.unannotatedType().hasTag(ARRAY)) {
buf.append(((ArrayType)args.head.unannotatedType()).elemtype); buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
if (args.head.getAnnotationMirrors().nonEmpty()) { if (args.head.getAnnotationMirrors().nonEmpty()) {
buf.append(args.head.getAnnotationMirrors()); buf.append(args.head.getAnnotationMirrors());
@ -485,28 +456,122 @@ public class Type implements PrimitiveType {
return tsym; return tsym;
} }
@Override
public TypeKind getKind() { public TypeKind getKind() {
switch (tag) { return TypeKind.OTHER;
case BYTE: return TypeKind.BYTE;
case CHAR: return TypeKind.CHAR;
case SHORT: return TypeKind.SHORT;
case INT: return TypeKind.INT;
case LONG: return TypeKind.LONG;
case FLOAT: return TypeKind.FLOAT;
case DOUBLE: return TypeKind.DOUBLE;
case BOOLEAN: return TypeKind.BOOLEAN;
case VOID: return TypeKind.VOID;
case BOT: return TypeKind.NULL;
case NONE: return TypeKind.NONE;
default: return TypeKind.OTHER;
}
} }
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) { public <R, P> R accept(TypeVisitor<R, P> v, P p) {
if (isPrimitive()) throw new AssertionError();
}
public static class JCPrimitiveType extends Type
implements javax.lang.model.type.PrimitiveType {
TypeTag tag;
public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
super(tsym);
this.tag = tag;
Assert.check(tag.isPrimitive);
}
@Override
public boolean isNumeric() {
return tag != BOOLEAN;
}
@Override
public boolean isPrimitive() {
return true;
}
@Override
public TypeTag getTag() {
return tag;
}
@Override
public boolean isPrimitiveOrVoid() {
return true;
}
/** Define a constant type, of the same kind as this type
* and with given constant value
*/
@Override
public Type constType(Object constValue) {
final Object value = constValue;
return new JCPrimitiveType(tag, tsym) {
@Override
public Object constValue() {
return value;
}
@Override
public Type baseType() {
return tsym.type;
}
};
}
/**
* The constant value of this type, converted to String
*/
@Override
public String stringValue() {
Object cv = Assert.checkNonNull(constValue());
if (tag == BOOLEAN) {
return ((Integer) cv).intValue() == 0 ? "false" : "true";
}
else if (tag == CHAR) {
return String.valueOf((char) ((Integer) cv).intValue());
}
else {
return cv.toString();
}
}
/** Is this a constant type whose value is false?
*/
@Override
public boolean isFalse() {
return
tag == BOOLEAN &&
constValue() != null &&
((Integer)constValue()).intValue() == 0;
}
/** Is this a constant type whose value is true?
*/
@Override
public boolean isTrue() {
return
tag == BOOLEAN &&
constValue() != null &&
((Integer)constValue()).intValue() != 0;
}
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitPrimitive(this, p); return v.visitPrimitive(this, p);
else }
@Override
public TypeKind getKind() {
switch (tag) {
case BYTE: return TypeKind.BYTE;
case CHAR: return TypeKind.CHAR;
case SHORT: return TypeKind.SHORT;
case INT: return TypeKind.INT;
case LONG: return TypeKind.LONG;
case FLOAT: return TypeKind.FLOAT;
case DOUBLE: return TypeKind.DOUBLE;
case BOOLEAN: return TypeKind.BOOLEAN;
}
throw new AssertionError(); throw new AssertionError();
}
} }
public static class WildcardType extends Type public static class WildcardType extends Type
@ -522,7 +587,7 @@ public class Type implements PrimitiveType {
} }
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) { public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
super(WILDCARD, tsym); super(tsym);
this.type = Assert.checkNonNull(type); this.type = Assert.checkNonNull(type);
this.kind = kind; this.kind = kind;
} }
@ -535,6 +600,12 @@ public class Type implements PrimitiveType {
this.bound = bound; this.bound = bound;
} }
@Override
public TypeTag getTag() {
return WILDCARD;
}
@Override
public boolean contains(Type t) { public boolean contains(Type t) {
return kind != UNBOUND && type.contains(t); return kind != UNBOUND && type.contains(t);
} }
@ -551,6 +622,17 @@ public class Type implements PrimitiveType {
return kind == UNBOUND; return kind == UNBOUND;
} }
@Override
public boolean isReference() {
return true;
}
@Override
public boolean isNullOrReference() {
return true;
}
@Override
public Type withTypeVar(Type t) { public Type withTypeVar(Type t) {
//-System.err.println(this+".withTypeVar("+t+");");//DEBUG //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
if (bound == t) if (bound == t)
@ -640,7 +722,7 @@ public class Type implements PrimitiveType {
public List<Type> all_interfaces_field; public List<Type> all_interfaces_field;
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) { public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
super(CLASS, tsym); super(tsym);
this.outer_field = outer; this.outer_field = outer;
this.typarams_field = typarams; this.typarams_field = typarams;
this.allparams_field = null; this.allparams_field = null;
@ -657,6 +739,11 @@ public class Type implements PrimitiveType {
*/ */
} }
@Override
public TypeTag getTag() {
return CLASS;
}
@Override @Override
public <R,S> R accept(Type.Visitor<R,S> v, S s) { public <R,S> R accept(Type.Visitor<R,S> v, S s) {
return v.visitClassType(this, s); return v.visitClassType(this, s);
@ -680,7 +767,7 @@ public class Type implements PrimitiveType {
*/ */
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) { if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
buf.append(getEnclosingType().toString()); buf.append(getEnclosingType().toString());
buf.append("."); buf.append(".");
buf.append(className(tsym, false)); buf.append(className(tsym, false));
@ -765,6 +852,16 @@ public class Type implements PrimitiveType {
// optimization, was: allparams().nonEmpty(); // optimization, was: allparams().nonEmpty();
} }
@Override
public boolean isReference() {
return true;
}
@Override
public boolean isNullOrReference() {
return true;
}
/** A cache for the rank. */ /** A cache for the rank. */
int rank_field = -1; int rank_field = -1;
@ -909,11 +1006,15 @@ public class Type implements PrimitiveType {
public Type elemtype; public Type elemtype;
public ArrayType(Type elemtype, TypeSymbol arrayClass) { public ArrayType(Type elemtype, TypeSymbol arrayClass) {
super(ARRAY, arrayClass); super(arrayClass);
this.elemtype = elemtype; this.elemtype = elemtype;
} }
@Override @Override
public TypeTag getTag() {
return ARRAY;
}
public <R,S> R accept(Type.Visitor<R,S> v, S s) { public <R,S> R accept(Type.Visitor<R,S> v, S s) {
return v.visitArrayType(this, s); return v.visitArrayType(this, s);
} }
@ -947,6 +1048,16 @@ public class Type implements PrimitiveType {
return elemtype.isParameterized(); return elemtype.isParameterized();
} }
@Override
public boolean isReference() {
return true;
}
@Override
public boolean isNullOrReference() {
return true;
}
public boolean isRaw() { public boolean isRaw() {
return elemtype.isRaw(); return elemtype.isRaw();
} }
@ -1001,13 +1112,17 @@ public class Type implements PrimitiveType {
Type restype, Type restype,
List<Type> thrown, List<Type> thrown,
TypeSymbol methodClass) { TypeSymbol methodClass) {
super(METHOD, methodClass); super(methodClass);
this.argtypes = argtypes; this.argtypes = argtypes;
this.restype = restype; this.restype = restype;
this.thrown = thrown; this.thrown = thrown;
} }
@Override @Override
public TypeTag getTag() {
return METHOD;
}
public <R,S> R accept(Type.Visitor<R,S> v, S s) { public <R,S> R accept(Type.Visitor<R,S> v, S s) {
return v.visitMethodType(this, s); return v.visitMethodType(this, s);
} }
@ -1077,7 +1192,12 @@ public class Type implements PrimitiveType {
public static class PackageType extends Type implements NoType { public static class PackageType extends Type implements NoType {
PackageType(TypeSymbol tsym) { PackageType(TypeSymbol tsym) {
super(PACKAGE, tsym); super(tsym);
}
@Override
public TypeTag getTag() {
return PACKAGE;
} }
@Override @Override
@ -1120,17 +1240,22 @@ public class Type implements PrimitiveType {
public Type lower; public Type lower;
public TypeVar(Name name, Symbol owner, Type lower) { public TypeVar(Name name, Symbol owner, Type lower) {
super(TYPEVAR, null); super(null);
tsym = new TypeVariableSymbol(0, name, this, owner); tsym = new TypeVariableSymbol(0, name, this, owner);
this.lower = lower; this.lower = lower;
} }
public TypeVar(TypeSymbol tsym, Type bound, Type lower) { public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
super(TYPEVAR, tsym); super(tsym);
this.bound = bound; this.bound = bound;
this.lower = lower; this.lower = lower;
} }
@Override
public TypeTag getTag() {
return TYPEVAR;
}
@Override @Override
public <R,S> R accept(Type.Visitor<R,S> v, S s) { public <R,S> R accept(Type.Visitor<R,S> v, S s) {
return v.visitTypeVar(this, s); return v.visitTypeVar(this, s);
@ -1138,8 +1263,9 @@ public class Type implements PrimitiveType {
@Override @Override
public Type getUpperBound() { public Type getUpperBound() {
if ((bound == null || bound.tag == NONE) && this != tsym.type) if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
bound = tsym.type.getUpperBound(); bound = tsym.type.getUpperBound();
}
return bound; return bound;
} }
@ -1158,6 +1284,17 @@ public class Type implements PrimitiveType {
return false; return false;
} }
@Override
public boolean isReference() {
return true;
}
@Override
public boolean isNullOrReference() {
return true;
}
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) { public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitTypeVariable(this, p); return v.visitTypeVariable(this, p);
} }
@ -1203,10 +1340,13 @@ public class Type implements PrimitiveType {
public static abstract class DelegatedType extends Type { public static abstract class DelegatedType extends Type {
public Type qtype; public Type qtype;
public TypeTag tag;
public DelegatedType(TypeTag tag, Type qtype) { public DelegatedType(TypeTag tag, Type qtype) {
super(tag, qtype.tsym); super(qtype.tsym);
this.tag = tag;
this.qtype = qtype; this.qtype = qtype;
} }
public TypeTag getTag() { return tag; }
public String toString() { return qtype.toString(); } public String toString() { return qtype.toString(); }
public List<Type> getTypeArguments() { return qtype.getTypeArguments(); } public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
public Type getEnclosingType() { return qtype.getEnclosingType(); } public Type getEnclosingType() { return qtype.getEnclosingType(); }
@ -1340,6 +1480,12 @@ public class Type implements PrimitiveType {
else return qtype + "?"; else return qtype + "?";
} }
@Override
public boolean isPartial() {
return true;
}
@Override
public Type baseType() { public Type baseType() {
if (inst != null) return inst.baseType(); if (inst != null) return inst.baseType();
else return this; else return this;
@ -1439,21 +1585,21 @@ public class Type implements PrimitiveType {
} }
} }
/** Represents VOID or NONE. /** Represents NONE.
*/ */
static class JCNoType extends Type implements NoType { public static class JCNoType extends Type implements NoType {
public JCNoType(TypeTag tag) { public JCNoType() {
super(tag, null); super(null);
}
@Override
public TypeTag getTag() {
return NONE;
} }
@Override @Override
public TypeKind getKind() { public TypeKind getKind() {
switch (tag) { return TypeKind.NONE;
case VOID: return TypeKind.VOID;
case NONE: return TypeKind.NONE;
default:
throw new AssertionError("Unexpected tag: " + tag);
}
} }
@Override @Override
@ -1462,9 +1608,43 @@ public class Type implements PrimitiveType {
} }
} }
/** Represents VOID.
*/
public static class JCVoidType extends Type implements NoType {
public JCVoidType() {
super(null);
}
@Override
public TypeTag getTag() {
return VOID;
}
@Override
public TypeKind getKind() {
return TypeKind.VOID;
}
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitNoType(this, p);
}
@Override
public boolean isPrimitiveOrVoid() {
return true;
}
}
static class BottomType extends Type implements NullType { static class BottomType extends Type implements NullType {
public BottomType() { public BottomType() {
super(BOT, null); super(null);
}
@Override
public TypeTag getTag() {
return BOT;
} }
@Override @Override
@ -1486,6 +1666,12 @@ public class Type implements PrimitiveType {
public String stringValue() { public String stringValue() {
return "null"; return "null";
} }
@Override
public boolean isNullOrReference() {
return true;
}
} }
public static class ErrorType extends ClassType public static class ErrorType extends ClassType
@ -1495,7 +1681,6 @@ public class Type implements PrimitiveType {
public ErrorType(Type originalType, TypeSymbol tsym) { public ErrorType(Type originalType, TypeSymbol tsym) {
super(noType, List.<Type>nil(), null); super(noType, List.<Type>nil(), null);
tag = ERROR;
this.tsym = tsym; this.tsym = tsym;
this.originalType = (originalType == null ? noType : originalType); this.originalType = (originalType == null ? noType : originalType);
} }
@ -1507,6 +1692,26 @@ public class Type implements PrimitiveType {
c.members_field = new Scope.ErrorScope(c); c.members_field = new Scope.ErrorScope(c);
} }
@Override
public TypeTag getTag() {
return ERROR;
}
@Override
public boolean isPartial() {
return true;
}
@Override
public boolean isReference() {
return true;
}
@Override
public boolean isNullOrReference() {
return true;
}
public ErrorType(Name name, TypeSymbol container, Type originalType) { public ErrorType(Name name, TypeSymbol container, Type originalType) {
this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType); this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
} }
@ -1559,7 +1764,7 @@ public class Type implements PrimitiveType {
public Type underlyingType; public Type underlyingType;
public AnnotatedType(Type underlyingType) { public AnnotatedType(Type underlyingType) {
super(underlyingType.tag, underlyingType.tsym); super(underlyingType.tsym);
this.typeAnnotations = List.nil(); this.typeAnnotations = List.nil();
this.underlyingType = underlyingType; this.underlyingType = underlyingType;
Assert.check(!underlyingType.isAnnotated(), Assert.check(!underlyingType.isAnnotated(),
@ -1568,7 +1773,7 @@ public class Type implements PrimitiveType {
public AnnotatedType(List<Attribute.TypeCompound> typeAnnotations, public AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
Type underlyingType) { Type underlyingType) {
super(underlyingType.tag, underlyingType.tsym); super(underlyingType.tsym);
this.typeAnnotations = typeAnnotations; this.typeAnnotations = typeAnnotations;
this.underlyingType = underlyingType; this.underlyingType = underlyingType;
Assert.check(!underlyingType.isAnnotated(), Assert.check(!underlyingType.isAnnotated(),
@ -1576,6 +1781,11 @@ public class Type implements PrimitiveType {
"; adding: " + typeAnnotations); "; adding: " + typeAnnotations);
} }
@Override
public TypeTag getTag() {
return underlyingType.getTag();
}
@Override @Override
public boolean isAnnotated() { public boolean isAnnotated() {
return true; return true;
@ -1651,10 +1861,18 @@ public class Type implements PrimitiveType {
@Override @Override
public List<Type> allparams() { return underlyingType.allparams(); } public List<Type> allparams() { return underlyingType.allparams(); }
@Override @Override
public boolean isPrimitive() { return underlyingType.isPrimitive(); }
@Override
public boolean isPrimitiveOrVoid() { return underlyingType.isPrimitiveOrVoid(); }
@Override
public boolean isNumeric() { return underlyingType.isNumeric(); } public boolean isNumeric() { return underlyingType.isNumeric(); }
@Override @Override
public boolean isReference() { return underlyingType.isReference(); } public boolean isReference() { return underlyingType.isReference(); }
@Override @Override
public boolean isNullOrReference() { return underlyingType.isNullOrReference(); }
@Override
public boolean isPartial() { return underlyingType.isPartial(); }
@Override
public boolean isParameterized() { return underlyingType.isParameterized(); } public boolean isParameterized() { return underlyingType.isParameterized(); }
@Override @Override
public boolean isRaw() { return underlyingType.isRaw(); } public boolean isRaw() { return underlyingType.isRaw(); }
@ -1719,6 +1937,28 @@ public class Type implements PrimitiveType {
public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); } public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); }
} }
public static class UnknownType extends Type {
public UnknownType() {
super(null);
}
@Override
public TypeTag getTag() {
return UNKNOWN;
}
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitUnknown(this, p);
}
@Override
public boolean isPartial() {
return true;
}
}
/** /**
* A visitor for types. A visitor is used to implement operations * A visitor for types. A visitor is used to implement operations
* (or relations) on types. Most common operations on types are * (or relations) on types. Most common operations on types are

View file

@ -42,132 +42,107 @@ import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
public enum TypeTag { public enum TypeTag {
/** The tag of the basic type `byte'. /** The tag of the basic type `byte'.
*/ */
BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, true),
TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
/** The tag of the basic type `char'. /** The tag of the basic type `char'.
*/ */
CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, true),
TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
/** The tag of the basic type `short'. /** The tag of the basic type `short'.
*/ */
SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, true),
TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
/** The tag of the basic type `int'.
*/
INT(INT_CLASS, INT_SUPERCLASSES,
TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
/** The tag of the basic type `long'. /** The tag of the basic type `long'.
*/ */
LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), LONG(LONG_CLASS, LONG_SUPERCLASSES, true),
/** The tag of the basic type `float'. /** The tag of the basic type `float'.
*/ */
FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, true),
/** The tag of the basic type `int'.
*/
INT(INT_CLASS, INT_SUPERCLASSES, true),
/** The tag of the basic type `double'. /** The tag of the basic type `double'.
*/ */
DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, true),
/** The tag of the basic type `boolean'. /** The tag of the basic type `boolean'.
*/ */
BOOLEAN(TypeTagKind.PRIMITIVE), BOOLEAN(0, 0, true),
/** The tag of the type `void'. /** The tag of the type `void'.
*/ */
VOID(TypeTagKind.VOID), VOID,
/** The tag of all class and interface types. /** The tag of all class and interface types.
*/ */
CLASS(TypeTagKind.REFERENCE), CLASS,
/** The tag of all array types. /** The tag of all array types.
*/ */
ARRAY(TypeTagKind.REFERENCE), ARRAY,
/** The tag of all (monomorphic) method types. /** The tag of all (monomorphic) method types.
*/ */
METHOD(TypeTagKind.OTHER), METHOD,
/** The tag of all package "types". /** The tag of all package "types".
*/ */
PACKAGE(TypeTagKind.OTHER), PACKAGE,
/** The tag of all (source-level) type variables. /** The tag of all (source-level) type variables.
*/ */
TYPEVAR(TypeTagKind.REFERENCE), TYPEVAR,
/** The tag of all type arguments. /** The tag of all type arguments.
*/ */
WILDCARD(TypeTagKind.REFERENCE), WILDCARD,
/** The tag of all polymorphic (method-) types. /** The tag of all polymorphic (method-) types.
*/ */
FORALL(TypeTagKind.OTHER), FORALL,
/** The tag of deferred expression types in method context /** The tag of deferred expression types in method context
*/ */
DEFERRED(TypeTagKind.OTHER), DEFERRED,
/** The tag of the bottom type {@code <null>}. /** The tag of the bottom type {@code <null>}.
*/ */
BOT(TypeTagKind.OTHER), BOT,
/** The tag of a missing type. /** The tag of a missing type.
*/ */
NONE(TypeTagKind.OTHER), NONE,
/** The tag of the error type. /** The tag of the error type.
*/ */
ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL), ERROR,
/** The tag of an unknown type /** The tag of an unknown type
*/ */
UNKNOWN(TypeTagKind.PARTIAL), UNKNOWN,
/** The tag of all instantiatable type variables. /** The tag of all instantiatable type variables.
*/ */
UNDETVAR(TypeTagKind.PARTIAL), UNDETVAR,
/** Pseudo-types, these are special tags /** Pseudo-types, these are special tags
*/ */
UNINITIALIZED_THIS(TypeTagKind.OTHER), UNINITIALIZED_THIS,
UNINITIALIZED_OBJECT(TypeTagKind.OTHER); UNINITIALIZED_OBJECT;
final boolean isPrimitive;
final boolean isNumeric;
final boolean isPartial;
final boolean isReference;
final boolean isPrimitiveOrVoid;
final int superClasses; final int superClasses;
final int numericClass; final int numericClass;
final boolean isPrimitive;
private TypeTag(int kind) { private TypeTag() {
this(0, 0, kind); this(0, 0, false);
} }
private TypeTag(int numericClass, int superClasses, int kind) { private TypeTag(int numericClass, int superClasses, boolean isPrimitive) {
isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0; this.superClasses = superClasses;
isNumeric = (kind & TypeTagKind.NUMERIC) != 0; this.numericClass = numericClass;
isPartial = (kind & TypeTagKind.PARTIAL) != 0; this.isPrimitive = isPrimitive;
isReference = (kind & TypeTagKind.REFERENCE) != 0;
isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) ||
((kind & TypeTagKind.VOID) != 0);
this.superClasses = superClasses;
this.numericClass = numericClass;
}
static class TypeTagKind {
static final int PRIMITIVE = 1;
static final int NUMERIC = 2;
static final int REFERENCE = 4;
static final int PARTIAL = 8;
static final int OTHER = 16;
static final int VOID = 32;
} }
public static class NumericClasses { public static class NumericClasses {
@ -261,4 +236,5 @@ public enum TypeTag {
throw new AssertionError("unknown primitive type " + this); throw new AssertionError("unknown primitive type " + this);
} }
} }
} }

View file

@ -286,8 +286,9 @@ public class Types {
* conversion to s? * conversion to s?
*/ */
public boolean isConvertible(Type t, Type s, Warner warn) { public boolean isConvertible(Type t, Type s, Warner warn) {
if (t.tag == ERROR) if (t.hasTag(ERROR)) {
return true; return true;
}
boolean tPrimitive = t.isPrimitive(); boolean tPrimitive = t.isPrimitive();
boolean sPrimitive = s.isPrimitive(); boolean sPrimitive = s.isPrimitive();
if (tPrimitive == sPrimitive) { if (tPrimitive == sPrimitive) {
@ -396,7 +397,8 @@ public class Types {
/** /**
* Compute the function descriptor associated with a given functional interface * Compute the function descriptor associated with a given functional interface
*/ */
public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { public FunctionDescriptor findDescriptorInternal(TypeSymbol origin,
CompoundScope membersCache) throws FunctionDescriptorLookupError {
if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
//t must be an interface //t must be an interface
throw failure("not.a.functional.intf", origin); throw failure("not.a.functional.intf", origin);
@ -655,17 +657,16 @@ public class Types {
} }
} else if (isSubtype(t, s)) { } else if (isSubtype(t, s)) {
return true; return true;
} } else if (t.hasTag(TYPEVAR)) {
else if (t.tag == TYPEVAR) {
return isSubtypeUnchecked(t.getUpperBound(), s, warn); return isSubtypeUnchecked(t.getUpperBound(), s, warn);
} } else if (!s.isRaw()) {
else if (!s.isRaw()) {
Type t2 = asSuper(t, s.tsym); Type t2 = asSuper(t, s.tsym);
if (t2 != null && t2.isRaw()) { if (t2 != null && t2.isRaw()) {
if (isReifiable(s)) if (isReifiable(s)) {
warn.silentWarn(LintCategory.UNCHECKED); warn.silentWarn(LintCategory.UNCHECKED);
else } else {
warn.warn(LintCategory.UNCHECKED); warn.warn(LintCategory.UNCHECKED);
}
return true; return true;
} }
} }
@ -673,13 +674,14 @@ public class Types {
} }
private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
if (t.tag != ARRAY || isReifiable(t)) if (!t.hasTag(ARRAY) || isReifiable(t)) {
return; return;
}
t = t.unannotatedType(); t = t.unannotatedType();
s = s.unannotatedType(); s = s.unannotatedType();
ArrayType from = (ArrayType)t; ArrayType from = (ArrayType)t;
boolean shouldWarn = false; boolean shouldWarn = false;
switch (s.tag) { switch (s.getTag()) {
case ARRAY: case ARRAY:
ArrayType to = (ArrayType)s; ArrayType to = (ArrayType)s;
shouldWarn = from.isVarargs() && shouldWarn = from.isVarargs() &&
@ -735,8 +737,9 @@ public class Types {
// where // where
private TypeRelation isSubtype = new TypeRelation() private TypeRelation isSubtype = new TypeRelation()
{ {
@Override
public Boolean visitType(Type t, Type s) { public Boolean visitType(Type t, Type s) {
switch (t.tag) { switch (t.getTag()) {
case BYTE: case BYTE:
return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag())); return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
case CHAR: case CHAR:
@ -756,7 +759,7 @@ public class Types {
case NONE: case NONE:
return false; return false;
default: default:
throw new AssertionError("isSubtype " + t.tag); throw new AssertionError("isSubtype " + t.getTag());
} }
} }
@ -826,14 +829,14 @@ public class Types {
@Override @Override
public Boolean visitArrayType(ArrayType t, Type s) { public Boolean visitArrayType(ArrayType t, Type s) {
if (s.tag == ARRAY) { if (s.hasTag(ARRAY)) {
if (t.elemtype.isPrimitive()) if (t.elemtype.isPrimitive())
return isSameType(t.elemtype, elemtype(s)); return isSameType(t.elemtype, elemtype(s));
else else
return isSubtypeNoCapture(t.elemtype, elemtype(s)); return isSubtypeNoCapture(t.elemtype, elemtype(s));
} }
if (s.tag == CLASS) { if (s.hasTag(CLASS)) {
Name sname = s.tsym.getQualifiedName(); Name sname = s.tsym.getQualifiedName();
return sname == names.java_lang_Object return sname == names.java_lang_Object
|| sname == names.java_lang_Cloneable || sname == names.java_lang_Cloneable
@ -846,9 +849,9 @@ public class Types {
@Override @Override
public Boolean visitUndetVar(UndetVar t, Type s) { public Boolean visitUndetVar(UndetVar t, Type s) {
//todo: test against origin needed? or replace with substitution? //todo: test against origin needed? or replace with substitution?
if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) { if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
return true; return true;
} else if (s.tag == BOT) { } else if (s.hasTag(BOT)) {
//if 's' is 'null' there's no instantiated type U for which //if 's' is 'null' there's no instantiated type U for which
//U <: s (but 'null' itself, which is not a valid type) //U <: s (but 'null' itself, which is not a valid type)
return false; return false;
@ -913,15 +916,17 @@ public class Types {
* Is t a supertype of s? * Is t a supertype of s?
*/ */
public boolean isSuperType(Type t, Type s) { public boolean isSuperType(Type t, Type s) {
switch (t.tag) { switch (t.getTag()) {
case ERROR: case ERROR:
return true; return true;
case UNDETVAR: { case UNDETVAR: {
UndetVar undet = (UndetVar)t; UndetVar undet = (UndetVar)t;
if (t == s || if (t == s ||
undet.qtype == s || undet.qtype == s ||
s.tag == ERROR || s.hasTag(ERROR) ||
s.tag == BOT) return true; s.hasTag(BOT)) {
return true;
}
undet.addBound(InferenceBound.LOWER, s, this); undet.addBound(InferenceBound.LOWER, s, this);
return true; return true;
} }
@ -990,12 +995,12 @@ public class Types {
if (s.isPartial()) if (s.isPartial())
return visit(s, t); return visit(s, t);
switch (t.tag) { switch (t.getTag()) {
case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
return t.tag == s.tag; return t.hasTag(s.getTag());
case TYPEVAR: { case TYPEVAR: {
if (s.tag == TYPEVAR) { if (s.hasTag(TYPEVAR)) {
//type-substitution does not preserve type-var types //type-substitution does not preserve type-var types
//check that type var symbols and bounds are indeed the same //check that type var symbols and bounds are indeed the same
return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType()); return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
@ -1009,7 +1014,7 @@ public class Types {
} }
} }
default: default:
throw new AssertionError("isSameType " + t.tag); throw new AssertionError("isSameType " + t.getTag());
} }
} }
@ -1080,8 +1085,9 @@ public class Types {
@Override @Override
public Boolean visitForAll(ForAll t, Type s) { public Boolean visitForAll(ForAll t, Type s) {
if (s.tag != FORALL) if (!s.hasTag(FORALL)) {
return false; return false;
}
ForAll forAll = (ForAll)s; ForAll forAll = (ForAll)s;
return hasSameBounds(t, forAll) return hasSameBounds(t, forAll)
@ -1090,12 +1096,14 @@ public class Types {
@Override @Override
public Boolean visitUndetVar(UndetVar t, Type s) { public Boolean visitUndetVar(UndetVar t, Type s) {
if (s.tag == WILDCARD) if (s.hasTag(WILDCARD)) {
// FIXME, this might be leftovers from before capture conversion // FIXME, this might be leftovers from before capture conversion
return false; return false;
}
if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
return true; return true;
}
t.addBound(InferenceBound.EQ, s, Types.this); t.addBound(InferenceBound.EQ, s, Types.this);
@ -1171,9 +1179,9 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="Contains Type"> // <editor-fold defaultstate="collapsed" desc="Contains Type">
public boolean containedBy(Type t, Type s) { public boolean containedBy(Type t, Type s) {
switch (t.tag) { switch (t.getTag()) {
case UNDETVAR: case UNDETVAR:
if (s.tag == WILDCARD) { if (s.hasTag(WILDCARD)) {
UndetVar undetvar = (UndetVar)t; UndetVar undetvar = (UndetVar)t;
WildcardType wt = (WildcardType)s.unannotatedType(); WildcardType wt = (WildcardType)s.unannotatedType();
switch(wt.kind) { switch(wt.kind) {
@ -1241,7 +1249,7 @@ public class Types {
private TypeRelation containsType = new TypeRelation() { private TypeRelation containsType = new TypeRelation() {
private Type U(Type t) { private Type U(Type t) {
while (t.tag == WILDCARD) { while (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType)t.unannotatedType(); WildcardType w = (WildcardType)t.unannotatedType();
if (w.isSuperBound()) if (w.isSuperBound())
return w.bound == null ? syms.objectType : w.bound.bound; return w.bound == null ? syms.objectType : w.bound.bound;
@ -1252,7 +1260,7 @@ public class Types {
} }
private Type L(Type t) { private Type L(Type t) {
while (t.tag == WILDCARD) { while (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType)t.unannotatedType(); WildcardType w = (WildcardType)t.unannotatedType();
if (w.isExtendsBound()) if (w.isExtendsBound())
return syms.botType; return syms.botType;
@ -1298,10 +1306,11 @@ public class Types {
@Override @Override
public Boolean visitUndetVar(UndetVar t, Type s) { public Boolean visitUndetVar(UndetVar t, Type s) {
if (s.tag != WILDCARD) if (!s.hasTag(WILDCARD)) {
return isSameType(t, s); return isSameType(t, s);
else } else {
return false; return false;
}
} }
@Override @Override
@ -1311,13 +1320,13 @@ public class Types {
}; };
public boolean isCaptureOf(Type s, WildcardType t) { public boolean isCaptureOf(Type s, WildcardType t) {
if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured()) if (!s.hasTag(TYPEVAR) || !((TypeVar)s.unannotatedType()).isCaptured())
return false; return false;
return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard); return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
} }
public boolean isSameWildcard(WildcardType t, Type s) { public boolean isSameWildcard(WildcardType t, Type s) {
if (s.tag != WILDCARD) if (!s.hasTag(WILDCARD))
return false; return false;
WildcardType w = (WildcardType)s.unannotatedType(); WildcardType w = (WildcardType)s.unannotatedType();
return w.kind == t.kind && w.type == t.type; return w.kind == t.kind && w.type == t.type;
@ -1369,15 +1378,15 @@ public class Types {
private TypeRelation isCastable = new TypeRelation() { private TypeRelation isCastable = new TypeRelation() {
public Boolean visitType(Type t, Type s) { public Boolean visitType(Type t, Type s) {
if (s.tag == ERROR) if (s.hasTag(ERROR))
return true; return true;
switch (t.tag) { switch (t.getTag()) {
case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case DOUBLE:
return s.isNumeric(); return s.isNumeric();
case BOOLEAN: case BOOLEAN:
return s.tag == BOOLEAN; return s.hasTag(BOOLEAN);
case VOID: case VOID:
return false; return false;
case BOT: case BOT:
@ -1394,10 +1403,10 @@ public class Types {
@Override @Override
public Boolean visitClassType(ClassType t, Type s) { public Boolean visitClassType(ClassType t, Type s) {
if (s.tag == ERROR || s.tag == BOT) if (s.hasTag(ERROR) || s.hasTag(BOT))
return true; return true;
if (s.tag == TYPEVAR) { if (s.hasTag(TYPEVAR)) {
if (isCastable(t, s.getUpperBound(), noWarnings)) { if (isCastable(t, s.getUpperBound(), noWarnings)) {
warnStack.head.warn(LintCategory.UNCHECKED); warnStack.head.warn(LintCategory.UNCHECKED);
return true; return true;
@ -1412,11 +1421,11 @@ public class Types {
visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false); visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
} }
if (s.tag == CLASS || s.tag == ARRAY) { if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
boolean upcast; boolean upcast;
if ((upcast = isSubtype(erasure(t), erasure(s))) if ((upcast = isSubtype(erasure(t), erasure(s)))
|| isSubtype(erasure(s), erasure(t))) { || isSubtype(erasure(s), erasure(t))) {
if (!upcast && s.tag == ARRAY) { if (!upcast && s.hasTag(ARRAY)) {
if (!isReifiable(s)) if (!isReifiable(s))
warnStack.head.warn(LintCategory.UNCHECKED); warnStack.head.warn(LintCategory.UNCHECKED);
return true; return true;
@ -1469,7 +1478,7 @@ public class Types {
} }
// Sidecast // Sidecast
if (s.tag == CLASS) { if (s.hasTag(CLASS)) {
if ((s.tsym.flags() & INTERFACE) != 0) { if ((s.tsym.flags() & INTERFACE) != 0) {
return ((t.tsym.flags() & FINAL) == 0) return ((t.tsym.flags() & FINAL) == 0)
? sideCast(t, s, warnStack.head) ? sideCast(t, s, warnStack.head)
@ -1501,7 +1510,7 @@ public class Types {
@Override @Override
public Boolean visitArrayType(ArrayType t, Type s) { public Boolean visitArrayType(ArrayType t, Type s) {
switch (s.tag) { switch (s.getTag()) {
case ERROR: case ERROR:
case BOT: case BOT:
return true; return true;
@ -1516,7 +1525,7 @@ public class Types {
return isSubtype(t, s); return isSubtype(t, s);
case ARRAY: case ARRAY:
if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) { if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
return elemtype(t).tag == elemtype(s).tag; return elemtype(t).hasTag(elemtype(s).getTag());
} else { } else {
return visit(elemtype(t), elemtype(s)); return visit(elemtype(t), elemtype(s));
} }
@ -1527,7 +1536,7 @@ public class Types {
@Override @Override
public Boolean visitTypeVar(TypeVar t, Type s) { public Boolean visitTypeVar(TypeVar t, Type s) {
switch (s.tag) { switch (s.getTag()) {
case ERROR: case ERROR:
case BOT: case BOT:
return true; return true;
@ -1579,8 +1588,9 @@ public class Types {
private Set<TypePair> cache = new HashSet<TypePair>(); private Set<TypePair> cache = new HashSet<TypePair>();
@Override
public Boolean visitType(Type t, Type s) { public Boolean visitType(Type t, Type s) {
if (s.tag == WILDCARD) if (s.hasTag(WILDCARD))
return visit(s, t); return visit(s, t);
else else
return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t); return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
@ -1617,10 +1627,10 @@ public class Types {
if (t.isUnbound()) if (t.isUnbound())
return false; return false;
if (s.tag != WILDCARD) { if (!s.hasTag(WILDCARD)) {
if (t.isExtendsBound()) if (t.isExtendsBound())
return notSoftSubtypeRecursive(s, t.type); return notSoftSubtypeRecursive(s, t.type);
else // isSuperBound() else
return notSoftSubtypeRecursive(t.type, s); return notSoftSubtypeRecursive(t.type, s);
} }
@ -1669,21 +1679,21 @@ public class Types {
*/ */
public boolean notSoftSubtype(Type t, Type s) { public boolean notSoftSubtype(Type t, Type s) {
if (t == s) return false; if (t == s) return false;
if (t.tag == TYPEVAR) { if (t.hasTag(TYPEVAR)) {
TypeVar tv = (TypeVar) t; TypeVar tv = (TypeVar) t;
return !isCastable(tv.bound, return !isCastable(tv.bound,
relaxBound(s), relaxBound(s),
noWarnings); noWarnings);
} }
if (s.tag != WILDCARD) if (!s.hasTag(WILDCARD))
s = upperBound(s); s = upperBound(s);
return !isSubtype(t, relaxBound(s)); return !isSubtype(t, relaxBound(s));
} }
private Type relaxBound(Type t) { private Type relaxBound(Type t) {
if (t.tag == TYPEVAR) { if (t.hasTag(TYPEVAR)) {
while (t.tag == TYPEVAR) while (t.hasTag(TYPEVAR))
t = t.getUpperBound(); t = t.getUpperBound();
t = rewriteQuantifiers(t, true, true); t = rewriteQuantifiers(t, true, true);
} }
@ -1732,16 +1742,16 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="Array Utils"> // <editor-fold defaultstate="collapsed" desc="Array Utils">
public boolean isArray(Type t) { public boolean isArray(Type t) {
while (t.tag == WILDCARD) while (t.hasTag(WILDCARD))
t = upperBound(t); t = upperBound(t);
return t.tag == ARRAY; return t.hasTag(ARRAY);
} }
/** /**
* The element type of an array. * The element type of an array.
*/ */
public Type elemtype(Type t) { public Type elemtype(Type t) {
switch (t.tag) { switch (t.getTag()) {
case WILDCARD: case WILDCARD:
return elemtype(upperBound(t)); return elemtype(upperBound(t));
case ARRAY: case ARRAY:
@ -1775,7 +1785,7 @@ public class Types {
*/ */
public int dimensions(Type t) { public int dimensions(Type t) {
int result = 0; int result = 0;
while (t.tag == ARRAY) { while (t.hasTag(ARRAY)) {
result++; result++;
t = elemtype(t); t = elemtype(t);
} }
@ -1789,8 +1799,7 @@ public class Types {
* @return the ArrayType for the given component * @return the ArrayType for the given component
*/ */
public ArrayType makeArrayType(Type t) { public ArrayType makeArrayType(Type t) {
if (t.tag == VOID || if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
t.tag == PACKAGE) {
Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString()); Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
} }
return new ArrayType(t, syms.arrayClass); return new ArrayType(t, syms.arrayClass);
@ -1821,7 +1830,7 @@ public class Types {
return t; return t;
Type st = supertype(t); Type st = supertype(t);
if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) { if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) {
Type x = asSuper(st, sym); Type x = asSuper(st, sym);
if (x != null) if (x != null)
return x; return x;
@ -1863,13 +1872,13 @@ public class Types {
* @param sym a symbol * @param sym a symbol
*/ */
public Type asOuterSuper(Type t, Symbol sym) { public Type asOuterSuper(Type t, Symbol sym) {
switch (t.tag) { switch (t.getTag()) {
case CLASS: case CLASS:
do { do {
Type s = asSuper(t, sym); Type s = asSuper(t, sym);
if (s != null) return s; if (s != null) return s;
t = t.getEnclosingType(); t = t.getEnclosingType();
} while (t.tag == CLASS); } while (t.hasTag(CLASS));
return null; return null;
case ARRAY: case ARRAY:
return isSubtype(t, sym.type) ? sym.type : null; return isSubtype(t, sym.type) ? sym.type : null;
@ -1890,16 +1899,16 @@ public class Types {
* @param sym a symbol * @param sym a symbol
*/ */
public Type asEnclosingSuper(Type t, Symbol sym) { public Type asEnclosingSuper(Type t, Symbol sym) {
switch (t.tag) { switch (t.getTag()) {
case CLASS: case CLASS:
do { do {
Type s = asSuper(t, sym); Type s = asSuper(t, sym);
if (s != null) return s; if (s != null) return s;
Type outer = t.getEnclosingType(); Type outer = t.getEnclosingType();
t = (outer.tag == CLASS) ? outer : t = (outer.hasTag(CLASS)) ? outer :
(t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type : (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
Type.noType; Type.noType;
} while (t.tag == CLASS); } while (t.hasTag(CLASS));
return null; return null;
case ARRAY: case ARRAY:
return isSubtype(t, sym.type) ? sym.type : null; return isSubtype(t, sym.type) ? sym.type : null;
@ -1987,11 +1996,11 @@ public class Types {
* (not defined for Method and ForAll types) * (not defined for Method and ForAll types)
*/ */
public boolean isAssignable(Type t, Type s, Warner warn) { public boolean isAssignable(Type t, Type s, Warner warn) {
if (t.tag == ERROR) if (t.hasTag(ERROR))
return true; return true;
if (t.tag.isSubRangeOf(INT) && t.constValue() != null) { if (t.getTag().isSubRangeOf(INT) && t.constValue() != null) {
int value = ((Number)t.constValue()).intValue(); int value = ((Number)t.constValue()).intValue();
switch (s.tag) { switch (s.getTag()) {
case BYTE: case BYTE:
if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE) if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
return true; return true;
@ -2007,7 +2016,7 @@ public class Types {
case INT: case INT:
return true; return true;
case CLASS: case CLASS:
switch (unboxedType(s).tag) { switch (unboxedType(s).getTag()) {
case BYTE: case BYTE:
case CHAR: case CHAR:
case SHORT: case SHORT:
@ -2135,7 +2144,7 @@ public class Types {
null, null,
syms.noSymbol); syms.noSymbol);
bc.type = new IntersectionClassType(bounds, bc, allInterfaces); bc.type = new IntersectionClassType(bounds, bc, allInterfaces);
bc.erasure_field = (bounds.head.tag == TYPEVAR) ? bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
syms.objectType : // error condition, recover syms.objectType : // error condition, recover
erasure(firstExplicitBound); erasure(firstExplicitBound);
bc.members_field = new Scope(bc); bc.members_field = new Scope(bc);
@ -2198,7 +2207,7 @@ public class Types {
*/ */
@Override @Override
public Type visitTypeVar(TypeVar t, Void ignored) { public Type visitTypeVar(TypeVar t, Void ignored) {
if (t.bound.tag == TYPEVAR || if (t.bound.hasTag(TYPEVAR) ||
(!t.bound.isCompound() && !t.bound.isInterface())) { (!t.bound.isCompound() && !t.bound.isInterface())) {
return t.bound; return t.bound;
} else { } else {
@ -2502,8 +2511,8 @@ public class Types {
} }
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) { for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
while (t.tag == TYPEVAR) while (t.hasTag(TYPEVAR))
t = t.getUpperBound(); t = t.getUpperBound();
TypeSymbol c = t.tsym; TypeSymbol c = t.tsym;
for (Scope.Entry e = c.members().lookup(ms.name, implFilter); for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
@ -2684,13 +2693,13 @@ public class Types {
@Override @Override
public Boolean visitMethodType(MethodType t, Type s) { public Boolean visitMethodType(MethodType t, Type s) {
return s.tag == METHOD return s.hasTag(METHOD)
&& containsTypeEquivalent(t.argtypes, s.getParameterTypes()); && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
} }
@Override @Override
public Boolean visitForAll(ForAll t, Type s) { public Boolean visitForAll(ForAll t, Type s) {
if (s.tag != FORALL) if (!s.hasTag(FORALL))
return strict ? false : visitMethodType(t.asMethodType(), s); return strict ? false : visitMethodType(t.asMethodType(), s);
ForAll forAll = (ForAll)s; ForAll forAll = (ForAll)s;
@ -3025,7 +3034,7 @@ public class Types {
*/ */
public int rank(Type t) { public int rank(Type t) {
t = t.unannotatedType(); t = t.unannotatedType();
switch(t.tag) { switch(t.getTag()) {
case CLASS: { case CLASS: {
ClassType cls = (ClassType)t; ClassType cls = (ClassType)t;
if (cls.rank_field < 0) { if (cls.rank_field < 0) {
@ -3091,7 +3100,7 @@ public class Types {
*/ */
@Deprecated @Deprecated
public String toString(Type t) { public String toString(Type t) {
if (t.tag == FORALL) { if (t.hasTag(FORALL)) {
ForAll forAll = (ForAll)t; ForAll forAll = (ForAll)t;
return typaramsString(forAll.tvars) + forAll.qtype; return typaramsString(forAll.tvars) + forAll.qtype;
} }
@ -3157,9 +3166,9 @@ public class Types {
if (cl == null) { if (cl == null) {
Type st = supertype(t); Type st = supertype(t);
if (!t.isCompound()) { if (!t.isCompound()) {
if (st.tag == CLASS) { if (st.hasTag(CLASS)) {
cl = insert(closure(st), t); cl = insert(closure(st), t);
} else if (st.tag == TYPEVAR) { } else if (st.hasTag(TYPEVAR)) {
cl = closure(st).prepend(t); cl = closure(st).prepend(t);
} else { } else {
cl = List.of(t); cl = List.of(t);
@ -3219,7 +3228,7 @@ public class Types {
if (isSameType(cl1.head, cl2.head)) if (isSameType(cl1.head, cl2.head))
return intersect(cl1.tail, cl2.tail).prepend(cl1.head); return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
if (cl1.head.tsym == cl2.head.tsym && if (cl1.head.tsym == cl2.head.tsym &&
cl1.head.tag == CLASS && cl2.head.tag == CLASS) { cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) {
if (cl1.head.isParameterized() && cl2.head.isParameterized()) { if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
Type merge = merge(cl1.head,cl2.head); Type merge = merge(cl1.head,cl2.head);
return intersect(cl1.tail, cl2.tail).prepend(merge); return intersect(cl1.tail, cl2.tail).prepend(merge);
@ -3343,7 +3352,7 @@ public class Types {
final int CLASS_BOUND = 2; final int CLASS_BOUND = 2;
int boundkind = 0; int boundkind = 0;
for (Type t : ts) { for (Type t : ts) {
switch (t.tag) { switch (t.getTag()) {
case CLASS: case CLASS:
boundkind |= CLASS_BOUND; boundkind |= CLASS_BOUND;
break; break;
@ -3353,8 +3362,8 @@ public class Types {
case TYPEVAR: case TYPEVAR:
do { do {
t = t.getUpperBound(); t = t.getUpperBound();
} while (t.tag == TYPEVAR); } while (t.hasTag(TYPEVAR));
if (t.tag == ARRAY) { if (t.hasTag(ARRAY)) {
boundkind |= ARRAY_BOUND; boundkind |= ARRAY_BOUND;
} else { } else {
boundkind |= CLASS_BOUND; boundkind |= CLASS_BOUND;
@ -3394,13 +3403,14 @@ public class Types {
case CLASS_BOUND: case CLASS_BOUND:
// calculate lub(A, B) // calculate lub(A, B)
while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR) while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) {
ts = ts.tail; ts = ts.tail;
}
Assert.check(!ts.isEmpty()); Assert.check(!ts.isEmpty());
//step 1 - compute erased candidate set (EC) //step 1 - compute erased candidate set (EC)
List<Type> cl = erasedSupertypes(ts.head); List<Type> cl = erasedSupertypes(ts.head);
for (Type t : ts.tail) { for (Type t : ts.tail) {
if (t.tag == CLASS || t.tag == TYPEVAR) if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
cl = intersect(cl, erasedSupertypes(t)); cl = intersect(cl, erasedSupertypes(t));
} }
//step 2 - compute minimal erased candidate set (MEC) //step 2 - compute minimal erased candidate set (MEC)
@ -3422,7 +3432,7 @@ public class Types {
// calculate lub(A, B[]) // calculate lub(A, B[])
List<Type> classes = List.of(arraySuperType()); List<Type> classes = List.of(arraySuperType());
for (Type t : ts) { for (Type t : ts) {
if (t.tag != ARRAY) // Filter out any arrays if (!t.hasTag(ARRAY)) // Filter out any arrays
classes = classes.prepend(t); classes = classes.prepend(t);
} }
// lub(A, B[]) is lub(A, arraySuperType) // lub(A, B[]) is lub(A, arraySuperType)
@ -3433,7 +3443,7 @@ public class Types {
List<Type> erasedSupertypes(Type t) { List<Type> erasedSupertypes(Type t) {
ListBuffer<Type> buf = lb(); ListBuffer<Type> buf = lb();
for (Type sup : closure(t)) { for (Type sup : closure(t)) {
if (sup.tag == TYPEVAR) { if (sup.hasTag(TYPEVAR)) {
buf.append(sup); buf.append(sup);
} else { } else {
buf.append(erasure(sup)); buf.append(erasure(sup));
@ -3509,7 +3519,7 @@ public class Types {
private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() { private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
public Integer visitType(Type t, Void ignored) { public Integer visitType(Type t, Void ignored) {
return t.tag.ordinal(); return t.getTag().ordinal();
} }
@Override @Override
@ -3635,7 +3645,7 @@ public class Types {
* Return the class that boxes the given primitive. * Return the class that boxes the given primitive.
*/ */
public ClassSymbol boxedClass(Type t) { public ClassSymbol boxedClass(Type t) {
return reader.enterClass(syms.boxedName[t.tag.ordinal()]); return reader.enterClass(syms.boxedName[t.getTag().ordinal()]);
} }
/** /**
@ -3667,7 +3677,7 @@ public class Types {
*/ */
public Type unboxedTypeOrType(Type t) { public Type unboxedTypeOrType(Type t) {
Type unboxedType = unboxedType(t); Type unboxedType = unboxedType(t);
return unboxedType.tag == NONE ? t : unboxedType; return unboxedType.hasTag(NONE) ? t : unboxedType;
} }
// </editor-fold> // </editor-fold>
@ -3717,7 +3727,7 @@ public class Types {
return buf.reverse(); return buf.reverse();
} }
public Type capture(Type t) { public Type capture(Type t) {
if (t.tag != CLASS) if (!t.hasTag(CLASS))
return t; return t;
if (t.getEnclosingType() != Type.noType) { if (t.getEnclosingType() != Type.noType) {
Type capturedEncl = capture(t.getEnclosingType()); Type capturedEncl = capture(t.getEnclosingType());
@ -3783,7 +3793,7 @@ public class Types {
public List<Type> freshTypeVariables(List<Type> types) { public List<Type> freshTypeVariables(List<Type> types) {
ListBuffer<Type> result = lb(); ListBuffer<Type> result = lb();
for (Type t : types) { for (Type t : types) {
if (t.tag == WILDCARD) { if (t.hasTag(WILDCARD)) {
t = t.unannotatedType(); t = t.unannotatedType();
Type bound = ((WildcardType)t).getExtendsBound(); Type bound = ((WildcardType)t).getExtendsBound();
if (bound == null) if (bound == null)
@ -3953,14 +3963,14 @@ public class Types {
@Override @Override
public Void visitClassType(ClassType source, Type target) throws AdaptFailure { public Void visitClassType(ClassType source, Type target) throws AdaptFailure {
if (target.tag == CLASS) if (target.hasTag(CLASS))
adaptRecursive(source.allparams(), target.allparams()); adaptRecursive(source.allparams(), target.allparams());
return null; return null;
} }
@Override @Override
public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure {
if (target.tag == ARRAY) if (target.hasTag(ARRAY))
adaptRecursive(elemtype(source), elemtype(target)); adaptRecursive(elemtype(source), elemtype(target));
return null; return null;
} }
@ -4142,7 +4152,7 @@ public class Types {
} }
Type B(Type t) { Type B(Type t) {
while (t.tag == WILDCARD) { while (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType)t.unannotatedType(); WildcardType w = (WildcardType)t.unannotatedType();
t = high ? t = high ?
w.getExtendsBound() : w.getExtendsBound() :
@ -4187,7 +4197,7 @@ public class Types {
* substituted by the wildcard * substituted by the wildcard
*/ */
private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
if (bound.tag == BOT) { if (bound.hasTag(BOT)) {
return new WildcardType(syms.objectType, return new WildcardType(syms.objectType,
BoundKind.UNBOUND, BoundKind.UNBOUND,
syms.boundClass, syms.boundClass,

View file

@ -115,12 +115,17 @@ public class DeferredAttr extends JCTree.Visitor {
SpeculativeCache speculativeCache; SpeculativeCache speculativeCache;
DeferredType(JCExpression tree, Env<AttrContext> env) { DeferredType(JCExpression tree, Env<AttrContext> env) {
super(DEFERRED, null); super(null);
this.tree = tree; this.tree = tree;
this.env = env.dup(tree, env.info.dup()); this.env = env.dup(tree, env.info.dup());
this.speculativeCache = new SpeculativeCache(); this.speculativeCache = new SpeculativeCache();
} }
@Override
public TypeTag getTag() {
return DEFERRED;
}
/** /**
* A speculative cache is used to keep track of all overload resolution rounds * A speculative cache is used to keep track of all overload resolution rounds
* that triggered speculative attribution on a given deferred type. Each entry * that triggered speculative attribution on a given deferred type. Each entry

View file

@ -96,7 +96,7 @@ public class Infer {
} }
/** A value for prototypes that admit any type, including polymorphic ones. */ /** A value for prototypes that admit any type, including polymorphic ones. */
public static final Type anyPoly = new Type(NONE, null); public static final Type anyPoly = new JCNoType();
/** /**
* This exception class is design to store a list of diagnostics corresponding * This exception class is design to store a list of diagnostics corresponding

View file

@ -2843,7 +2843,7 @@ public class Resolve {
protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
Scope sc = new Scope(syms.arrayClass); Scope sc = new Scope(syms.arrayClass);
MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass); arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
sc.enter(arrayConstr); sc.enter(arrayConstr);
return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false); return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
} }

View file

@ -1859,7 +1859,7 @@ public class Code {
} }
} }
static final Type jsrReturnValue = new Type(INT, null); static final Type jsrReturnValue = new JCPrimitiveType(INT, null);
/* ************************************************************************** /* **************************************************************************

View file

@ -139,7 +139,7 @@ public class JavacTypes implements javax.lang.model.util.Types {
Type unboxed = types.unboxedType((Type) t); Type unboxed = types.unboxedType((Type) t);
if (! unboxed.isPrimitive()) // only true primitives, not void if (! unboxed.isPrimitive()) // only true primitives, not void
throw new IllegalArgumentException(t.toString()); throw new IllegalArgumentException(t.toString());
return unboxed; return (PrimitiveType)unboxed;
} }
public TypeMirror capture(TypeMirror t) { public TypeMirror capture(TypeMirror t) {