Kinds.java revision 3294:9adfb22ff08f
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. Oracle designates this 81541Srgrimes * particular file as subject to the "Classpath" exception as provided 91541Srgrimes * by Oracle in the LICENSE file that accompanied this code. 101541Srgrimes * 111541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 121541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 151541Srgrimes * accompanied this code). 161541Srgrimes * 171541Srgrimes * You should have received a copy of the GNU General Public License version 181541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 191541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201541Srgrimes * 211541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 221541Srgrimes * or visit www.oracle.com if you need additional information or have any 231541Srgrimes * questions. 241541Srgrimes */ 251541Srgrimes 261541Srgrimespackage com.sun.tools.javac.code; 271541Srgrimes 281541Srgrimesimport java.util.EnumSet; 291541Srgrimesimport java.util.Set; 301541Srgrimesimport java.util.Locale; 311541Srgrimes 321541Srgrimesimport com.sun.source.tree.MemberReferenceTree; 331541Srgrimesimport com.sun.tools.javac.api.Formattable; 341541Srgrimesimport com.sun.tools.javac.api.Messages; 3550477Speter 361541Srgrimesimport static com.sun.tools.javac.code.Flags.*; 371541Srgrimesimport static com.sun.tools.javac.code.TypeTag.CLASS; 382165Spaulimport static com.sun.tools.javac.code.TypeTag.PACKAGE; 392165Spaulimport static com.sun.tools.javac.code.TypeTag.TYPEVAR; 402165Spaul 41221059Skib/** Internal symbol kinds, which distinguish between elements of 4229683Sgibbs * different subclasses of Symbol. Symbol kinds are organized so they can be 4344510Swollman * or'ed to sets. 4450673Sjlemon * 4550673Sjlemon * <p><b>This is NOT part of any supported API. 4668889Sjake * If you write code that depends on this, you do so at your own risk. 47141428Siedowse * This code and its internal interfaces are subject to change or 48173760Sattilio * deletion without notice.</b> 49234952Skib */ 50247777Sdavidepublic class Kinds { 51247777Sdavide 5244510Swollman private Kinds() {} // uninstantiable 53247777Sdavide 54247777Sdavide /** 55247777Sdavide * Kind of symbols. 56247777Sdavide * 57247777Sdavide * IMPORTANT: This is an ordered type. The ordering of 58247777Sdavide * declarations in this enum matters. Be careful when changing 59247777Sdavide * it. 60247777Sdavide */ 6183045Sobrien public enum Kind { 6229683Sgibbs NIL(Category.BASIC, KindSelector.NIL), 6329683Sgibbs PCK(Category.BASIC, KindName.PACKAGE, KindSelector.PCK), 6429683Sgibbs TYP(Category.BASIC, KindName.CLASS, KindSelector.TYP), 6555205Speter VAR(Category.BASIC, KindName.VAR, KindSelector.VAR), 6650673Sjlemon MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH), 6750673Sjlemon POLY(Category.BASIC, KindSelector.POLY), 68128485Scperciva MDL(Category.BASIC, KindSelector.MDL), 6992719Salfred ERR(Category.ERROR, KindSelector.ERR), 70173760Sattilio AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded target 71173760Sattilio HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target 72173760Sattilio STATICERR(Category.RESOLUTION_TARGET), // overloaded? target 73173760Sattilio MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target 74254712Sdavide ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target 75271065Sgavin WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target 76254703Sdavide WRONG_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded target 77173760Sattilio ABSENT_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded non-target 78173760Sattilio ABSENT_TYP(Category.RESOLUTION_TARGET, KindName.CLASS); // not overloaded non-target 79173760Sattilio 8050673Sjlemon // There are essentially two "levels" to the Kind datatype. 81247777Sdavide // The first is a totally-ordered set of categories of 82247777Sdavide // solutions. Within each category, we have more 83247777Sdavide // possibilities. 84247777Sdavide private enum Category { 85247777Sdavide BASIC, ERROR, RESOLUTION, RESOLUTION_TARGET; 86247777Sdavide } 87247777Sdavide 88247777Sdavide private final KindName kindName; 89247777Sdavide private final KindName absentKind; 90177859Sjeff private final KindSelector selector; 91177859Sjeff private final Category category; 92177859Sjeff 93177859Sjeff private Kind(Category category) { 94181191Ssam this(category, null, null, null); 95181191Ssam } 96181191Ssam 97181191Ssam private Kind(Category category, 98127969Scperciva KindSelector selector) { 99127969Scperciva this(category, null, null, selector); 100247777Sdavide } 10144510Swollman 10255205Speter private Kind(Category category, 1032165Spaul KindName absentKind) { 10429683Sgibbs this(category, null, absentKind, null); 105 } 106 107 private Kind(Category category, 108 KindName kindName, 109 KindSelector selector) { 110 this(category, kindName, null, selector); 111 } 112 113 private Kind(Category category, 114 KindName kindName, 115 KindName absentKind, 116 KindSelector selector) { 117 this.category = category; 118 this.kindName = kindName; 119 this.absentKind = absentKind; 120 this.selector = selector; 121 } 122 123 public KindSelector toSelector() { 124 return selector; 125 } 126 127 public boolean matches(KindSelector kindSelectors) { 128 return selector.contains(kindSelectors); 129 } 130 131 public boolean isResolutionError() { 132 return category == Category.RESOLUTION || category == Category.RESOLUTION_TARGET; 133 } 134 135 public boolean isResolutionTargetError() { 136 return category == Category.RESOLUTION_TARGET; 137 } 138 139 public boolean isValid() { 140 return category == Category.BASIC; 141 } 142 143 public boolean betterThan(Kind other) { 144 return ordinal() < other.ordinal(); 145 } 146 147 public KindName kindName() { 148 if (kindName == null) { 149 throw new AssertionError("Unexpected kind: " + this); 150 } else { 151 return kindName; 152 } 153 } 154 155 public KindName absentKind() { 156 if (absentKind == null) { 157 throw new AssertionError("Unexpected kind: " + this); 158 } else { 159 return absentKind; 160 } 161 } 162 } 163 164 public static class KindSelector { 165 166 //basic selectors 167 public static final KindSelector NIL = new KindSelector(0); 168 public static final KindSelector PCK = new KindSelector(0x01); 169 public static final KindSelector TYP = new KindSelector(0x02); 170 public static final KindSelector VAR = new KindSelector(0x04); 171 public static final KindSelector VAL = new KindSelector(0x0c); 172 public static final KindSelector MTH = new KindSelector(0x10); 173 public static final KindSelector POLY = new KindSelector(0x20); 174 public static final KindSelector MDL = new KindSelector(0x40); 175 public static final KindSelector ERR = new KindSelector(0x7f); 176 public static final KindSelector ASG = new KindSelector(0x84); 177 178 //common derived selectors 179 public static final KindSelector TYP_PCK = of(TYP, PCK); 180 public static final KindSelector VAL_MTH = of(VAL, MTH); 181 public static final KindSelector VAL_POLY = of(VAL, POLY); 182 public static final KindSelector VAL_TYP = of(VAL, TYP); 183 public static final KindSelector VAL_TYP_PCK = of(VAL, TYP, PCK); 184 185 private final byte data; 186 187 private KindSelector(int data) { 188 this.data = (byte) data; 189 } 190 191 public static KindSelector of(KindSelector... kindSelectors) { 192 byte newData = 0; 193 for (KindSelector kindSel : kindSelectors) { 194 newData |= kindSel.data; 195 } 196 return new KindSelector(newData); 197 } 198 199 public boolean subset(KindSelector other) { 200 return (data & ~other.data) == 0; 201 } 202 203 public boolean contains(KindSelector other) { 204 return (data & other.data) != 0; 205 } 206 207 /** A set of KindName(s) representing a set of symbol's kinds. */ 208 public Set<KindName> kindNames() { 209 EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class); 210 if ((data & VAL.data) != 0) { 211 if ((data & VAL.data) == VAR.data) kinds.add(KindName.VAR); 212 else kinds.add(KindName.VAL); 213 } 214 if ((data & MTH.data) != 0) kinds.add(KindName.METHOD); 215 if ((data & TYP.data) != 0) kinds.add(KindName.CLASS); 216 if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE); 217 if ((data & MDL.data) != 0) kinds.add(KindName.MODULE); 218 return kinds; 219 } 220 } 221 222 public enum KindName implements Formattable { 223 ANNOTATION("kindname.annotation"), 224 CONSTRUCTOR("kindname.constructor"), 225 INTERFACE("kindname.interface"), 226 ENUM("kindname.enum"), 227 STATIC("kindname.static"), 228 TYPEVAR("kindname.type.variable"), 229 BOUND("kindname.type.variable.bound"), 230 VAR("kindname.variable"), 231 VAL("kindname.value"), 232 METHOD("kindname.method"), 233 CLASS("kindname.class"), 234 STATIC_INIT("kindname.static.init"), 235 INSTANCE_INIT("kindname.instance.init"), 236 PACKAGE("kindname.package"), 237 MODULE("kindname.module"); 238 239 private final String name; 240 241 KindName(String name) { 242 this.name = name; 243 } 244 245 public String toString() { 246 return name; 247 } 248 249 public String getKind() { 250 return "Kindname"; 251 } 252 253 public String toString(Locale locale, Messages messages) { 254 String s = toString(); 255 return messages.getLocalizedString(locale, "compiler.misc." + s); 256 } 257 } 258 259 public static KindName kindName(MemberReferenceTree.ReferenceMode mode) { 260 switch (mode) { 261 case INVOKE: return KindName.METHOD; 262 case NEW: return KindName.CONSTRUCTOR; 263 default : throw new AssertionError("Unexpected mode: "+ mode); 264 } 265 } 266 267 /** A KindName representing a given symbol 268 */ 269 public static KindName kindName(Symbol sym) { 270 switch (sym.getKind()) { 271 case PACKAGE: 272 return KindName.PACKAGE; 273 274 case ENUM: 275 return KindName.ENUM; 276 277 case ANNOTATION_TYPE: 278 case CLASS: 279 return KindName.CLASS; 280 281 case INTERFACE: 282 return KindName.INTERFACE; 283 284 case TYPE_PARAMETER: 285 return KindName.TYPEVAR; 286 287 case ENUM_CONSTANT: 288 case FIELD: 289 case PARAMETER: 290 case LOCAL_VARIABLE: 291 case EXCEPTION_PARAMETER: 292 case RESOURCE_VARIABLE: 293 return KindName.VAR; 294 295 case CONSTRUCTOR: 296 return KindName.CONSTRUCTOR; 297 298 case METHOD: 299 return KindName.METHOD; 300 case STATIC_INIT: 301 return KindName.STATIC_INIT; 302 case INSTANCE_INIT: 303 return KindName.INSTANCE_INIT; 304 305 default: 306 throw new AssertionError("Unexpected kind: "+sym.getKind()); 307 } 308 } 309 310 /** A KindName representing the kind of a given class/interface type. 311 */ 312 public static KindName typeKindName(Type t) { 313 if (t.hasTag(TYPEVAR) || 314 t.hasTag(CLASS) && (t.tsym.flags() & COMPOUND) != 0) 315 return KindName.BOUND; 316 else if (t.hasTag(PACKAGE)) 317 return KindName.PACKAGE; 318 else if ((t.tsym.flags_field & ANNOTATION) != 0) 319 return KindName.ANNOTATION; 320 else if ((t.tsym.flags_field & INTERFACE) != 0) 321 return KindName.INTERFACE; 322 else 323 return KindName.CLASS; 324 } 325 326} 327