type.java
来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,249 行 · 第 1/3 页
JAVA
1,249 行
/* * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */package com.sun.tools.javac.code;import javax.lang.model.element.Element;import javax.lang.model.type.*;import com.sun.tools.javac.util.*;import com.sun.tools.javac.code.Symbol.*;import javax.lang.model.element.Element;import javax.lang.model.type.*;import static com.sun.tools.javac.code.Flags.*;import static com.sun.tools.javac.code.Kinds.*;import static com.sun.tools.javac.code.BoundKind.*;import static com.sun.tools.javac.code.TypeTags.*;/** This class represents Java types. The class itself defines the behavior of * the following types: * <pre> * 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). * </pre> * <p>The behavior of the following types is defined in subclasses, which are * all static inner classes of this class: * <pre> * 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), * type arguments (tag: WILDCARD, class: WildcardType), * polymorphic types (tag: FORALL, class: ForAll), * the error type (tag: ERROR, class: ErrorType). * </pre> * * <p><b>This is NOT part of any API supported by Sun Microsystems. If * you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice.</b> * * @see TypeTags */public class Type implements PrimitiveType { /** Constant type: no type at all. */ public static final JCNoType noType = new JCNoType(NONE); /** 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. Only primitive types and * strings (ClassType) can have a constant value attribute. * @return the constant value attribute of this type */ public Object constValue() { return null; } public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); } /** Define a type given its tag and type symbol */ public Type(int tag, TypeSymbol tsym) { this.tag = tag; this.tsym = tsym; } /** An abstract class for mappings from types to types */ public static abstract class Mapping { private String name; public Mapping(String name) { this.name = name; } public abstract Type apply(Type t); public String toString() { return name; } } /** 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<Type> map(List<Type> ts, Mapping f) { if (ts.nonEmpty()) { List<Type> tail1 = map(ts.tail, f); Type t = f.apply(ts.head); if (tail1 != ts.tail || t != ts.head) return tail1.prepend(t); } return ts; } /** Define a constant type, of the same kind as this type * and with given constant value */ public Type constType(Object constValue) { final Object value = constValue; assert tag <= BOOLEAN; return new Type(tag, tsym) { @Override public Object constValue() { return value; } @Override public Type baseType() { return tsym.type; } }; } /** * If this is a constant type, return its underlying type. * Otherwise, return the type itself. */ public Type baseType() { return this; } /** Return the base types of a list of types. */ public static List<Type> baseTypes(List<Type> ts) { if (ts.nonEmpty()) { Type t = ts.head.baseType(); List<Type> baseTypes = baseTypes(ts.tail); if (t != ts.head || baseTypes != ts.tail) return baseTypes.prepend(t); } return ts; } /** The Java source which this type represents. */ public String toString() { String s = (tsym == null || tsym.name == null) ? "<none>" : tsym.name.toString(); if (moreInfo && tag == TYPEVAR) s = s + hashCode(); return s; } /** * The Java source which this type list represents. A List is * represented as a comma-spearated listing of the elements in * that list. */ public static String toString(List<Type> ts) { if (ts.isEmpty()) { return ""; } else { StringBuffer buf = new StringBuffer(); buf.append(ts.head.toString()); for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail) buf.append(",").append(l.head.toString()); return buf.toString(); } } /** * The constant value of this type, converted to String */ public String stringValue() { assert constValue() != null; 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(); } /** * This method is analogous to isSameType, but weaker, since we * never complete classes. Where isSameType would complete a * class, equals assumes that the two types are different. */ public boolean equals(Object t) { return super.equals(t); } public int 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) { List<Type> args = getParameterTypes(); if (!varargs) return args.toString(); StringBuffer buf = new StringBuffer(); while (args.tail.nonEmpty()) { buf.append(args.head); args = args.tail; buf.append(','); } if (args.head.tag == ARRAY) { buf.append(((ArrayType)args.head).elemtype); buf.append("..."); } else { buf.append(args.head); } return buf.toString(); } /** Access methods. */ public List<Type> getTypeArguments() { return List.nil(); } public Type getEnclosingType() { return null; } public List<Type> getParameterTypes() { return List.nil(); } public Type getReturnType() { return null; } public List<Type> getThrownTypes() { return List.nil(); } public Type getUpperBound() { return null; } public Type getLowerBound() { return null; } public void setThrown(List<Type> ts) { throw new AssertionError(); } /** Navigation methods, these will work for classes, type variables, * foralls, but will return null for arrays and methods. */ /** Return all parameters of this type and all its outer types in order * outer (first) to inner (last). */ public List<Type> allparams() { return List.nil(); } /** Does this type contain "error" elements? */ public boolean isErroneous() { return false; } public static boolean isErroneous(List<Type> ts) { for (List<Type> l = ts; l.nonEmpty(); l = l.tail) if (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 boolean isCompound() { return tsym.completer == null // Compound types can't have a completer. Calling // flags() will complete the symbol causing the // compiler to load classes unnecessarily. This led // to regression 6180021. && (tsym.flags() & COMPOUND) != 0; } public boolean isInterface() { return (tsym.flags() & INTERFACE) != 0; } public boolean isPrimitive() { return tag < VOID; } /** * Does this type contain occurrences of type t? */ public boolean contains(Type t) { return t == this; } public static boolean contains(List<Type> ts, Type t) { for (List<Type> l = ts; l.tail != null /*inlined: l.nonEmpty()*/; l = l.tail) if (l.head.contains(t)) return true; return false; } /** Does this type contain an occurrence of some type in `elems'? */ public boolean containsSome(List<Type> ts) { for (List<Type> l = ts; l.nonEmpty(); l = l.tail) if (this.contains(ts.head)) return true; return false; } public boolean isSuperBound() { return false; } public boolean isExtendsBound() { return false; } public boolean isUnbound() { return false; } public Type withTypeVar(Type t) { return this; } public static List<Type> removeBounds(List<Type> ts) { ListBuffer<Type> result = new ListBuffer<Type>(); for(;ts.nonEmpty(); ts = ts.tail) { result.append(ts.head.removeBounds()); } return result.toList(); } public Type removeBounds() { return this; } /** The underlying method type of this type. */ public MethodType asMethodType() { 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); } } public TypeSymbol asElement() { return tsym; } 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; } } public <R, P> R accept(TypeVisitor<R, P> v, P p) { if (isPrimitive()) return v.visitPrimitive(this, p); else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?