📄 type.java
字号:
public static boolean isRaw(List ts) {
return false;
}
public static boolean isDerivedRaw(Type t) {
return t.isRaw() || t.supertype() != null &&
isDerivedRaw(t.supertype()) || isDerivedRaw(t.interfaces());
}
public static boolean isDerivedRaw(List ts) {
List l = ts;
while (l.nonEmpty() && !isDerivedRaw((Type) l.head))
l = l.tail;
return l.nonEmpty();
}
/**
* The erasure of this type -- the type that results when
* all type parameters in this type are deleted.
*/
public Type erasure() {
if (tag <= lastBaseTag)
return this;
else
return map(erasureFun);
}
public static List erasure(List these) {
return map(these, erasureFun);
}
static Mapping erasureFun = new Mapping() {
public Type apply(Type t) {
return t.erasure();
}
};
/**
* Does this type contain occurrences of type `elem'?
*/
public boolean contains(Type elem) {
return elem == this;
}
public static boolean contains(List these, Type elem) {
for (List l = these; l.tail != null; l = l.tail)
if (((Type) l.head).contains(elem))
return true;
return false;
}
/**
* Does this type contain an occurrence of some type in `elems'?
*/
public boolean containsSome(List elems) {
for (List l = elems; l.nonEmpty(); l = l.tail)
if (this.contains((Type) elems.head))
return true;
return false;
}
/**
* Is this type the same as that type?
*/
public boolean isSameType(Type that) {
if (this == that)
return true;
if (that.tag >= firstPartialTag)
return that.isSameType(this);
switch (this.tag) {
case BYTE:
case CHAR:
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
case BOOLEAN:
case VOID:
case BOT:
case NONE:
return this.tag == that.tag;
default:
throw new AssertionError("isSameType " + this.tag);
}
}
/**
* Same for lists of types, if lists are of different length, return false.
*/
public static boolean isSameTypes(List these, List those) {
while (these.tail != null && those.tail != null &&
((Type) these.head).isSameType((Type) those.head)) {
these = these.tail;
those = those.tail;
}
return these.tail == null && those.tail == null;
}
/**
* Is this type a subtype of that type?
* (not defined for Method and ForAll types)
*/
public boolean isSubType(Type that) {
if (this == that)
return true;
if (that.tag >= firstPartialTag)
return that.isSuperType(this);
switch (this.tag) {
case BYTE:
case CHAR:
return (this.tag == that.tag || this.tag + 2 <= that.tag &&
that.tag <= DOUBLE);
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
return this.tag <= that.tag && that.tag <= DOUBLE;
case BOOLEAN:
case VOID:
return this.tag == that.tag;
case BOT:
return (that.tag == BOT || that.tag == CLASS || that.tag == ARRAY);
default:
throw new AssertionError("isSubType " + this.tag);
}
}
/**
* Is this type a supertype of that type?
* overridden for partial types.
*/
public boolean isSuperType(Type that) {
return that.isSubType(this);
}
/**
* Is this type a subtype of every type in given list `those'?
* (not defined for Method and ForAll types)
*/
public boolean isSubType(List those) {
for (List l = those; l.nonEmpty(); l = l.tail) {
if (!this.isSubType((Type) l.head))
return false;
}
return true;
}
/**
* Same for lists of types, if lists are of different length, return false.
*/
public static boolean isSubTypes(List these, List those) {
while (these.tail != null && those.tail != null &&
((Type) these.head).isSubType((Type) those.head)) {
these = these.tail;
those = those.tail;
}
return these.tail == null && those.tail == null;
}
/**
* If this switch is true, we allow assigning character constants to byte
* provided they fit in the range.
*/
private static final boolean looseInterpretation = true;
/**
* Is this type assignable to that type? Equivalent to subtype
* except for constant values. (not defined for Method and ForAll types)
*/
public boolean isAssignable(Type that) {
if (this.tag <= INT && this.constValue != null) {
int value = ((Number) this.constValue).intValue();
switch (that.tag) {
case BYTE:
if ((looseInterpretation || this.tag != CHAR) &&
Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
return true;
break;
case CHAR:
if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
return true;
break;
case SHORT:
if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
return true;
break;
case INT:
return true;
}
}
return this.isSubType(that);
}
/**
* If this type is castable to that type, return the result of the cast
* otherwise return null;
* that type is assumed to be an erased type.
* (not defined for Method and ForAll types).
*/
public boolean isCastable(Type that) {
if (that.tag == ERROR)
return true;
switch (this.tag) {
case BYTE:
case CHAR:
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
return that.tag <= DOUBLE;
case BOOLEAN:
return that.tag == BOOLEAN;
case VOID:
return false;
case BOT:
return this.isSubType(that);
default:
throw new AssertionError();
}
}
/**
* The underlying method type of this type.
*/
public MethodType asMethodType() {
throw new AssertionError();
}
/**
* Does this type have the same arguments as that type?
* It is assumed that both types are (possibly polymorphic) method types.
* Monomorphic method types "have the same arguments",
* if their argument lists are equal.
* Polymorphic method types "have the same arguments",
* if they have the same arguments after renaming all type variables
* of one to corresponding type variables in the other, where
* correspondence is by position in the type parameter list.
*/
public boolean hasSameArgs(Type that) {
throw new AssertionError();
}
/**
* Complete loading all classes in this type.
*/
public void complete() {
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
/**
* An empty list of types.
*/
public static final List emptyList = new List();
public static class ClassType extends Type {
/**
* The enclosing type of this type. If this is the type of an inner
* class, outer_field refers to the type of its enclosing
* instance class, in all other cases it referes to noType.
*/
public Type outer_field;
/**
* The type parameters of this type (to be set once class is loaded).
*/
public List typarams_field;
/**
* A cache variable for the type parameters of this type,
* appended to all parameters of its enclosing class.
* @see allparams()
*/
public List allparams_field;
/**
* The supertype of this class (to be set once class is loaded).
*/
public Type supertype_field;
/**
* The interfaces of this class (to be set once class is loaded).
*/
public List interfaces_field;
public ClassType(Type outer, List typarams, TypeSymbol tsym) {
super(CLASS, tsym);
this.outer_field = outer;
this.typarams_field = typarams;
this.allparams_field = null;
this.supertype_field = null;
this.interfaces_field = null;
}
/**
* make a compound type from non-empty list of types
* @param bounds the types from which the compound type is formed
* @param tsym the compound type's type symbol
* @param supertype is objectType if all bounds are interfaces,
* null otherwise.
*/
static Type makeCompoundType(List bounds, TypeSymbol tsym, Type supertype) {
ClassSymbol bc = new ClassSymbol(ABSTRACT | PUBLIC | SYNTHETIC | COMPOUND,
tsym.name, tsym);
bc.erasure_field = ((Type) bounds.head).erasure();
bc.members_field = new Scope(bc);
ClassType bt = (ClassType) bc.type;
bt.allparams_field = Type.emptyList;
if (supertype != null) {
bt.supertype_field = supertype;
bt.interfaces_field = bounds;
} else {
bt.supertype_field = (Type) bounds.head;
bt.interfaces_field = bounds.tail;
}
return bt;
}
/**
* Same as previous function, except that third parameter is
* computed directly. Note that this test might cause a symbol completion.
* Hence, this version of makeCompoundType may not be called during
* a classfile read.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -