langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java
changeset 27224 228abfa87080
parent 25874 83c19f00452c
child 27844 8b5d79870a2f
equal deleted inserted replaced
27130:41df50e7303d 27224:228abfa87080
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.javac.code;
    26 package com.sun.tools.javac.code;
    27 
    27 
    28 import java.util.EnumSet;
    28 import java.util.EnumSet;
       
    29 import java.util.Set;
    29 import java.util.Locale;
    30 import java.util.Locale;
    30 
    31 
    31 import com.sun.source.tree.MemberReferenceTree;
    32 import com.sun.source.tree.MemberReferenceTree;
    32 import com.sun.tools.javac.api.Formattable;
    33 import com.sun.tools.javac.api.Formattable;
    33 import com.sun.tools.javac.api.Messages;
    34 import com.sun.tools.javac.api.Messages;
       
    35 
    34 import static com.sun.tools.javac.code.Flags.*;
    36 import static com.sun.tools.javac.code.Flags.*;
    35 import static com.sun.tools.javac.code.TypeTag.CLASS;
    37 import static com.sun.tools.javac.code.TypeTag.CLASS;
    36 import static com.sun.tools.javac.code.TypeTag.PACKAGE;
    38 import static com.sun.tools.javac.code.TypeTag.PACKAGE;
    37 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
    39 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
    38 
    40 
    47  */
    49  */
    48 public class Kinds {
    50 public class Kinds {
    49 
    51 
    50     private Kinds() {} // uninstantiable
    52     private Kinds() {} // uninstantiable
    51 
    53 
    52     /** The empty set of kinds.
    54     /**
       
    55      * Kind of symbols.
       
    56      *
       
    57      * IMPORTANT: This is an ordered type.  The ordering of
       
    58      * declarations in this enum matters.  Be careful when changing
       
    59      * it.
    53      */
    60      */
    54     public final static int NIL = 0;
    61     public enum Kind {
    55 
    62         NIL(Category.BASIC, KindSelector.NIL),
    56     /** The kind of package symbols.
    63         PCK(Category.BASIC, KindName.PACKAGE, KindSelector.PCK),
    57      */
    64         TYP(Category.BASIC, KindName.CLASS, KindSelector.TYP),
    58     public final static int PCK = 1 << 0;
    65         VAR(Category.BASIC, KindName.VAR, KindSelector.VAR),
    59 
    66         MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH),
    60     /** The kind of type symbols (classes, interfaces and type variables).
    67         POLY(Category.BASIC, KindSelector.POLY),
    61      */
    68         ERR(Category.ERROR, KindSelector.ERR),
    62     public final static int TYP = 1 << 1;
    69         AMBIGUOUS(Category.OVERLOAD),
    63 
    70         HIDDEN(Category.OVERLOAD),
    64     /** The kind of variable symbols.
    71         STATICERR(Category.OVERLOAD),
    65      */
    72         MISSING_ENCL(Category.OVERLOAD),
    66     public final static int VAR = 1 << 2;
    73         ABSENT_VAR(Category.OVERLOAD, KindName.VAR),
    67 
    74         WRONG_MTHS(Category.OVERLOAD, KindName.METHOD),
    68     /** The kind of values (variables or non-variable expressions), includes VAR.
    75         WRONG_MTH(Category.OVERLOAD, KindName.METHOD),
    69      */
    76         ABSENT_MTH(Category.OVERLOAD, KindName.METHOD),
    70     public final static int VAL = (1 << 3) | VAR;
    77         ABSENT_TYP(Category.OVERLOAD, KindName.CLASS),
    71 
    78         WRONG_STATICNESS(Category.OVERLOAD, KindName.METHOD);
    72     /** The kind of methods.
    79 
    73      */
    80         // There are essentially two "levels" to the Kind datatype.
    74     public final static int MTH = 1 << 4;
    81         // The first is a totally-ordered set of categories of
    75 
    82         // solutions.  Within each category, we have more
    76     /** Poly kind, for deferred types.
    83         // possibilities.
    77      */
    84         private enum Category {
    78     public final static int POLY = 1 << 5;
    85             BASIC, ERROR, OVERLOAD;
    79 
    86         }
    80     /** The error kind, which includes all other kinds.
    87 
    81      */
    88         private final KindName kindName;
    82     public final static int ERR = (1 << 6) - 1;
    89         private final KindName absentKind;
    83 
    90         private final KindSelector selector;
    84     /** The set of all kinds.
    91         private final Category category;
    85      */
    92 
    86     public final static int AllKinds = ERR;
    93         private Kind(Category category) {
    87 
    94             this(category, null, null, null);
    88     /** Kinds for erroneous symbols that complement the above
    95         }
    89      */
    96 
    90     public static final int ERRONEOUS           = 1 << 7;
    97         private Kind(Category category,
    91     public static final int AMBIGUOUS           = ERRONEOUS + 1;  // ambiguous reference
    98                      KindSelector selector) {
    92     public static final int HIDDEN              = ERRONEOUS + 2;  // hidden method or field
    99             this(category, null, null, selector);
    93     public static final int STATICERR           = ERRONEOUS + 3;  // nonstatic member from static context
   100         }
    94     public static final int MISSING_ENCL        = ERRONEOUS + 4;  // missing enclosing class
   101 
    95     public static final int ABSENT_VAR          = ERRONEOUS + 5;  // missing variable
   102         private Kind(Category category,
    96     public static final int WRONG_MTHS          = ERRONEOUS + 6;  // methods with wrong arguments
   103                      KindName absentKind) {
    97     public static final int WRONG_MTH           = ERRONEOUS + 7;  // one method with wrong arguments
   104             this(category, null, absentKind, null);
    98     public static final int ABSENT_MTH          = ERRONEOUS + 8;  // missing method
   105         }
    99     public static final int ABSENT_TYP          = ERRONEOUS + 9;  // missing type
   106 
   100     public static final int WRONG_STATICNESS    = ERRONEOUS + 10; // wrong staticness for method references
   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 isOverloadError() {
       
   132             return category == Category.OVERLOAD;
       
   133         }
       
   134 
       
   135         public boolean isValid() {
       
   136             return category == Category.BASIC;
       
   137         }
       
   138 
       
   139         public boolean betterThan(Kind other) {
       
   140             return ordinal() < other.ordinal();
       
   141         }
       
   142 
       
   143         public KindName kindName() {
       
   144             if (kindName == null) {
       
   145                 throw new AssertionError("Unexpected kind: " + this);
       
   146             } else {
       
   147                 return kindName;
       
   148             }
       
   149         }
       
   150 
       
   151         public KindName absentKind() {
       
   152             if (absentKind == null) {
       
   153                 throw new AssertionError("Unexpected kind: " + this);
       
   154             } else {
       
   155                 return absentKind;
       
   156             }
       
   157         }
       
   158     }
       
   159 
       
   160     public static class KindSelector {
       
   161 
       
   162         //basic selectors
       
   163         public static final KindSelector NIL = new KindSelector(0);
       
   164         public static final KindSelector PCK = new KindSelector(0x01);
       
   165         public static final KindSelector TYP = new KindSelector(0x02);
       
   166         public static final KindSelector VAR = new KindSelector(0x04);
       
   167         public static final KindSelector VAL = new KindSelector(0x0c);
       
   168         public static final KindSelector MTH = new KindSelector(0x10);
       
   169         public static final KindSelector ERR = new KindSelector(0x3f);
       
   170         public static final KindSelector POLY = new KindSelector(0x20);
       
   171 
       
   172         //common derived selectors
       
   173         public static final KindSelector TYP_PCK = of(TYP, PCK);
       
   174         public static final KindSelector VAL_MTH = of(VAL, MTH);
       
   175         public static final KindSelector VAL_POLY = of(VAL, POLY);
       
   176         public static final KindSelector VAL_TYP = of(VAL, TYP);
       
   177         public static final KindSelector VAL_TYP_PCK = of(VAL, TYP, PCK);
       
   178 
       
   179         private final byte data;
       
   180 
       
   181         private KindSelector(int data) {
       
   182             this.data = (byte) data;
       
   183         }
       
   184 
       
   185         public static KindSelector of(KindSelector... kindSelectors) {
       
   186             byte newData = 0;
       
   187             for (KindSelector kindSel : kindSelectors) {
       
   188                 newData |= kindSel.data;
       
   189             }
       
   190             return new KindSelector(newData);
       
   191         }
       
   192 
       
   193         public boolean subset(KindSelector other) {
       
   194             return (data & ~other.data) == 0;
       
   195         }
       
   196 
       
   197         public boolean contains(KindSelector other) {
       
   198             return (data & other.data) != 0;
       
   199         }
       
   200 
       
   201         /** A set of KindName(s) representing a set of symbol's kinds. */
       
   202         public Set<KindName> kindNames() {
       
   203             EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class);
       
   204             if ((data & VAL.data) != 0) {
       
   205                 if ((data & VAL.data) == VAR.data) kinds.add(KindName.VAR);
       
   206                 else kinds.add(KindName.VAL);
       
   207             }
       
   208             if ((data & MTH.data) != 0) kinds.add(KindName.METHOD);
       
   209             if ((data & TYP.data) != 0) kinds.add(KindName.CLASS);
       
   210             if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE);
       
   211             return kinds;
       
   212         }
       
   213     }
   101 
   214 
   102     public enum KindName implements Formattable {
   215     public enum KindName implements Formattable {
   103         ANNOTATION("kindname.annotation"),
   216         ANNOTATION("kindname.annotation"),
   104         CONSTRUCTOR("kindname.constructor"),
   217         CONSTRUCTOR("kindname.constructor"),
   105         INTERFACE("kindname.interface"),
   218         INTERFACE("kindname.interface"),
   133             String s = toString();
   246             String s = toString();
   134             return messages.getLocalizedString(locale, "compiler.misc." + s);
   247             return messages.getLocalizedString(locale, "compiler.misc." + s);
   135         }
   248         }
   136     }
   249     }
   137 
   250 
   138     /** A KindName representing a given symbol kind
       
   139      */
       
   140     public static KindName kindName(int kind) {
       
   141         switch (kind) {
       
   142         case PCK: return KindName.PACKAGE;
       
   143         case TYP: return KindName.CLASS;
       
   144         case VAR: return KindName.VAR;
       
   145         case VAL: return KindName.VAL;
       
   146         case MTH: return KindName.METHOD;
       
   147             default : throw new AssertionError("Unexpected kind: "+kind);
       
   148         }
       
   149     }
       
   150 
       
   151     public static KindName kindName(MemberReferenceTree.ReferenceMode mode) {
   251     public static KindName kindName(MemberReferenceTree.ReferenceMode mode) {
   152         switch (mode) {
   252         switch (mode) {
   153             case INVOKE: return KindName.METHOD;
   253             case INVOKE: return KindName.METHOD;
   154             case NEW: return KindName.CONSTRUCTOR;
   254             case NEW: return KindName.CONSTRUCTOR;
   155             default : throw new AssertionError("Unexpected mode: "+ mode);
   255             default : throw new AssertionError("Unexpected mode: "+ mode);
   193             return KindName.STATIC_INIT;
   293             return KindName.STATIC_INIT;
   194         case INSTANCE_INIT:
   294         case INSTANCE_INIT:
   195             return KindName.INSTANCE_INIT;
   295             return KindName.INSTANCE_INIT;
   196 
   296 
   197         default:
   297         default:
   198             if (sym.kind == VAL)
       
   199                 // I don't think this can happen but it can't harm
       
   200                 // playing it safe --ahe
       
   201                 return KindName.VAL;
       
   202             else
       
   203                 throw new AssertionError("Unexpected kind: "+sym.getKind());
   298                 throw new AssertionError("Unexpected kind: "+sym.getKind());
   204         }
   299         }
   205     }
       
   206 
       
   207     /** A set of KindName(s) representing a set of symbol's kinds.
       
   208      */
       
   209     public static EnumSet<KindName> kindNames(int kind) {
       
   210         EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class);
       
   211         if ((kind & VAL) != 0)
       
   212             kinds.add(((kind & VAL) == VAR) ? KindName.VAR : KindName.VAL);
       
   213         if ((kind & MTH) != 0) kinds.add(KindName.METHOD);
       
   214         if ((kind & TYP) != 0) kinds.add(KindName.CLASS);
       
   215         if ((kind & PCK) != 0) kinds.add(KindName.PACKAGE);
       
   216         return kinds;
       
   217     }
   300     }
   218 
   301 
   219     /** A KindName representing the kind of a given class/interface type.
   302     /** A KindName representing the kind of a given class/interface type.
   220      */
   303      */
   221     public static KindName typeKindName(Type t) {
   304     public static KindName typeKindName(Type t) {
   230             return KindName.INTERFACE;
   313             return KindName.INTERFACE;
   231         else
   314         else
   232             return KindName.CLASS;
   315             return KindName.CLASS;
   233     }
   316     }
   234 
   317 
   235     /** A KindName representing the kind of a missing symbol, given an
       
   236      *  error kind.
       
   237      * */
       
   238     public static KindName absentKind(int kind) {
       
   239         switch (kind) {
       
   240         case ABSENT_VAR:
       
   241             return KindName.VAR;
       
   242         case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS:
       
   243             return KindName.METHOD;
       
   244         case ABSENT_TYP:
       
   245             return KindName.CLASS;
       
   246         default:
       
   247             throw new AssertionError("Unexpected kind: "+kind);
       
   248         }
       
   249     }
       
   250 }
   318 }