View Javadoc
1   /*
2    * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package com.sun.tools.javac.code;
27  
28  import com.sun.source.tree.Tree.Kind;
29  
30  import javax.lang.model.type.TypeKind;
31  
32  import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
33  
34  /** An interface for type tag values, which distinguish between different
35   *  sorts of types.
36   *
37   *  <p><b>This is NOT part of any supported API.
38   *  If you write code that depends on this, you do so at your own risk.
39   *  This code and its internal interfaces are subject to change or
40   *  deletion without notice.</b>
41   */
42  public enum TypeTag {
43      /** The tag of the basic type `byte'.
44       */
45      BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, true),
46  
47      /** The tag of the basic type `char'.
48       */
49      CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, true),
50  
51      /** The tag of the basic type `short'.
52       */
53      SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, true),
54  
55      /** The tag of the basic type `long'.
56       */
57      LONG(LONG_CLASS, LONG_SUPERCLASSES, true),
58  
59      /** The tag of the basic type `float'.
60       */
61      FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, true),
62      /** The tag of the basic type `int'.
63       */
64      INT(INT_CLASS, INT_SUPERCLASSES, true),
65      /** The tag of the basic type `double'.
66       */
67      DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, true),
68      /** The tag of the basic type `boolean'.
69       */
70      BOOLEAN(0, 0, true),
71  
72      /** The tag of the type `void'.
73       */
74      VOID,
75  
76      /** The tag of all class and interface types.
77       */
78      CLASS,
79  
80      /** The tag of all array types.
81       */
82      ARRAY,
83  
84      /** The tag of all (monomorphic) method types.
85       */
86      METHOD,
87  
88      /** The tag of all package "types".
89       */
90      PACKAGE,
91  
92      /** The tag of all (source-level) type variables.
93       */
94      TYPEVAR,
95  
96      /** The tag of all type arguments.
97       */
98      WILDCARD,
99  
100     /** The tag of all polymorphic (method-) types.
101      */
102     FORALL,
103 
104     /** The tag of deferred expression types in method context
105      */
106     DEFERRED,
107 
108     /** The tag of the bottom type {@code <null>}.
109      */
110     BOT,
111 
112     /** The tag of a missing type.
113      */
114     NONE,
115 
116     /** The tag of the error type.
117      */
118     ERROR,
119 
120     /** The tag of an unknown type
121      */
122     UNKNOWN,
123 
124     /** The tag of all instantiatable type variables.
125      */
126     UNDETVAR,
127 
128     /** Pseudo-types, these are special tags
129      */
130     UNINITIALIZED_THIS,
131 
132     UNINITIALIZED_OBJECT;
133 
134     final int superClasses;
135     final int numericClass;
136     final boolean isPrimitive;
137 
138     private TypeTag() {
139         this(0, 0, false);
140     }
141 
142     private TypeTag(int numericClass, int superClasses, boolean isPrimitive) {
143         this.superClasses = superClasses;
144         this.numericClass = numericClass;
145         this.isPrimitive = isPrimitive;
146     }
147 
148     public static class NumericClasses {
149         public static final int BYTE_CLASS = 1;
150         public static final int CHAR_CLASS = 2;
151         public static final int SHORT_CLASS = 4;
152         public static final int INT_CLASS = 8;
153         public static final int LONG_CLASS = 16;
154         public static final int FLOAT_CLASS = 32;
155         public static final int DOUBLE_CLASS = 64;
156 
157         static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS |
158                 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
159 
160         static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS |
161                 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
162 
163         static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS |
164                 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
165 
166         static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
167 
168         static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
169 
170         static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS;
171     }
172 
173     public boolean isStrictSubRangeOf(TypeTag tag) {
174         /*  Please don't change the implementation of this method to call method
175          *  isSubRangeOf. Both methods are called from hotspot code, the current
176          *  implementation is better performance-wise than the commented modification.
177          */
178         return (this.superClasses & tag.numericClass) != 0 && this != tag;
179     }
180 
181     public boolean isSubRangeOf(TypeTag tag) {
182         return (this.superClasses & tag.numericClass) != 0;
183     }
184 
185     /** Returns the number of type tags.
186      */
187     public static int getTypeTagCount() {
188         // last two tags are not included in the total as long as they are pseudo-types
189         return (UNDETVAR.ordinal() + 1);
190     }
191 
192     public Kind getKindLiteral() {
193         switch (this) {
194         case INT:
195             return Kind.INT_LITERAL;
196         case LONG:
197             return Kind.LONG_LITERAL;
198         case FLOAT:
199             return Kind.FLOAT_LITERAL;
200         case DOUBLE:
201             return Kind.DOUBLE_LITERAL;
202         case BOOLEAN:
203             return Kind.BOOLEAN_LITERAL;
204         case CHAR:
205             return Kind.CHAR_LITERAL;
206         case CLASS:
207             return Kind.STRING_LITERAL;
208         case BOT:
209             return Kind.NULL_LITERAL;
210         default:
211             throw new AssertionError("unknown literal kind " + this);
212         }
213     }
214 
215     public TypeKind getPrimitiveTypeKind() {
216         switch (this) {
217         case BOOLEAN:
218             return TypeKind.BOOLEAN;
219         case BYTE:
220             return TypeKind.BYTE;
221         case SHORT:
222             return TypeKind.SHORT;
223         case INT:
224             return TypeKind.INT;
225         case LONG:
226             return TypeKind.LONG;
227         case CHAR:
228             return TypeKind.CHAR;
229         case FLOAT:
230             return TypeKind.FLOAT;
231         case DOUBLE:
232             return TypeKind.DOUBLE;
233         case VOID:
234             return TypeKind.VOID;
235         default:
236             throw new AssertionError("unknown primitive type " + this);
237         }
238     }
239 
240 }