0001: /*
0002: * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package com.sun.tools.javac.code;
0027:
0028: import javax.lang.model.element.Element;
0029: import javax.lang.model.type.*;
0030: import com.sun.tools.javac.util.*;
0031: import com.sun.tools.javac.code.Symbol.*;
0032: import javax.lang.model.element.Element;
0033:
0034: import javax.lang.model.type.*;
0035:
0036: import static com.sun.tools.javac.code.Flags.*;
0037: import static com.sun.tools.javac.code.Kinds.*;
0038: import static com.sun.tools.javac.code.BoundKind.*;
0039: import static com.sun.tools.javac.code.TypeTags.*;
0040:
0041: /** This class represents Java types. The class itself defines the behavior of
0042: * the following types:
0043: * <pre>
0044: * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
0045: * type `void' (tag: VOID),
0046: * the bottom type (tag: BOT),
0047: * the missing type (tag: NONE).
0048: * </pre>
0049: * <p>The behavior of the following types is defined in subclasses, which are
0050: * all static inner classes of this class:
0051: * <pre>
0052: * class types (tag: CLASS, class: ClassType),
0053: * array types (tag: ARRAY, class: ArrayType),
0054: * method types (tag: METHOD, class: MethodType),
0055: * package types (tag: PACKAGE, class: PackageType),
0056: * type variables (tag: TYPEVAR, class: TypeVar),
0057: * type arguments (tag: WILDCARD, class: WildcardType),
0058: * polymorphic types (tag: FORALL, class: ForAll),
0059: * the error type (tag: ERROR, class: ErrorType).
0060: * </pre>
0061: *
0062: * <p><b>This is NOT part of any API supported by Sun Microsystems. If
0063: * you write code that depends on this, you do so at your own risk.
0064: * This code and its internal interfaces are subject to change or
0065: * deletion without notice.</b>
0066: *
0067: * @see TypeTags
0068: */
0069: @Version("@(#)Type.java 1.108 07/05/05")
0070: public class Type implements PrimitiveType {
0071:
0072: /** Constant type: no type at all. */
0073: public static final JCNoType noType = new JCNoType(NONE);
0074:
0075: /** If this switch is turned on, the names of type variables
0076: * and anonymous classes are printed with hashcodes appended.
0077: */
0078: public static boolean moreInfo = false;
0079:
0080: /** The tag of this type.
0081: *
0082: * @see TypeTags
0083: */
0084: public int tag;
0085:
0086: /** The defining class / interface / package / type variable
0087: */
0088: public TypeSymbol tsym;
0089:
0090: /**
0091: * The constant value of this type, null if this type does not
0092: * have a constant value attribute. Only primitive types and
0093: * strings (ClassType) can have a constant value attribute.
0094: * @return the constant value attribute of this type
0095: */
0096: public Object constValue() {
0097: return null;
0098: }
0099:
0100: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0101: return v.visitType(this , s);
0102: }
0103:
0104: /** Define a type given its tag and type symbol
0105: */
0106: public Type(int tag, TypeSymbol tsym) {
0107: this .tag = tag;
0108: this .tsym = tsym;
0109: }
0110:
0111: /** An abstract class for mappings from types to types
0112: */
0113: public static abstract class Mapping {
0114: private String name;
0115:
0116: public Mapping(String name) {
0117: this .name = name;
0118: }
0119:
0120: public abstract Type apply(Type t);
0121:
0122: public String toString() {
0123: return name;
0124: }
0125: }
0126:
0127: /** map a type function over all immediate descendants of this type
0128: */
0129: public Type map(Mapping f) {
0130: return this ;
0131: }
0132:
0133: /** map a type function over a list of types
0134: */
0135: public static List<Type> map(List<Type> ts, Mapping f) {
0136: if (ts.nonEmpty()) {
0137: List<Type> tail1 = map(ts.tail, f);
0138: Type t = f.apply(ts.head);
0139: if (tail1 != ts.tail || t != ts.head)
0140: return tail1.prepend(t);
0141: }
0142: return ts;
0143: }
0144:
0145: /** Define a constant type, of the same kind as this type
0146: * and with given constant value
0147: */
0148: public Type constType(Object constValue) {
0149: final Object value = constValue;
0150: assert tag <= BOOLEAN;
0151: return new Type(tag, tsym) {
0152: @Override
0153: public Object constValue() {
0154: return value;
0155: }
0156:
0157: @Override
0158: public Type baseType() {
0159: return tsym.type;
0160: }
0161: };
0162: }
0163:
0164: /**
0165: * If this is a constant type, return its underlying type.
0166: * Otherwise, return the type itself.
0167: */
0168: public Type baseType() {
0169: return this ;
0170: }
0171:
0172: /** Return the base types of a list of types.
0173: */
0174: public static List<Type> baseTypes(List<Type> ts) {
0175: if (ts.nonEmpty()) {
0176: Type t = ts.head.baseType();
0177: List<Type> baseTypes = baseTypes(ts.tail);
0178: if (t != ts.head || baseTypes != ts.tail)
0179: return baseTypes.prepend(t);
0180: }
0181: return ts;
0182: }
0183:
0184: /** The Java source which this type represents.
0185: */
0186: public String toString() {
0187: String s = (tsym == null || tsym.name == null) ? "<none>"
0188: : tsym.name.toString();
0189: if (moreInfo && tag == TYPEVAR)
0190: s = s + hashCode();
0191: return s;
0192: }
0193:
0194: /**
0195: * The Java source which this type list represents. A List is
0196: * represented as a comma-spearated listing of the elements in
0197: * that list.
0198: */
0199: public static String toString(List<Type> ts) {
0200: if (ts.isEmpty()) {
0201: return "";
0202: } else {
0203: StringBuffer buf = new StringBuffer();
0204: buf.append(ts.head.toString());
0205: for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
0206: buf.append(",").append(l.head.toString());
0207: return buf.toString();
0208: }
0209: }
0210:
0211: /**
0212: * The constant value of this type, converted to String
0213: */
0214: public String stringValue() {
0215: assert constValue() != null;
0216: if (tag == BOOLEAN)
0217: return ((Integer) constValue()).intValue() == 0 ? "false"
0218: : "true";
0219: else if (tag == CHAR)
0220: return String.valueOf((char) ((Integer) constValue())
0221: .intValue());
0222: else
0223: return constValue().toString();
0224: }
0225:
0226: /**
0227: * This method is analogous to isSameType, but weaker, since we
0228: * never complete classes. Where isSameType would complete a
0229: * class, equals assumes that the two types are different.
0230: */
0231: public boolean equals(Object t) {
0232: return super .equals(t);
0233: }
0234:
0235: public int hashCode() {
0236: return super .hashCode();
0237: }
0238:
0239: /** Is this a constant type whose value is false?
0240: */
0241: public boolean isFalse() {
0242: return tag == BOOLEAN && constValue() != null
0243: && ((Integer) constValue()).intValue() == 0;
0244: }
0245:
0246: /** Is this a constant type whose value is true?
0247: */
0248: public boolean isTrue() {
0249: return tag == BOOLEAN && constValue() != null
0250: && ((Integer) constValue()).intValue() != 0;
0251: }
0252:
0253: public String argtypes(boolean varargs) {
0254: List<Type> args = getParameterTypes();
0255: if (!varargs)
0256: return args.toString();
0257: StringBuffer buf = new StringBuffer();
0258: while (args.tail.nonEmpty()) {
0259: buf.append(args.head);
0260: args = args.tail;
0261: buf.append(',');
0262: }
0263: if (args.head.tag == ARRAY) {
0264: buf.append(((ArrayType) args.head).elemtype);
0265: buf.append("...");
0266: } else {
0267: buf.append(args.head);
0268: }
0269: return buf.toString();
0270: }
0271:
0272: /** Access methods.
0273: */
0274: public List<Type> getTypeArguments() {
0275: return List.nil();
0276: }
0277:
0278: public Type getEnclosingType() {
0279: return null;
0280: }
0281:
0282: public List<Type> getParameterTypes() {
0283: return List.nil();
0284: }
0285:
0286: public Type getReturnType() {
0287: return null;
0288: }
0289:
0290: public List<Type> getThrownTypes() {
0291: return List.nil();
0292: }
0293:
0294: public Type getUpperBound() {
0295: return null;
0296: }
0297:
0298: public Type getLowerBound() {
0299: return null;
0300: }
0301:
0302: public void setThrown(List<Type> ts) {
0303: throw new AssertionError();
0304: }
0305:
0306: /** Navigation methods, these will work for classes, type variables,
0307: * foralls, but will return null for arrays and methods.
0308: */
0309:
0310: /** Return all parameters of this type and all its outer types in order
0311: * outer (first) to inner (last).
0312: */
0313: public List<Type> allparams() {
0314: return List.nil();
0315: }
0316:
0317: /** Does this type contain "error" elements?
0318: */
0319: public boolean isErroneous() {
0320: return false;
0321: }
0322:
0323: public static boolean isErroneous(List<Type> ts) {
0324: for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
0325: if (l.head.isErroneous())
0326: return true;
0327: return false;
0328: }
0329:
0330: /** Is this type parameterized?
0331: * A class type is parameterized if it has some parameters.
0332: * An array type is parameterized if its element type is parameterized.
0333: * All other types are not parameterized.
0334: */
0335: public boolean isParameterized() {
0336: return false;
0337: }
0338:
0339: /** Is this type a raw type?
0340: * A class type is a raw type if it misses some of its parameters.
0341: * An array type is a raw type if its element type is raw.
0342: * All other types are not raw.
0343: * Type validation will ensure that the only raw types
0344: * in a program are types that miss all their type variables.
0345: */
0346: public boolean isRaw() {
0347: return false;
0348: }
0349:
0350: public boolean isCompound() {
0351: return tsym.completer == null
0352: // Compound types can't have a completer. Calling
0353: // flags() will complete the symbol causing the
0354: // compiler to load classes unnecessarily. This led
0355: // to regression 6180021.
0356: && (tsym.flags() & COMPOUND) != 0;
0357: }
0358:
0359: public boolean isInterface() {
0360: return (tsym.flags() & INTERFACE) != 0;
0361: }
0362:
0363: public boolean isPrimitive() {
0364: return tag < VOID;
0365: }
0366:
0367: /**
0368: * Does this type contain occurrences of type t?
0369: */
0370: public boolean contains(Type t) {
0371: return t == this ;
0372: }
0373:
0374: public static boolean contains(List<Type> ts, Type t) {
0375: for (List<Type> l = ts; l.tail != null /*inlined: l.nonEmpty()*/; l = l.tail)
0376: if (l.head.contains(t))
0377: return true;
0378: return false;
0379: }
0380:
0381: /** Does this type contain an occurrence of some type in `elems'?
0382: */
0383: public boolean containsSome(List<Type> ts) {
0384: for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
0385: if (this .contains(ts.head))
0386: return true;
0387: return false;
0388: }
0389:
0390: public boolean isSuperBound() {
0391: return false;
0392: }
0393:
0394: public boolean isExtendsBound() {
0395: return false;
0396: }
0397:
0398: public boolean isUnbound() {
0399: return false;
0400: }
0401:
0402: public Type withTypeVar(Type t) {
0403: return this ;
0404: }
0405:
0406: public static List<Type> removeBounds(List<Type> ts) {
0407: ListBuffer<Type> result = new ListBuffer<Type>();
0408: for (; ts.nonEmpty(); ts = ts.tail) {
0409: result.append(ts.head.removeBounds());
0410: }
0411: return result.toList();
0412: }
0413:
0414: public Type removeBounds() {
0415: return this ;
0416: }
0417:
0418: /** The underlying method type of this type.
0419: */
0420: public MethodType asMethodType() {
0421: throw new AssertionError();
0422: }
0423:
0424: /** Complete loading all classes in this type.
0425: */
0426: public void complete() {
0427: }
0428:
0429: public Object clone() {
0430: try {
0431: return super .clone();
0432: } catch (CloneNotSupportedException e) {
0433: throw new AssertionError(e);
0434: }
0435: }
0436:
0437: public TypeSymbol asElement() {
0438: return tsym;
0439: }
0440:
0441: public TypeKind getKind() {
0442: switch (tag) {
0443: case BYTE:
0444: return TypeKind.BYTE;
0445: case CHAR:
0446: return TypeKind.CHAR;
0447: case SHORT:
0448: return TypeKind.SHORT;
0449: case INT:
0450: return TypeKind.INT;
0451: case LONG:
0452: return TypeKind.LONG;
0453: case FLOAT:
0454: return TypeKind.FLOAT;
0455: case DOUBLE:
0456: return TypeKind.DOUBLE;
0457: case BOOLEAN:
0458: return TypeKind.BOOLEAN;
0459: case VOID:
0460: return TypeKind.VOID;
0461: case BOT:
0462: return TypeKind.NULL;
0463: case NONE:
0464: return TypeKind.NONE;
0465: default:
0466: return TypeKind.OTHER;
0467: }
0468: }
0469:
0470: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
0471: if (isPrimitive())
0472: return v.visitPrimitive(this , p);
0473: else
0474: throw new AssertionError();
0475: }
0476:
0477: public static class WildcardType extends Type implements
0478: javax.lang.model.type.WildcardType {
0479:
0480: public Type type;
0481: public BoundKind kind;
0482: public TypeVar bound;
0483:
0484: @Override
0485: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0486: return v.visitWildcardType(this , s);
0487: }
0488:
0489: public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
0490: super (WILDCARD, tsym);
0491: assert (type != null);
0492: this .kind = kind;
0493: this .type = type;
0494: }
0495:
0496: public WildcardType(WildcardType t, TypeVar bound) {
0497: this (t.type, t.kind, t.tsym, bound);
0498: }
0499:
0500: public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
0501: TypeVar bound) {
0502: this (type, kind, tsym);
0503: this .bound = bound;
0504: }
0505:
0506: public boolean isSuperBound() {
0507: return kind == SUPER || kind == UNBOUND;
0508: }
0509:
0510: public boolean isExtendsBound() {
0511: return kind == EXTENDS || kind == UNBOUND;
0512: }
0513:
0514: public boolean isUnbound() {
0515: return kind == UNBOUND;
0516: }
0517:
0518: public Type withTypeVar(Type t) {
0519: //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
0520: if (bound == t)
0521: return this ;
0522: bound = (TypeVar) t;
0523: return this ;
0524: }
0525:
0526: boolean isPrintingBound = false;
0527:
0528: public String toString() {
0529: StringBuffer s = new StringBuffer();
0530: s.append(kind.toString());
0531: if (kind != UNBOUND)
0532: s.append(type);
0533: if (moreInfo && bound != null && !isPrintingBound)
0534: try {
0535: isPrintingBound = true;
0536: s.append("{:").append(bound.bound).append(":}");
0537: } finally {
0538: isPrintingBound = false;
0539: }
0540: return s.toString();
0541: }
0542:
0543: public Type map(Mapping f) {
0544: //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
0545: Type t = type;
0546: if (t != null)
0547: t = f.apply(t);
0548: if (t == type)
0549: return this ;
0550: else
0551: return new WildcardType(t, kind, tsym, bound);
0552: }
0553:
0554: public Type removeBounds() {
0555: return isUnbound() ? this : type;
0556: }
0557:
0558: public Type getExtendsBound() {
0559: if (kind == EXTENDS)
0560: return type;
0561: else
0562: return null;
0563: }
0564:
0565: public Type getSuperBound() {
0566: if (kind == SUPER)
0567: return type;
0568: else
0569: return null;
0570: }
0571:
0572: public TypeKind getKind() {
0573: return TypeKind.WILDCARD;
0574: }
0575:
0576: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
0577: return v.visitWildcard(this , p);
0578: }
0579: }
0580:
0581: public static class ClassType extends Type implements DeclaredType {
0582:
0583: /** The enclosing type of this type. If this is the type of an inner
0584: * class, outer_field refers to the type of its enclosing
0585: * instance class, in all other cases it referes to noType.
0586: */
0587: private Type outer_field;
0588:
0589: /** The type parameters of this type (to be set once class is loaded).
0590: */
0591: public List<Type> typarams_field;
0592:
0593: /** A cache variable for the type parameters of this type,
0594: * appended to all parameters of its enclosing class.
0595: * @see #allparams
0596: */
0597: public List<Type> allparams_field;
0598:
0599: /** The supertype of this class (to be set once class is loaded).
0600: */
0601: public Type super type_field;
0602:
0603: /** The interfaces of this class (to be set once class is loaded).
0604: */
0605: public List<Type> interfaces_field;
0606:
0607: public ClassType(Type outer, List<Type> typarams,
0608: TypeSymbol tsym) {
0609: super (CLASS, tsym);
0610: this .outer_field = outer;
0611: this .typarams_field = typarams;
0612: this .allparams_field = null;
0613: this .super type_field = null;
0614: this .interfaces_field = null;
0615: /*
0616: // this can happen during error recovery
0617: assert
0618: outer.isParameterized() ?
0619: typarams.length() == tsym.type.typarams().length() :
0620: outer.isRaw() ?
0621: typarams.length() == 0 :
0622: true;
0623: */
0624: }
0625:
0626: @Override
0627: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0628: return v.visitClassType(this , s);
0629: }
0630:
0631: public Type constType(Object constValue) {
0632: final Object value = constValue;
0633: return new ClassType(getEnclosingType(), typarams_field,
0634: tsym) {
0635: @Override
0636: public Object constValue() {
0637: return value;
0638: }
0639:
0640: @Override
0641: public Type baseType() {
0642: return tsym.type;
0643: }
0644: };
0645: }
0646:
0647: /** The Java source which this type represents.
0648: */
0649: public String toString() {
0650: StringBuffer buf = new StringBuffer();
0651: if (getEnclosingType().tag == CLASS
0652: && tsym.owner.kind == TYP) {
0653: buf.append(getEnclosingType().toString());
0654: buf.append(".");
0655: buf.append(className(tsym, false));
0656: } else {
0657: buf.append(className(tsym, true));
0658: }
0659: if (getTypeArguments().nonEmpty()) {
0660: buf.append('<');
0661: buf.append(getTypeArguments().toString());
0662: buf.append(">");
0663: }
0664: return buf.toString();
0665: }
0666:
0667: //where
0668: private String className(Symbol sym, boolean longform) {
0669: if (sym.name.len == 0 && (sym.flags() & COMPOUND) != 0) {
0670: StringBuffer s = new StringBuffer(super type_field
0671: .toString());
0672: for (List<Type> is = interfaces_field; is.nonEmpty(); is = is.tail) {
0673: s.append("&");
0674: s.append(is.head.toString());
0675: }
0676: return s.toString();
0677: } else if (sym.name.len == 0) {
0678: String s;
0679: ClassType norm = (ClassType) tsym.type;
0680: if (norm == null) {
0681: s = Log.getLocalizedString("anonymous.class",
0682: (Object) null);
0683: } else if (norm.interfaces_field != null
0684: && norm.interfaces_field.nonEmpty()) {
0685: s = Log.getLocalizedString("anonymous.class",
0686: norm.interfaces_field.head);
0687: } else {
0688: s = Log.getLocalizedString("anonymous.class",
0689: norm.super type_field);
0690: }
0691: if (moreInfo)
0692: s += String.valueOf(sym.hashCode());
0693: return s;
0694: } else if (longform) {
0695: return sym.getQualifiedName().toString();
0696: } else {
0697: return sym.name.toString();
0698: }
0699: }
0700:
0701: public List<Type> getTypeArguments() {
0702: if (typarams_field == null) {
0703: complete();
0704: if (typarams_field == null)
0705: typarams_field = List.nil();
0706: }
0707: return typarams_field;
0708: }
0709:
0710: public Type getEnclosingType() {
0711: return outer_field;
0712: }
0713:
0714: public void setEnclosingType(Type outer) {
0715: outer_field = outer;
0716: }
0717:
0718: public List<Type> allparams() {
0719: if (allparams_field == null) {
0720: allparams_field = getTypeArguments().prependList(
0721: getEnclosingType().allparams());
0722: }
0723: return allparams_field;
0724: }
0725:
0726: public boolean isErroneous() {
0727: return getEnclosingType().isErroneous()
0728: || isErroneous(getTypeArguments())
0729: || this != tsym.type && tsym.type.isErroneous();
0730: }
0731:
0732: public boolean isParameterized() {
0733: return allparams().tail != null;
0734: // optimization, was: allparams().nonEmpty();
0735: }
0736:
0737: /** A cache for the rank. */
0738: int rank_field = -1;
0739:
0740: /** A class type is raw if it misses some
0741: * of its type parameter sections.
0742: * After validation, this is equivalent to:
0743: * allparams.isEmpty() && tsym.type.allparams.nonEmpty();
0744: */
0745: public boolean isRaw() {
0746: return this != tsym.type
0747: && // necessary, but not sufficient condition
0748: tsym.type.allparams().nonEmpty()
0749: && allparams().isEmpty();
0750: }
0751:
0752: public Type map(Mapping f) {
0753: Type outer = getEnclosingType();
0754: Type outer1 = f.apply(outer);
0755: List<Type> typarams = getTypeArguments();
0756: List<Type> typarams1 = map(typarams, f);
0757: if (outer1 == outer && typarams1 == typarams)
0758: return this ;
0759: else
0760: return new ClassType(outer1, typarams1, tsym);
0761: }
0762:
0763: public boolean contains(Type elem) {
0764: return elem == this
0765: || (isParameterized() && (getEnclosingType()
0766: .contains(elem) || contains(
0767: getTypeArguments(), elem)));
0768: }
0769:
0770: public void complete() {
0771: if (tsym.completer != null)
0772: tsym.complete();
0773: }
0774:
0775: public TypeKind getKind() {
0776: return TypeKind.DECLARED;
0777: }
0778:
0779: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
0780: return v.visitDeclared(this , p);
0781: }
0782: }
0783:
0784: public static class ArrayType extends Type implements
0785: javax.lang.model.type.ArrayType {
0786:
0787: public Type elemtype;
0788:
0789: public ArrayType(Type elemtype, TypeSymbol arrayClass) {
0790: super (ARRAY, arrayClass);
0791: this .elemtype = elemtype;
0792: }
0793:
0794: @Override
0795: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0796: return v.visitArrayType(this , s);
0797: }
0798:
0799: public String toString() {
0800: return elemtype + "[]";
0801: }
0802:
0803: public boolean equals(Object obj) {
0804: return this == obj
0805: || (obj instanceof ArrayType && this .elemtype
0806: .equals(((ArrayType) obj).elemtype));
0807: }
0808:
0809: public int hashCode() {
0810: return (ARRAY << 5) + elemtype.hashCode();
0811: }
0812:
0813: public List<Type> allparams() {
0814: return elemtype.allparams();
0815: }
0816:
0817: public boolean isErroneous() {
0818: return elemtype.isErroneous();
0819: }
0820:
0821: public boolean isParameterized() {
0822: return elemtype.isParameterized();
0823: }
0824:
0825: public boolean isRaw() {
0826: return elemtype.isRaw();
0827: }
0828:
0829: public Type map(Mapping f) {
0830: Type elemtype1 = f.apply(elemtype);
0831: if (elemtype1 == elemtype)
0832: return this ;
0833: else
0834: return new ArrayType(elemtype1, tsym);
0835: }
0836:
0837: public boolean contains(Type elem) {
0838: return elem == this || elemtype.contains(elem);
0839: }
0840:
0841: public void complete() {
0842: elemtype.complete();
0843: }
0844:
0845: public Type getComponentType() {
0846: return elemtype;
0847: }
0848:
0849: public TypeKind getKind() {
0850: return TypeKind.ARRAY;
0851: }
0852:
0853: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
0854: return v.visitArray(this , p);
0855: }
0856: }
0857:
0858: public static class MethodType extends Type implements Cloneable,
0859: ExecutableType {
0860:
0861: public List<Type> argtypes;
0862: public Type restype;
0863: public List<Type> thrown;
0864:
0865: public MethodType(List<Type> argtypes, Type restype,
0866: List<Type> thrown, TypeSymbol methodClass) {
0867: super (METHOD, methodClass);
0868: this .argtypes = argtypes;
0869: this .restype = restype;
0870: this .thrown = thrown;
0871: }
0872:
0873: @Override
0874: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0875: return v.visitMethodType(this , s);
0876: }
0877:
0878: /** The Java source which this type represents.
0879: *
0880: * XXX 06/09/99 iris This isn't correct Java syntax, but it probably
0881: * should be.
0882: */
0883: public String toString() {
0884: return "(" + argtypes + ")" + restype;
0885: }
0886:
0887: public boolean equals(Object obj) {
0888: if (this == obj)
0889: return true;
0890: if (!(obj instanceof MethodType))
0891: return false;
0892: MethodType m = (MethodType) obj;
0893: List<Type> args1 = argtypes;
0894: List<Type> args2 = m.argtypes;
0895: while (!args1.isEmpty() && !args2.isEmpty()) {
0896: if (!args1.head.equals(args2.head))
0897: return false;
0898: args1 = args1.tail;
0899: args2 = args2.tail;
0900: }
0901: if (!args1.isEmpty() || !args2.isEmpty())
0902: return false;
0903: return restype.equals(m.restype);
0904: }
0905:
0906: public int hashCode() {
0907: int h = METHOD;
0908: for (List<Type> this args = this .argtypes; this args.tail != null; /*inlined: thisargs.nonEmpty()*/
0909: this args = this args.tail)
0910: h = (h << 5) + this args.head.hashCode();
0911: return (h << 5) + this .restype.hashCode();
0912: }
0913:
0914: public List<Type> getParameterTypes() {
0915: return argtypes;
0916: }
0917:
0918: public Type getReturnType() {
0919: return restype;
0920: }
0921:
0922: public List<Type> getThrownTypes() {
0923: return thrown;
0924: }
0925:
0926: public void setThrown(List<Type> t) {
0927: thrown = t;
0928: }
0929:
0930: public boolean isErroneous() {
0931: return isErroneous(argtypes) || restype != null
0932: && restype.isErroneous();
0933: }
0934:
0935: public Type map(Mapping f) {
0936: List<Type> argtypes1 = map(argtypes, f);
0937: Type restype1 = f.apply(restype);
0938: List<Type> thrown1 = map(thrown, f);
0939: if (argtypes1 == argtypes && restype1 == restype
0940: && thrown1 == thrown)
0941: return this ;
0942: else
0943: return new MethodType(argtypes1, restype1, thrown1,
0944: tsym);
0945: }
0946:
0947: public boolean contains(Type elem) {
0948: return elem == this || contains(argtypes, elem)
0949: || restype.contains(elem);
0950: }
0951:
0952: public MethodType asMethodType() {
0953: return this ;
0954: }
0955:
0956: public void complete() {
0957: for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
0958: l.head.complete();
0959: restype.complete();
0960: for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
0961: l.head.complete();
0962: }
0963:
0964: public List<TypeVar> getTypeVariables() {
0965: return List.nil();
0966: }
0967:
0968: public TypeSymbol asElement() {
0969: return null;
0970: }
0971:
0972: public TypeKind getKind() {
0973: return TypeKind.EXECUTABLE;
0974: }
0975:
0976: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
0977: return v.visitExecutable(this , p);
0978: }
0979: }
0980:
0981: public static class PackageType extends Type implements NoType {
0982:
0983: PackageType(TypeSymbol tsym) {
0984: super (PACKAGE, tsym);
0985: }
0986:
0987: @Override
0988: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
0989: return v.visitPackageType(this , s);
0990: }
0991:
0992: public String toString() {
0993: return tsym.getQualifiedName().toString();
0994: }
0995:
0996: public TypeKind getKind() {
0997: return TypeKind.PACKAGE;
0998: }
0999:
1000: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1001: return v.visitNoType(this , p);
1002: }
1003: }
1004:
1005: public static class TypeVar extends Type implements TypeVariable {
1006:
1007: /** The bound of this type variable; set from outside.
1008: * Must be nonempty once it is set.
1009: * For a bound, `bound' is the bound type itself.
1010: * Multiple bounds are expressed as a single class type which has the
1011: * individual bounds as superclass, respectively interfaces.
1012: * The class type then has as `tsym' a compiler generated class `c',
1013: * which has a flag COMPOUND and whose owner is the type variable
1014: * itself. Furthermore, the erasure_field of the class
1015: * points to the first class or interface bound.
1016: */
1017: public Type bound = null;
1018: public Type lower;
1019:
1020: public TypeVar(Name name, Symbol owner, Type lower) {
1021: super (TYPEVAR, null);
1022: tsym = new TypeSymbol(0, name, this , owner);
1023: this .lower = lower;
1024: }
1025:
1026: public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1027: super (TYPEVAR, tsym);
1028: this .bound = bound;
1029: this .lower = lower;
1030: }
1031:
1032: @Override
1033: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
1034: return v.visitTypeVar(this , s);
1035: }
1036:
1037: public Type getUpperBound() {
1038: return bound;
1039: }
1040:
1041: int rank_field = -1;
1042:
1043: public Type getLowerBound() {
1044: return lower;
1045: }
1046:
1047: public TypeKind getKind() {
1048: return TypeKind.TYPEVAR;
1049: }
1050:
1051: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1052: return v.visitTypeVariable(this , p);
1053: }
1054: }
1055:
1056: /** A captured type variable comes from wildcards which can have
1057: * both upper and lower bound. CapturedType extends TypeVar with
1058: * a lower bound.
1059: */
1060: public static class CapturedType extends TypeVar {
1061:
1062: public Type lower;
1063: public WildcardType wildcard;
1064:
1065: public CapturedType(Name name, Symbol owner, Type upper,
1066: Type lower, WildcardType wildcard) {
1067: super (name, owner, lower);
1068: assert lower != null;
1069: this .bound = upper;
1070: this .lower = lower;
1071: this .wildcard = wildcard;
1072: }
1073:
1074: @Override
1075: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
1076: return v.visitCapturedType(this , s);
1077: }
1078:
1079: public Type getLowerBound() {
1080: return lower;
1081: }
1082:
1083: @Override
1084: public String toString() {
1085: return "capture#" + (hashCode() & 0xFFFFFFFFL) % PRIME
1086: + " of " + wildcard;
1087: }
1088:
1089: static final int PRIME = 997; // largest prime less than 1000
1090: }
1091:
1092: public static abstract class DelegatedType extends Type {
1093: public Type qtype;
1094:
1095: public DelegatedType(int tag, Type qtype) {
1096: super (tag, qtype.tsym);
1097: this .qtype = qtype;
1098: }
1099:
1100: public String toString() {
1101: return qtype.toString();
1102: }
1103:
1104: public List<Type> getTypeArguments() {
1105: return qtype.getTypeArguments();
1106: }
1107:
1108: public Type getEnclosingType() {
1109: return qtype.getEnclosingType();
1110: }
1111:
1112: public List<Type> getParameterTypes() {
1113: return qtype.getParameterTypes();
1114: }
1115:
1116: public Type getReturnType() {
1117: return qtype.getReturnType();
1118: }
1119:
1120: public List<Type> getThrownTypes() {
1121: return qtype.getThrownTypes();
1122: }
1123:
1124: public List<Type> allparams() {
1125: return qtype.allparams();
1126: }
1127:
1128: public Type getUpperBound() {
1129: return qtype.getUpperBound();
1130: }
1131:
1132: public Object clone() {
1133: DelegatedType t = (DelegatedType) super .clone();
1134: t.qtype = (Type) qtype.clone();
1135: return t;
1136: }
1137:
1138: public boolean isErroneous() {
1139: return qtype.isErroneous();
1140: }
1141: }
1142:
1143: public static class ForAll extends DelegatedType implements
1144: Cloneable, ExecutableType {
1145: public List<Type> tvars;
1146:
1147: public ForAll(List<Type> tvars, Type qtype) {
1148: super (FORALL, qtype);
1149: this .tvars = tvars;
1150: }
1151:
1152: @Override
1153: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
1154: return v.visitForAll(this , s);
1155: }
1156:
1157: public String toString() {
1158: return "<" + tvars + ">" + qtype;
1159: }
1160:
1161: public List<Type> getTypeArguments() {
1162: return tvars;
1163: }
1164:
1165: public void setThrown(List<Type> t) {
1166: qtype.setThrown(t);
1167: }
1168:
1169: public Object clone() {
1170: ForAll result = (ForAll) super .clone();
1171: result.qtype = (Type) result.qtype.clone();
1172: return result;
1173: }
1174:
1175: public boolean isErroneous() {
1176: return qtype.isErroneous();
1177: }
1178:
1179: public Type map(Mapping f) {
1180: return f.apply(qtype);
1181: }
1182:
1183: public boolean contains(Type elem) {
1184: return qtype.contains(elem);
1185: }
1186:
1187: public MethodType asMethodType() {
1188: return qtype.asMethodType();
1189: }
1190:
1191: public void complete() {
1192: for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1193: ((TypeVar) l.head).bound.complete();
1194: }
1195: qtype.complete();
1196: }
1197:
1198: public List<TypeVar> getTypeVariables() {
1199: return List.convert(TypeVar.class, getTypeArguments());
1200: }
1201:
1202: public TypeKind getKind() {
1203: return TypeKind.EXECUTABLE;
1204: }
1205:
1206: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1207: return v.visitExecutable(this , p);
1208: }
1209: }
1210:
1211: /** A class for instantiatable variables, for use during type
1212: * inference.
1213: */
1214: public static class UndetVar extends DelegatedType {
1215: public List<Type> lobounds = List.nil();
1216: public List<Type> hibounds = List.nil();
1217: public Type inst = null;
1218:
1219: @Override
1220: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
1221: return v.visitUndetVar(this , s);
1222: }
1223:
1224: public UndetVar(Type origin) {
1225: super (UNDETVAR, origin);
1226: }
1227:
1228: public String toString() {
1229: if (inst != null)
1230: return inst.toString();
1231: else
1232: return qtype + "?";
1233: }
1234:
1235: public Type baseType() {
1236: if (inst != null)
1237: return inst.baseType();
1238: else
1239: return this ;
1240: }
1241: }
1242:
1243: /** Represents VOID or NONE.
1244: */
1245: static class JCNoType extends Type implements NoType {
1246: public JCNoType(int tag) {
1247: super (tag, null);
1248: }
1249:
1250: @Override
1251: public TypeKind getKind() {
1252: switch (tag) {
1253: case VOID:
1254: return TypeKind.VOID;
1255: case NONE:
1256: return TypeKind.NONE;
1257: default:
1258: throw new AssertionError("Unexpected tag: " + tag);
1259: }
1260: }
1261:
1262: @Override
1263: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1264: return v.visitNoType(this , p);
1265: }
1266: }
1267:
1268: static class BottomType extends Type implements NullType {
1269: public BottomType() {
1270: super (TypeTags.BOT, null);
1271: }
1272:
1273: @Override
1274: public TypeKind getKind() {
1275: return TypeKind.NULL;
1276: }
1277:
1278: @Override
1279: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1280: return v.visitNull(this , p);
1281: }
1282:
1283: @Override
1284: public Type constType(Object value) {
1285: return this ;
1286: }
1287:
1288: @Override
1289: public String stringValue() {
1290: return "null";
1291: }
1292: }
1293:
1294: public static class ErrorType extends ClassType implements
1295: javax.lang.model.type.ErrorType {
1296:
1297: public ErrorType() {
1298: super (noType, List.<Type> nil(), null);
1299: tag = ERROR;
1300: }
1301:
1302: public ErrorType(ClassSymbol c) {
1303: this ();
1304: tsym = c;
1305: c.type = this ;
1306: c.kind = ERR;
1307: c.members_field = new Scope.ErrorScope(c);
1308: }
1309:
1310: public ErrorType(Name name, TypeSymbol container) {
1311: this (new ClassSymbol(PUBLIC | STATIC | ACYCLIC, name, null,
1312: container));
1313: }
1314:
1315: @Override
1316: public <R, S> R accept(Type.Visitor<R, S> v, S s) {
1317: return v.visitErrorType(this , s);
1318: }
1319:
1320: public Type constType(Object constValue) {
1321: return this ;
1322: }
1323:
1324: public Type getEnclosingType() {
1325: return this ;
1326: }
1327:
1328: public Type getReturnType() {
1329: return this ;
1330: }
1331:
1332: public Type asSub(Symbol sym) {
1333: return this ;
1334: }
1335:
1336: public Type map(Mapping f) {
1337: return this ;
1338: }
1339:
1340: public boolean isGenType(Type t) {
1341: return true;
1342: }
1343:
1344: public boolean isErroneous() {
1345: return true;
1346: }
1347:
1348: public boolean isCompound() {
1349: return false;
1350: }
1351:
1352: public boolean isInterface() {
1353: return false;
1354: }
1355:
1356: public List<Type> allparams() {
1357: return List.nil();
1358: }
1359:
1360: public List<Type> getTypeArguments() {
1361: return List.nil();
1362: }
1363:
1364: public TypeKind getKind() {
1365: return TypeKind.ERROR;
1366: }
1367:
1368: public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1369: return v.visitError(this , p);
1370: }
1371: }
1372:
1373: /**
1374: * A visitor for types. A visitor is used to implement operations
1375: * (or relations) on types. Most common operations on types are
1376: * binary relations and this interface is designed for binary
1377: * relations, that is, operations on the form
1378: * Type × S → R.
1379: * <!-- In plain text: Type x S -> R -->
1380: *
1381: * @param <R> the return type of the operation implemented by this
1382: * visitor; use Void if no return type is needed.
1383: * @param <S> the type of the second argument (the first being the
1384: * type itself) of the operation implemented by this visitor; use
1385: * Void if a second argument is not needed.
1386: */
1387: public interface Visitor<R, S> {
1388: R visitClassType(ClassType t, S s);
1389:
1390: R visitWildcardType(WildcardType t, S s);
1391:
1392: R visitArrayType(ArrayType t, S s);
1393:
1394: R visitMethodType(MethodType t, S s);
1395:
1396: R visitPackageType(PackageType t, S s);
1397:
1398: R visitTypeVar(TypeVar t, S s);
1399:
1400: R visitCapturedType(CapturedType t, S s);
1401:
1402: R visitForAll(ForAll t, S s);
1403:
1404: R visitUndetVar(UndetVar t, S s);
1405:
1406: R visitErrorType(ErrorType t, S s);
1407:
1408: R visitType(Type t, S s);
1409: }
1410: }
|