001 /* 002 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Sun designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Sun in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 022 * CA 95054 USA or visit www.sun.com if you need additional information or 023 * have any questions. 024 */ 025 026 package com.sun.tools.javac.code; 027 028 import java.util.EnumSet; 029 import java.util.Locale; 030 031 import com.sun.tools.javac.api.Formattable; 032 import com.sun.tools.javac.api.Messages; 033 034 import static com.sun.tools.javac.code.TypeTags.*; 035 import static com.sun.tools.javac.code.Flags.*; 036 037 /** Internal symbol kinds, which distinguish between elements of 038 * different subclasses of Symbol. Symbol kinds are organized so they can be 039 * or'ed to sets. 040 * 041 * <p><b>This is NOT part of any API supported by Sun Microsystems. If 042 * you write code that depends on this, you do so at your own risk. 043 * This code and its internal interfaces are subject to change or 044 * deletion without notice.</b> 045 */ 046 public class Kinds { 047 048 private Kinds() {} // uninstantiable 049 050 /** The empty set of kinds. 051 */ 052 public final static int NIL = 0; 053 054 /** The kind of package symbols. 055 */ 056 public final static int PCK = 1 << 0; 057 058 /** The kind of type symbols (classes, interfaces and type variables). 059 */ 060 public final static int TYP = 1 << 1; 061 062 /** The kind of variable symbols. 063 */ 064 public final static int VAR = 1 << 2; 065 066 /** The kind of values (variables or non-variable expressions), includes VAR. 067 */ 068 public final static int VAL = (1 << 3) | VAR; 069 070 /** The kind of methods. 071 */ 072 public final static int MTH = 1 << 4; 073 074 /** The error kind, which includes all other kinds. 075 */ 076 public final static int ERR = (1 << 5) - 1; 077 078 /** The set of all kinds. 079 */ 080 public final static int AllKinds = ERR; 081 082 /** Kinds for erroneous symbols that complement the above 083 */ 084 public static final int ERRONEOUS = 1 << 6; 085 public static final int AMBIGUOUS = ERRONEOUS+1; // ambiguous reference 086 public static final int HIDDEN = ERRONEOUS+2; // hidden method or field 087 public static final int STATICERR = ERRONEOUS+3; // nonstatic member from static context 088 public static final int ABSENT_VAR = ERRONEOUS+4; // missing variable 089 public static final int WRONG_MTHS = ERRONEOUS+5; // methods with wrong arguments 090 public static final int WRONG_MTH = ERRONEOUS+6; // one method with wrong arguments 091 public static final int ABSENT_MTH = ERRONEOUS+7; // missing method 092 public static final int ABSENT_TYP = ERRONEOUS+8; // missing type 093 094 public enum KindName implements Formattable { 095 ANNOTATION("kindname.interface"), 096 CONSTRUCTOR("kindname.constructor"), 097 INTERFACE("kindname.interface"), 098 STATIC("kindname.static"), 099 TYPEVAR("kindname.type.variable"), 100 BOUND("kindname.type.variable.bound"), 101 VAR("kindname.variable"), 102 VAL("kindname.value"), 103 METHOD("kindname.method"), 104 CLASS("kindname.class"), 105 PACKAGE("kindname.package"); 106 107 private String name; 108 109 KindName(String name) { 110 this.name = name; 111 } 112 113 public String toString() { 114 return name; 115 } 116 117 public String getKind() { 118 return "Kindname"; 119 } 120 121 public String toString(Locale locale, Messages messages) { 122 String s = toString(); 123 return messages.getLocalizedString(locale, "compiler.misc." + s); 124 } 125 } 126 127 /** A KindName representing a given symbol kind 128 */ 129 public static KindName kindName(int kind) { 130 switch (kind) { 131 case PCK: return KindName.PACKAGE; 132 case TYP: return KindName.CLASS; 133 case VAR: return KindName.VAR; 134 case VAL: return KindName.VAL; 135 case MTH: return KindName.METHOD; 136 default : throw new AssertionError("Unexpected kind: "+kind); 137 } 138 } 139 140 /** A KindName representing a given symbol 141 */ 142 public static KindName kindName(Symbol sym) { 143 switch (sym.getKind()) { 144 case PACKAGE: 145 return KindName.PACKAGE; 146 147 case ENUM: 148 case ANNOTATION_TYPE: 149 case INTERFACE: 150 case CLASS: 151 return KindName.CLASS; 152 153 case TYPE_PARAMETER: 154 return KindName.TYPEVAR; 155 156 case ENUM_CONSTANT: 157 case FIELD: 158 case PARAMETER: 159 case LOCAL_VARIABLE: 160 case EXCEPTION_PARAMETER: 161 return KindName.VAR; 162 163 case METHOD: 164 case CONSTRUCTOR: 165 case STATIC_INIT: 166 case INSTANCE_INIT: 167 return KindName.METHOD; 168 169 default: 170 if (sym.kind == VAL) 171 // I don't think this can happen but it can't harm 172 // playing it safe --ahe 173 return KindName.VAL; 174 else 175 throw new AssertionError("Unexpected kind: "+sym.getKind()); 176 } 177 } 178 179 /** A set of KindName(s) representing a set of symbol's kinds. 180 */ 181 public static EnumSet<KindName> kindNames(int kind) { 182 EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class); 183 if ((kind & VAL) != 0) 184 kinds.add(((kind & VAL) == VAR) ? KindName.VAR : KindName.VAL); 185 if ((kind & MTH) != 0) kinds.add(KindName.METHOD); 186 if ((kind & TYP) != 0) kinds.add(KindName.CLASS); 187 if ((kind & PCK) != 0) kinds.add(KindName.PACKAGE); 188 return kinds; 189 } 190 191 /** A KindName representing the kind of a given class/interface type. 192 */ 193 public static KindName typeKindName(Type t) { 194 if (t.tag == TYPEVAR || 195 t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0) 196 return KindName.BOUND; 197 else if (t.tag == PACKAGE) 198 return KindName.PACKAGE; 199 else if ((t.tsym.flags_field & ANNOTATION) != 0) 200 return KindName.ANNOTATION; 201 else if ((t.tsym.flags_field & INTERFACE) != 0) 202 return KindName.INTERFACE; 203 else 204 return KindName.CLASS; 205 } 206 207 /** A KindName representing the kind of a a missing symbol, given an 208 * error kind. 209 * */ 210 public static KindName absentKind(int kind) { 211 switch (kind) { 212 case ABSENT_VAR: 213 return KindName.VAR; 214 case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: 215 return KindName.METHOD; 216 case ABSENT_TYP: 217 return KindName.CLASS; 218 default: 219 throw new AssertionError("Unexpected kind: "+kind); 220 } 221 } 222 }