src/share/classes/com/sun/tools/javac/code/TypeTag.java

changeset 1826
9851071b551a
parent 1442
fcf89720ae71
child 1853
831467c4c6a7
equal deleted inserted replaced
1825:e701af23a095 1826:9851071b551a
1 /* 1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this 7 * published by the Free Software Foundation. Oracle designates this
26 package com.sun.tools.javac.code; 26 package com.sun.tools.javac.code;
27 27
28 import com.sun.source.tree.Tree.Kind; 28 import com.sun.source.tree.Tree.Kind;
29 29
30 import javax.lang.model.type.TypeKind; 30 import javax.lang.model.type.TypeKind;
31
32 import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
31 33
32 /** An interface for type tag values, which distinguish between different 34 /** An interface for type tag values, which distinguish between different
33 * sorts of types. 35 * sorts of types.
34 * 36 *
35 * <p><b>This is NOT part of any supported API. 37 * <p><b>This is NOT part of any supported API.
38 * deletion without notice.</b> 40 * deletion without notice.</b>
39 */ 41 */
40 public enum TypeTag { 42 public enum TypeTag {
41 /** The tag of the basic type `byte'. 43 /** The tag of the basic type `byte'.
42 */ 44 */
43 BYTE(1), 45 BYTE(BYTE_CLASS, BYTE_SUPERCLASSES,
46 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
44 47
45 /** The tag of the basic type `char'. 48 /** The tag of the basic type `char'.
46 */ 49 */
47 CHAR(2), 50 CHAR(CHAR_CLASS, CHAR_SUPERCLASSES,
51 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
48 52
49 /** The tag of the basic type `short'. 53 /** The tag of the basic type `short'.
50 */ 54 */
51 SHORT(3), 55 SHORT(SHORT_CLASS, SHORT_SUPERCLASSES,
56 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
52 57
53 /** The tag of the basic type `int'. 58 /** The tag of the basic type `int'.
54 */ 59 */
55 INT(4), 60 INT(INT_CLASS, INT_SUPERCLASSES,
61 TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
56 62
57 /** The tag of the basic type `long'. 63 /** The tag of the basic type `long'.
58 */ 64 */
59 LONG(5), 65 LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
60 66
61 /** The tag of the basic type `float'. 67 /** The tag of the basic type `float'.
62 */ 68 */
63 FLOAT(6), 69 FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
64 70
65 /** The tag of the basic type `double'. 71 /** The tag of the basic type `double'.
66 */ 72 */
67 DOUBLE(7), 73 DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC),
68 74
69 /** The tag of the basic type `boolean'. 75 /** The tag of the basic type `boolean'.
70 */ 76 */
71 BOOLEAN, 77 BOOLEAN(TypeTagKind.PRIMITIVE),
72 78
73 /** The tag of the type `void'. 79 /** The tag of the type `void'.
74 */ 80 */
75 VOID, 81 VOID(TypeTagKind.VOID),
76 82
77 /** The tag of all class and interface types. 83 /** The tag of all class and interface types.
78 */ 84 */
79 CLASS, 85 CLASS(TypeTagKind.REFERENCE),
80 86
81 /** The tag of all array types. 87 /** The tag of all array types.
82 */ 88 */
83 ARRAY, 89 ARRAY(TypeTagKind.REFERENCE),
84 90
85 /** The tag of all (monomorphic) method types. 91 /** The tag of all (monomorphic) method types.
86 */ 92 */
87 METHOD, 93 METHOD(TypeTagKind.OTHER),
88 94
89 /** The tag of all package "types". 95 /** The tag of all package "types".
90 */ 96 */
91 PACKAGE, 97 PACKAGE(TypeTagKind.OTHER),
92 98
93 /** The tag of all (source-level) type variables. 99 /** The tag of all (source-level) type variables.
94 */ 100 */
95 TYPEVAR, 101 TYPEVAR(TypeTagKind.REFERENCE),
96 102
97 /** The tag of all type arguments. 103 /** The tag of all type arguments.
98 */ 104 */
99 WILDCARD, 105 WILDCARD(TypeTagKind.REFERENCE),
100 106
101 /** The tag of all polymorphic (method-) types. 107 /** The tag of all polymorphic (method-) types.
102 */ 108 */
103 FORALL, 109 FORALL(TypeTagKind.OTHER),
104 110
105 /** The tag of deferred expression types in method context 111 /** The tag of deferred expression types in method context
106 */ 112 */
107 DEFERRED, 113 DEFERRED(TypeTagKind.OTHER),
108 114
109 /** The tag of the bottom type {@code <null>}. 115 /** The tag of the bottom type {@code <null>}.
110 */ 116 */
111 BOT, 117 BOT(TypeTagKind.OTHER),
112 118
113 /** The tag of a missing type. 119 /** The tag of a missing type.
114 */ 120 */
115 NONE, 121 NONE(TypeTagKind.OTHER),
116 122
117 /** The tag of the error type. 123 /** The tag of the error type.
118 */ 124 */
119 ERROR, 125 ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL),
120 126
121 /** The tag of an unknown type 127 /** The tag of an unknown type
122 */ 128 */
123 UNKNOWN, 129 UNKNOWN(TypeTagKind.PARTIAL),
124 130
125 /** The tag of all instantiatable type variables. 131 /** The tag of all instantiatable type variables.
126 */ 132 */
127 UNDETVAR, 133 UNDETVAR(TypeTagKind.PARTIAL),
128 134
129 /** Pseudo-types, these are special tags 135 /** Pseudo-types, these are special tags
130 */ 136 */
131 UNINITIALIZED_THIS, 137 UNINITIALIZED_THIS(TypeTagKind.OTHER),
132 138
133 UNINITIALIZED_OBJECT; 139 UNINITIALIZED_OBJECT(TypeTagKind.OTHER);
134 140
135 /** This field will only be used for tags related with numeric types for 141 final boolean isPrimitive;
136 * optimization reasons. 142 final boolean isNumeric;
137 */ 143 final boolean isPartial;
138 private final int order; 144 final boolean isReference;
139 145 final boolean isPrimitiveOrVoid;
140 private TypeTag() { 146 final int superClasses;
141 this(0); 147 final int numericClass;
142 } 148
143 149 private TypeTag(int kind) {
144 private TypeTag(int order) { 150 this(0, 0, kind);
145 this.order = order; 151 }
146 } 152
147 153 private TypeTag(int numericClass, int superClasses, int kind) {
148 private static final int MIN_NUMERIC_TAG_ORDER = 1; 154 isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0;
149 private static final int MAX_NUMERIC_TAG_ORDER = 7; 155 isNumeric = (kind & TypeTagKind.NUMERIC) != 0;
156 isPartial = (kind & TypeTagKind.PARTIAL) != 0;
157 isReference = (kind & TypeTagKind.REFERENCE) != 0;
158 isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) ||
159 ((kind & TypeTagKind.VOID) != 0);
160 this.superClasses = superClasses;
161 this.numericClass = numericClass;
162 }
163
164 static class TypeTagKind {
165 static final int PRIMITIVE = 1;
166 static final int NUMERIC = 2;
167 static final int REFERENCE = 4;
168 static final int PARTIAL = 8;
169 static final int OTHER = 16;
170 static final int VOID = 32;
171 }
172
173 public static class NumericClasses {
174 public static final int BYTE_CLASS = 1;
175 public static final int CHAR_CLASS = 2;
176 public static final int SHORT_CLASS = 4;
177 public static final int INT_CLASS = 8;
178 public static final int LONG_CLASS = 16;
179 public static final int FLOAT_CLASS = 32;
180 public static final int DOUBLE_CLASS = 64;
181
182 static final int BYTE_SUPERCLASSES = BYTE_CLASS | SHORT_CLASS | INT_CLASS |
183 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
184
185 static final int CHAR_SUPERCLASSES = CHAR_CLASS | INT_CLASS |
186 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
187
188 static final int SHORT_SUPERCLASSES = SHORT_CLASS | INT_CLASS |
189 LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
190
191 static final int INT_SUPERCLASSES = INT_CLASS | LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
192
193 static final int LONG_SUPERCLASSES = LONG_CLASS | FLOAT_CLASS | DOUBLE_CLASS;
194
195 static final int FLOAT_SUPERCLASSES = FLOAT_CLASS | DOUBLE_CLASS;
196 }
197
198 public boolean isStrictSubRangeOf(TypeTag tag) {
199 /* Please don't change the implementation of this method to call method
200 * isSubRangeOf. Both methods are called from hotspot code, the current
201 * implementation is better performance-wise than the commented modification.
202 */
203 return (this.superClasses & tag.numericClass) != 0 && this != tag;
204 }
205
206 public boolean isSubRangeOf(TypeTag tag) {
207 return (this.superClasses & tag.numericClass) != 0;
208 }
150 209
151 /** Returns the number of type tags. 210 /** Returns the number of type tags.
152 */ 211 */
153 public static int getTypeTagCount() { 212 public static int getTypeTagCount() {
154 // last two tags are not included in the total as long as they are pseudo-types 213 // last two tags are not included in the total as long as they are pseudo-types
155 return (UNDETVAR.ordinal() + 1); 214 return (UNDETVAR.ordinal() + 1);
156 }
157
158 public boolean isSubRangeOf(TypeTag range) {
159 return (this == range) || isStrictSubRangeOf(range);
160 }
161
162 public boolean isStrictSubRangeOf(TypeTag range) {
163 if (this.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER &&
164 range.order >= MIN_NUMERIC_TAG_ORDER && this.order <= MAX_NUMERIC_TAG_ORDER) {
165 if (this == range)
166 return false;
167 switch (this) {
168 case BYTE:
169 return true;
170 case CHAR: case SHORT: case INT:
171 case LONG: case FLOAT:
172 return this.order < range.order && range.order <= MAX_NUMERIC_TAG_ORDER;
173 default:
174 return false;
175 }
176 }
177 else
178 return false;
179 } 215 }
180 216
181 public Kind getKindLiteral() { 217 public Kind getKindLiteral() {
182 switch (this) { 218 switch (this) {
183 case INT: 219 case INT:

mercurial