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 
TypeTag()138     private TypeTag() {
139         this(0, 0, false);
140     }
141 
TypeTag(int numericClass, int superClasses, boolean isPrimitive)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 
isStrictSubRangeOf(TypeTag tag)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 
isSubRangeOf(TypeTag tag)181     public boolean isSubRangeOf(TypeTag tag) {
182         return (this.superClasses & tag.numericClass) != 0;
183     }
184 
185     /** Returns the number of type tags.
186      */
getTypeTagCount()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 
getKindLiteral()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 
getPrimitiveTypeKind()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 }
241