langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java
changeset 27224 228abfa87080
parent 25874 83c19f00452c
child 27844 8b5d79870a2f
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java	Wed Jul 05 20:04:46 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java	Tue Oct 21 09:01:51 2014 -0400
@@ -26,11 +26,13 @@
 package com.sun.tools.javac.code;
 
 import java.util.EnumSet;
+import java.util.Set;
 import java.util.Locale;
 
 import com.sun.source.tree.MemberReferenceTree;
 import com.sun.tools.javac.api.Formattable;
 import com.sun.tools.javac.api.Messages;
+
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.PACKAGE;
@@ -49,55 +51,166 @@
 
     private Kinds() {} // uninstantiable
 
-    /** The empty set of kinds.
-     */
-    public final static int NIL = 0;
-
-    /** The kind of package symbols.
+    /**
+     * Kind of symbols.
+     *
+     * IMPORTANT: This is an ordered type.  The ordering of
+     * declarations in this enum matters.  Be careful when changing
+     * it.
      */
-    public final static int PCK = 1 << 0;
+    public enum Kind {
+        NIL(Category.BASIC, KindSelector.NIL),
+        PCK(Category.BASIC, KindName.PACKAGE, KindSelector.PCK),
+        TYP(Category.BASIC, KindName.CLASS, KindSelector.TYP),
+        VAR(Category.BASIC, KindName.VAR, KindSelector.VAR),
+        MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH),
+        POLY(Category.BASIC, KindSelector.POLY),
+        ERR(Category.ERROR, KindSelector.ERR),
+        AMBIGUOUS(Category.OVERLOAD),
+        HIDDEN(Category.OVERLOAD),
+        STATICERR(Category.OVERLOAD),
+        MISSING_ENCL(Category.OVERLOAD),
+        ABSENT_VAR(Category.OVERLOAD, KindName.VAR),
+        WRONG_MTHS(Category.OVERLOAD, KindName.METHOD),
+        WRONG_MTH(Category.OVERLOAD, KindName.METHOD),
+        ABSENT_MTH(Category.OVERLOAD, KindName.METHOD),
+        ABSENT_TYP(Category.OVERLOAD, KindName.CLASS),
+        WRONG_STATICNESS(Category.OVERLOAD, KindName.METHOD);
 
-    /** The kind of type symbols (classes, interfaces and type variables).
-     */
-    public final static int TYP = 1 << 1;
+        // There are essentially two "levels" to the Kind datatype.
+        // The first is a totally-ordered set of categories of
+        // solutions.  Within each category, we have more
+        // possibilities.
+        private enum Category {
+            BASIC, ERROR, OVERLOAD;
+        }
 
-    /** The kind of variable symbols.
-     */
-    public final static int VAR = 1 << 2;
+        private final KindName kindName;
+        private final KindName absentKind;
+        private final KindSelector selector;
+        private final Category category;
+
+        private Kind(Category category) {
+            this(category, null, null, null);
+        }
+
+        private Kind(Category category,
+                     KindSelector selector) {
+            this(category, null, null, selector);
+        }
+
+        private Kind(Category category,
+                     KindName absentKind) {
+            this(category, null, absentKind, null);
+        }
 
-    /** The kind of values (variables or non-variable expressions), includes VAR.
-     */
-    public final static int VAL = (1 << 3) | VAR;
+        private Kind(Category category,
+                     KindName kindName,
+                     KindSelector selector) {
+            this(category, kindName, null, selector);
+        }
 
-    /** The kind of methods.
-     */
-    public final static int MTH = 1 << 4;
+        private Kind(Category category,
+                     KindName kindName,
+                     KindName absentKind,
+                     KindSelector selector) {
+            this.category = category;
+            this.kindName = kindName;
+            this.absentKind = absentKind;
+            this.selector = selector;
+        }
+
+        public KindSelector toSelector() {
+            return selector;
+        }
+
+        public boolean matches(KindSelector kindSelectors) {
+            return selector.contains(kindSelectors);
+        }
 
-    /** Poly kind, for deferred types.
-     */
-    public final static int POLY = 1 << 5;
+        public boolean isOverloadError() {
+            return category == Category.OVERLOAD;
+        }
+
+        public boolean isValid() {
+            return category == Category.BASIC;
+        }
+
+        public boolean betterThan(Kind other) {
+            return ordinal() < other.ordinal();
+        }
+
+        public KindName kindName() {
+            if (kindName == null) {
+                throw new AssertionError("Unexpected kind: " + this);
+            } else {
+                return kindName;
+            }
+        }
 
-    /** The error kind, which includes all other kinds.
-     */
-    public final static int ERR = (1 << 6) - 1;
+        public KindName absentKind() {
+            if (absentKind == null) {
+                throw new AssertionError("Unexpected kind: " + this);
+            } else {
+                return absentKind;
+            }
+        }
+    }
 
