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 + -
显示快捷键?