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