📄 type.java
字号:
/** * @(#)Type.java 1.51 03/04/15 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.tools.javac.v8.code;import com.sun.tools.javac.v8.util.*;import com.sun.tools.javac.v8.code.Symbol.*;/** * This class represents GJ types. The class itself defines the behavior of * the following types: * * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN), * type `void' (tag: VOID), * the bottom type (tag: BOT), * the missing type (tag: NONE). * * The behavior of the following types is defined in subclasses, which are * all static inner classes of this class: * * class types (tag: CLASS, class: ClassType), * array types (tag: ARRAY, class: ArrayType), * method types (tag: METHOD, class: MethodType), * package types (tag: PACKAGE, class: PackageType), * type variables (tag: TYPEVAR, class: TypeVar), * polymorphic types (tag: FORALL, class: ForAll), * the error type (tag: ERROR, class: ErrorType). * * @see TypeTags */public class Type implements Flags, Kinds, TypeTags { /** * Constant type: no type at all. */ public static final Type noType = new Type(NONE, null); /** * 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 TypeTags */ public int tag; /** * The defining class / interface / package / type variable */ public TypeSymbol tsym; /** * The constant value of this type, null if this type does not have * a constant value attribute. Constant values can be set only for * base types (numbers, booleans) and class types (strings). */ public Object constValue = null; /** * Define a type given its tag and type symbol */ public Type(int tag, TypeSymbol tsym) { super(); this.tag = tag; this.tsym = tsym; } /** * An abstract class for mappings from types to types */ public static abstract class Mapping { public Mapping() { super(); } public abstract Type apply(Type t); } /** * map a type function over all immediate descendants of this type */ public Type map(Mapping f) { return this; } /** * map a type function over a list of types */ public static List map(List these, Mapping f) { if (these.nonEmpty()) { List tail1 = map(these.tail, f); Type head1 = f.apply((Type) these.head); if (tail1 != these.tail || head1 != these.head) return tail1.prepend(head1); } return these; } /** * Define a constant type, of the same kind as this type * and with given constant value */ public Type constType(Object constValue) { assert tag <= BOOLEAN; Type t = new Type(tag, tsym); t.constValue = constValue; return t; } /** * If this is a constant type, return its underlying type. * Otherwise, return the type itself. */ public Type baseType() { if (constValue == null) return this; else return tsym.type; } /** * Return the base types of a list of types. */ public static List baseTypes(List types) { if (types.nonEmpty()) { Type t = ((Type) types.head).baseType(); List ts = baseTypes(types.tail); if (t != types.head || ts != types.tail) return new List(t, ts); } return types; } /** * Convert to string. */ public String toString() { String s = (tsym == null || tsym.name == null) ? "null" : tsym.name.toString(); return s; } /** * The Java source which this type represents. Use of this method * will result in the loss of the plain-language description for * the type. */ public String toJava() { String s = (tsym == null || tsym.name == null) ? "null" : tsym.name.toJava(); return s; } /** * The Java source which this type represents. A List will always * be represented as a comma-spearated listing of the elements in * that list. Use of this method will result in the loss of the * plain-language description for the type. */ public static String toJavaList(List list) { if (list.isEmpty()) { return ""; } else { StringBuffer buf = new StringBuffer(); buf.append(((Type) list.head).toJava()); for (List l = list.tail; l.nonEmpty(); l = l.tail) { buf.append(","); buf.append(((Type) l.head).toJava()); } return buf.toString(); } } /** * The constant value of this type, converted to String * PRE: Type has a non-null constValue field. */ public String stringValue() { if (tag == BOOLEAN) return ((Integer) constValue).intValue() == 0 ? "false" : "true"; else if (tag == CHAR) return String.valueOf((char)((Integer) constValue).intValue()); else return constValue.toString(); } /** * 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; } /** * Access methods. */ public List typarams() { return emptyList; } public Type outer() { return null; } public Type elemtype() { return null; } public int dimensions() { return 0; } public List argtypes() { return emptyList; } public Type restype() { return null; } public List thrown() { return Type.emptyList; } public Type bound() { return null; } /** * Set the thrown exceptions for a method type. */ public void setThrown(List t) { throw new AssertionError(); } /** * Navigation methods, these will work for classes, type variables, * foralls, but will return null for arrays and methods. */ public Type supertype() { return null; } public List interfaces() { return emptyList; } /** * Return all parameters of this type and all its outer types in order * outer (first) to inner (last). */ public List allparams() { return emptyList; } /** * Return the (most specific) base type of this type that starts * with symbol sym. If none exists, return null. */ public Type asSuper(Symbol sym) { return null; } /** * Return the base type of this type or any * of its outer types that starts with symbol sym. * If none exists, return null. */ public Type asOuterSuper(Symbol sym) { return null; } /** * If this type is a (possibly selected) type variable, * return the bounding class of this type, otherwise * return the type itself */ public Type classBound() { return this; } /** * Return the least specific subtype of this type that starts * with symbol sym. if none exists, return null. * The least specific subtype is determined as follows: * * If there is exactly one parameterized instance of sym * that is a subtype of this type, that parameterized instance is returned. * Otherwise, if the plain type or raw type `sym' is a subtype * of this type, the type `sym' itself is returned. * Otherwise, null is returned. */ Type asSub(Symbol sym) { return null; } /** * The type of given symbol, seen as a member of this type */ public Type memberType(Symbol sym) { return sym.type; } /** * Substitute all occurrences of a type in `from' with the * corresponding type in `to'. Match lists `from' and `to' from the right: * If lists have different length, discard leading elements of the longer list. */ public Type subst(List from, List to) { return this; } public static List subst(List these, List from, List to) { if (these.tail != null && from.tail != null) { Type head1 = ((Type) these.head).subst(from, to); List tail1 = subst(these.tail, from, to); if (head1 != these.head || tail1 != these.tail) return tail1.prepend(head1); } return these; } /** * Does this type contain "error" elements? */ public boolean isErroneous() { return false; } public static boolean isErroneous(List ts) { for (List l = ts; l.nonEmpty(); l = l.tail) if (((Type) l.head).isErroneous()) return true; return false; } /** * Is this type parameterized? * A class type is parameterized if it has some parameters. * An array type is parameterized if its element type is parameterized. * All other types are not parameterized. */ public boolean isParameterized() { return false; } /** * Is this type a raw type? * A class type is a raw type if it misses some of its parameters. * An array type is a raw type if its element type is raw. * All other types are not raw. * Type validation will ensure that the only raw types * in a program are types that miss all their type variables. */ public boolean isRaw() { return false; } 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -