TypeTag.java revision 3850:8e69054abeeb
1/* 2 * Copyright (c) 1999, 2014, 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 26package com.sun.tools.javac.code; 27 28import com.sun.source.tree.Tree.Kind; 29 30import javax.lang.model.type.TypeKind; 31 32import 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 */ 42public 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 module "types". 93 */ 94 MODULE, 95 96 /** The tag of all (source-level) type variables. 97 */ 98 TYPEVAR, 99 100 /** The tag of all type arguments. 101 */ 102 WILDCARD, 103 104 /** The tag of all polymorphic (method-) types. 105 */ 106 FORALL, 107 108 /** The tag of deferred expression types in method context 109 */ 110 DEFERRED, 111 112 /** The tag of the bottom type {@code <null>}. 113 */ 114 BOT, 115 116 /** The tag of a missing type. 117 */ 118 NONE, 119 120 /** The tag of the error type. 121 */ 122 ERROR, 123 124 /** The tag of an unknown type 125 */ 126 UNKNOWN, 127 128 /** The tag of all instantiatable type variables. 129 */ 130 UNDETVAR, 131 132 /** Pseudo-types, these are special tags 133 */ 134 UNINITIALIZED_THIS, 135 136 UNINITIALIZED_OBJECT; 137 138 final int superClasses; 139 final int numericClass; 140 final boolean isPrimitive; 141 142 private TypeTag() { 143 this(0, 0, false); 144 } 145 146 private TypeTag(int numericClass, int superClasses, boolean isPrimitive) { 147 this.superClasses = superClasses; 148 this.numericClass = numericClass; 149 this.isPrimitive = isPrimitive; 150 } 151 152 public static class NumericClasses { 153 public static final int BYTE_CLASS = 1; 154 public static final int CHAR_CLASS = 2; 155 public static final int SHORT_CLASS = 4; 156 public static final int INT_CLASS = 8; 157 public static final int LONG_CLASS = 16; 158 public static final int FLOAT_CLASS = 32; 159 public static final int DOUBLE_CLASS = 64; 160 161 static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS | 162 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 163 164 static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS | 165 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 166 167 static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS | 168 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 169 170 static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 171 172 static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS; 173 174 static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS; 175 } 176 177 public boolean isStrictSubRangeOf(TypeTag tag) { 178 /* Please don't change the implementation of this method to call method 179 * isSubRangeOf. Both methods are called from hotspot code, the current 180 * implementation is better performance-wise than the commented modification. 181 */ 182 return (this.superClasses & tag.numericClass) != 0 && this != tag; 183 } 184 185 public boolean isSubRangeOf(TypeTag tag) { 186 return (this.superClasses & tag.numericClass) != 0; 187 } 188 189 /** Returns the number of type tags. 190 */ 191 public static int getTypeTagCount() { 192 // last two tags are not included in the total as long as they are pseudo-types 193 return (UNDETVAR.ordinal() + 1); 194 } 195 196 public Kind getKindLiteral() { 197 switch (this) { 198 case INT: 199 return Kind.INT_LITERAL; 200 case LONG: 201 return Kind.LONG_LITERAL; 202 case FLOAT: 203 return Kind.FLOAT_LITERAL; 204 case DOUBLE: 205 return Kind.DOUBLE_LITERAL; 206 case BOOLEAN: 207 return Kind.BOOLEAN_LITERAL; 208 case CHAR: 209 return Kind.CHAR_LITERAL; 210 case CLASS: 211 return Kind.STRING_LITERAL; 212 case BOT: 213 return Kind.NULL_LITERAL; 214 default: 215 throw new AssertionError("unknown literal kind " + this); 216 } 217 } 218 219 public TypeKind getPrimitiveTypeKind() { 220 switch (this) { 221 case BOOLEAN: 222 return TypeKind.BOOLEAN; 223 case BYTE: 224 return TypeKind.BYTE; 225 case SHORT: 226 return TypeKind.SHORT; 227 case INT: 228 return TypeKind.INT; 229 case LONG: 230 return TypeKind.LONG; 231 case CHAR: 232 return TypeKind.CHAR; 233 case FLOAT: 234 return TypeKind.FLOAT; 235 case DOUBLE: 236 return TypeKind.DOUBLE; 237 case VOID: 238 return TypeKind.VOID; 239 default: 240 throw new AssertionError("unknown primitive type " + this); 241 } 242 } 243 244 /** Returns true if the given value is within the allowed range for this type. */ 245 public boolean checkRange(int value) { 246 switch (this) { 247 case BOOLEAN: 248 return 0 <= value && value <= 1; 249 case BYTE: 250 return Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE; 251 case CHAR: 252 return Character.MIN_VALUE <= value && value <= Character.MAX_VALUE; 253 case SHORT: 254 return Short.MIN_VALUE <= value && value <= Short.MAX_VALUE; 255 case INT: 256 return true; 257 default: 258 throw new AssertionError(); 259 } 260 } 261} 262