diff -r bf020de5a6db -r 831467c4c6a7 src/share/classes/com/sun/tools/javac/code/Type.java --- a/src/share/classes/com/sun/tools/javac/code/Type.java Mon Jun 24 22:03:57 2013 -0400 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Tue Jun 25 16:12:53 2013 +0100 @@ -70,25 +70,19 @@ * * @see TypeTag */ -public class Type implements PrimitiveType { +public abstract class Type implements TypeMirror { /** 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. */ - 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 * and anonymous classes are printed with hashcodes appended. */ public static boolean moreInfo = false; - /** The tag of this type. - * - * @see TypeTag - */ - protected TypeTag tag; - /** The defining class / interface / package / type variable. */ public TypeSymbol tsym; @@ -98,39 +92,37 @@ * @return true if tag is equal to the current type tag. */ public boolean hasTag(TypeTag tag) { - return this.tag == tag; + return tag == getTag(); } /** * Returns the current type tag. * @return the value of the current type tag. */ - public TypeTag getTag() { - return tag; - } + public abstract TypeTag getTag(); public boolean isNumeric() { - return tag.isNumeric; + return false; } public boolean isPrimitive() { - return tag.isPrimitive; + return false; } public boolean isPrimitiveOrVoid() { - return tag.isPrimitiveOrVoid; + return false; } public boolean isReference() { - return tag.isReference; + return false; } public boolean isNullOrReference() { - return (tag.isReference || tag == BOT); + return false; } public boolean isPartial() { - return tag.isPartial; + return false; } /** @@ -143,6 +135,18 @@ 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. * By default, this is itself. For ErrorType, a different value @@ -153,7 +157,7 @@ } public static List getModelTypes(List ts) { - ListBuffer lb = new ListBuffer(); + ListBuffer lb = new ListBuffer<>(); for (Type t: ts) lb.append(t.getModelType()); return lb.toList(); @@ -163,8 +167,7 @@ /** Define a type given its tag and type symbol */ - public Type(TypeTag tag, TypeSymbol tsym) { - this.tag = tag; + public Type(TypeSymbol tsym) { this.tsym = tsym; } @@ -203,18 +206,7 @@ * and with given constant value */ public Type constType(Object constValue) { - final Object value = constValue; - Assert.check(isPrimitive()); - return new Type(tag, tsym) { - @Override - public Object constValue() { - return value; - } - @Override - public Type baseType() { - return tsym.type; - } - }; + throw new AssertionError(); } /** @@ -272,7 +264,9 @@ String s = (tsym == null || tsym.name == null) ? "" : tsym.name.toString(); - if (moreInfo && tag == TYPEVAR) s = s + hashCode(); + if (moreInfo && hasTag(TYPEVAR)) { + s = s + hashCode(); + } return s; } @@ -298,12 +292,7 @@ */ 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(); + return cv.toString(); } /** @@ -321,24 +310,6 @@ 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) { List args = getParameterTypes(); if (!varargs) return args.toString(); @@ -348,7 +319,7 @@ args = args.tail; buf.append(','); } - if (args.head.unannotatedType().tag == ARRAY) { + if (args.head.unannotatedType().hasTag(ARRAY)) { buf.append(((ArrayType)args.head.unannotatedType()).elemtype); if (args.head.getAnnotationMirrors().nonEmpty()) { buf.append(args.head.getAnnotationMirrors()); @@ -485,28 +456,122 @@ return tsym; } + @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; - case VOID: return TypeKind.VOID; - case BOT: return TypeKind.NULL; - case NONE: return TypeKind.NONE; - default: return TypeKind.OTHER; - } + return TypeKind.OTHER; } + @Override public R accept(TypeVisitor 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 accept(TypeVisitor v, P 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(); + } + } public static class WildcardType extends Type @@ -522,7 +587,7 @@ } public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) { - super(WILDCARD, tsym); + super(tsym); this.type = Assert.checkNonNull(type); this.kind = kind; } @@ -535,6 +600,12 @@ this.bound = bound; } + @Override + public TypeTag getTag() { + return WILDCARD; + } + + @Override public boolean contains(Type t) { return kind != UNBOUND && type.contains(t); } @@ -551,6 +622,17 @@ return kind == UNBOUND; } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + + @Override public Type withTypeVar(Type t) { //-System.err.println(this+".withTypeVar("+t+");");//DEBUG if (bound == t) @@ -640,7 +722,7 @@ public List all_interfaces_field; public ClassType(Type outer, List typarams, TypeSymbol tsym) { - super(CLASS, tsym); + super(tsym); this.outer_field = outer; this.typarams_field = typarams; this.allparams_field = null; @@ -658,6 +740,11 @@ } @Override + public TypeTag getTag() { + return CLASS; + } + + @Override public R accept(Type.Visitor v, S s) { return v.visitClassType(this, s); } @@ -680,7 +767,7 @@ */ public String toString() { 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("."); buf.append(className(tsym, false)); @@ -765,6 +852,16 @@ // optimization, was: allparams().nonEmpty(); } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + /** A cache for the rank. */ int rank_field = -1; @@ -909,11 +1006,15 @@ public Type elemtype; public ArrayType(Type elemtype, TypeSymbol arrayClass) { - super(ARRAY, arrayClass); + super(arrayClass); this.elemtype = elemtype; } @Override + public TypeTag getTag() { + return ARRAY; + } + public R accept(Type.Visitor v, S s) { return v.visitArrayType(this, s); } @@ -947,6 +1048,16 @@ return elemtype.isParameterized(); } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + public boolean isRaw() { return elemtype.isRaw(); } @@ -1001,13 +1112,17 @@ Type restype, List thrown, TypeSymbol methodClass) { - super(METHOD, methodClass); + super(methodClass); this.argtypes = argtypes; this.restype = restype; this.thrown = thrown; } @Override + public TypeTag getTag() { + return METHOD; + } + public R accept(Type.Visitor v, S s) { return v.visitMethodType(this, s); } @@ -1077,7 +1192,12 @@ public static class PackageType extends Type implements NoType { PackageType(TypeSymbol tsym) { - super(PACKAGE, tsym); + super(tsym); + } + + @Override + public TypeTag getTag() { + return PACKAGE; } @Override @@ -1120,26 +1240,32 @@ public Type lower; public TypeVar(Name name, Symbol owner, Type lower) { - super(TYPEVAR, null); + super(null); tsym = new TypeVariableSymbol(0, name, this, owner); this.lower = lower; } public TypeVar(TypeSymbol tsym, Type bound, Type lower) { - super(TYPEVAR, tsym); + super(tsym); this.bound = bound; this.lower = lower; } @Override + public TypeTag getTag() { + return TYPEVAR; + } + + @Override public R accept(Type.Visitor v, S s) { return v.visitTypeVar(this, s); } @Override 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(); + } return bound; } @@ -1158,6 +1284,17 @@ return false; } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + + @Override public R accept(TypeVisitor v, P p) { return v.visitTypeVariable(this, p); } @@ -1203,10 +1340,13 @@ public static abstract class DelegatedType extends Type { public Type qtype; + public TypeTag tag; public DelegatedType(TypeTag tag, Type qtype) { - super(tag, qtype.tsym); + super(qtype.tsym); + this.tag = tag; this.qtype = qtype; } + public TypeTag getTag() { return tag; } public String toString() { return qtype.toString(); } public List getTypeArguments() { return qtype.getTypeArguments(); } public Type getEnclosingType() { return qtype.getEnclosingType(); } @@ -1340,6 +1480,12 @@ else return qtype + "?"; } + @Override + public boolean isPartial() { + return true; + } + + @Override public Type baseType() { if (inst != null) return inst.baseType(); else return this; @@ -1439,21 +1585,21 @@ } } - /** Represents VOID or NONE. + /** Represents NONE. */ - static class JCNoType extends Type implements NoType { - public JCNoType(TypeTag tag) { - super(tag, null); + public static class JCNoType extends Type implements NoType { + public JCNoType() { + super(null); + } + + @Override + public TypeTag getTag() { + return NONE; } @Override public TypeKind getKind() { - switch (tag) { - case VOID: return TypeKind.VOID; - case NONE: return TypeKind.NONE; - default: - throw new AssertionError("Unexpected tag: " + tag); - } + return TypeKind.NONE; } @Override @@ -1462,9 +1608,43 @@ } } + /** 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 accept(TypeVisitor v, P p) { + return v.visitNoType(this, p); + } + + @Override + public boolean isPrimitiveOrVoid() { + return true; + } + } + static class BottomType extends Type implements NullType { public BottomType() { - super(BOT, null); + super(null); + } + + @Override + public TypeTag getTag() { + return BOT; } @Override @@ -1486,6 +1666,12 @@ public String stringValue() { return "null"; } + + @Override + public boolean isNullOrReference() { + return true; + } + } public static class ErrorType extends ClassType @@ -1495,7 +1681,6 @@ public ErrorType(Type originalType, TypeSymbol tsym) { super(noType, List.nil(), null); - tag = ERROR; this.tsym = tsym; this.originalType = (originalType == null ? noType : originalType); } @@ -1507,6 +1692,26 @@ 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) { this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType); } @@ -1559,7 +1764,7 @@ public Type underlyingType; public AnnotatedType(Type underlyingType) { - super(underlyingType.tag, underlyingType.tsym); + super(underlyingType.tsym); this.typeAnnotations = List.nil(); this.underlyingType = underlyingType; Assert.check(!underlyingType.isAnnotated(), @@ -1568,7 +1773,7 @@ public AnnotatedType(List typeAnnotations, Type underlyingType) { - super(underlyingType.tag, underlyingType.tsym); + super(underlyingType.tsym); this.typeAnnotations = typeAnnotations; this.underlyingType = underlyingType; Assert.check(!underlyingType.isAnnotated(), @@ -1577,6 +1782,11 @@ } @Override + public TypeTag getTag() { + return underlyingType.getTag(); + } + + @Override public boolean isAnnotated() { return true; } @@ -1651,10 +1861,18 @@ @Override public List allparams() { return underlyingType.allparams(); } @Override + public boolean isPrimitive() { return underlyingType.isPrimitive(); } + @Override + public boolean isPrimitiveOrVoid() { return underlyingType.isPrimitiveOrVoid(); } + @Override public boolean isNumeric() { return underlyingType.isNumeric(); } @Override public boolean isReference() { return underlyingType.isReference(); } @Override + public boolean isNullOrReference() { return underlyingType.isNullOrReference(); } + @Override + public boolean isPartial() { return underlyingType.isPartial(); } + @Override public boolean isParameterized() { return underlyingType.isParameterized(); } @Override public boolean isRaw() { return underlyingType.isRaw(); } @@ -1719,6 +1937,28 @@ 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 accept(TypeVisitor 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 * (or relations) on types. Most common operations on types are