-    /** The set of all kinds.
-     */
-    public final static int AllKinds = ERR;
+    public static class KindSelector {
+
+        //basic selectors
+        public static final KindSelector NIL = new KindSelector(0);
+        public static final KindSelector PCK = new KindSelector(0x01);
+        public static final KindSelector TYP = new KindSelector(0x02);
+        public static final KindSelector VAR = new KindSelector(0x04);
+        public static final KindSelector VAL = new KindSelector(0x0c);
+        public static final KindSelector MTH = new KindSelector(0x10);
+        public static final KindSelector ERR = new KindSelector(0x3f);
+        public static final KindSelector POLY = new KindSelector(0x20);
 
-    /** Kinds for erroneous symbols that complement the above
-     */
-    public static final int ERRONEOUS           = 1 << 7;
-    public static final int AMBIGUOUS           = ERRONEOUS + 1;  // ambiguous reference
-    public static final int HIDDEN              = ERRONEOUS + 2;  // hidden method or field
-    public static final int STATICERR           = ERRONEOUS + 3;  // nonstatic member from static context
-    public static final int MISSING_ENCL        = ERRONEOUS + 4;  // missing enclosing class
-    public static final int ABSENT_VAR          = ERRONEOUS + 5;  // missing variable
-    public static final int WRONG_MTHS          = ERRONEOUS + 6;  // methods with wrong arguments
-    public static final int WRONG_MTH           = ERRONEOUS + 7;  // one method with wrong arguments
-    public static final int ABSENT_MTH          = ERRONEOUS + 8;  // missing method
-    public static final int ABSENT_TYP          = ERRONEOUS + 9;  // missing type
-    public static final int WRONG_STATICNESS    = ERRONEOUS + 10; // wrong staticness for method references
+        //common derived selectors
+        public static final KindSelector TYP_PCK = of(TYP, PCK);
+        public static final KindSelector VAL_MTH = of(VAL, MTH);
+        public static final KindSelector VAL_POLY = of(VAL, POLY);
+        public static final KindSelector VAL_TYP = of(VAL, TYP);
+        public static final KindSelector VAL_TYP_PCK = of(VAL, TYP, PCK);
+
+        private final byte data;
+
+        private KindSelector(int data) {
+            this.data = (byte) data;
+        }
+
+        public static KindSelector of(KindSelector... kindSelectors) {
+            byte newData = 0;
+            for (KindSelector kindSel : kindSelectors) {
+                newData |= kindSel.data;
+            }
+            return new KindSelector(newData);
+        }
+
+        public boolean subset(KindSelector other) {
+            return (data & ~other.data) == 0;
+        }
+
+        public boolean contains(KindSelector other) {
+            return (data & other.data) != 0;
+        }
+
+        /** A set of KindName(s) representing a set of symbol's kinds. */
+        public Set<KindName> kindNames() {
+            EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class);
+            if ((data & VAL.data) != 0) {
+                if ((data & VAL.data) == VAR.data) kinds.add(KindName.VAR);
+                else kinds.add(KindName.VAL);
+            }
+            if ((data & MTH.data) != 0) kinds.add(KindName.METHOD);
+            if ((data & TYP.data) != 0) kinds.add(KindName.CLASS);
+            if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE);
+            return kinds;
+        }
+    }
 
     public enum KindName implements Formattable {
         ANNOTATION("kindname.annotation"),
@@ -135,19 +248,6 @@
         }
     }
 
-    /** A KindName representing a given symbol kind
-     */
-    public static KindName kindName(int kind) {
-        switch (kind) {
-        case PCK: return KindName.PACKAGE;
-        case TYP: return KindName.CLASS;
-        case VAR: return KindName.VAR;
-        case VAL: return KindName.VAL;
-        case MTH: return KindName.METHOD;
-            default : throw new AssertionError("Unexpected kind: "+kind);
-        }
-    }
-
     public static KindName kindName(MemberReferenceTree.ReferenceMode mode) {
         switch (mode) {
             case INVOKE: return KindName.METHOD;
@@ -195,27 +295,10 @@
             return KindName.INSTANCE_INIT;
 
         default:
-            if (sym.kind == VAL)
-                // I don't think this can happen but it can't harm
-                // playing it safe --ahe
-                return KindName.VAL;
-            else
                 throw new AssertionError("Unexpected kind: "+sym.getKind());
         }
     }
 
-    /** A set of KindName(s) representing a set of symbol's kinds.
-     */
-    public static EnumSet<KindName> kindNames(int kind) {
-        EnumSet<KindName> kinds = EnumSet.noneOf(KindName.class);
-        if ((kind & VAL) != 0)
-            kinds.add(((kind & VAL) == VAR) ? KindName.VAR : KindName.VAL);
-        if ((kind & MTH) != 0) kinds.add(KindName.METHOD);
-        if ((kind & TYP) != 0) kinds.add(KindName.CLASS);
-        if ((kind & PCK) != 0) kinds.add(KindName.PACKAGE);
-        return kinds;
-    }
-
     /** A KindName representing the kind of a given class/interface type.
      */
     public static KindName typeKindName(Type t) {
@@ -232,19 +315,4 @@
             return KindName.CLASS;
     }
 
-    /** A KindName representing the kind of a missing symbol, given an
-     *  error kind.
-     * */
-    public static KindName absentKind(int kind) {
-        switch (kind) {
-        case ABSENT_VAR:
-            return KindName.VAR;
-        case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS:
-            return KindName.METHOD;
-        case ABSENT_TYP:
-            return KindName.CLASS;
-        default:
-            throw new AssertionError("Unexpected kind: "+kind);
-        }
-    }
 }