langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 14359 d4099818ab70
parent 14267 6321fbe0cf50
child 14366 af625e568667
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Oct 23 13:58:56 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Oct 25 11:09:36 2012 -0700
@@ -56,8 +56,8 @@
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
-import static com.sun.tools.javac.code.TypeTags.*;
-import static com.sun.tools.javac.code.TypeTags.WILDCARD;
+import static com.sun.tools.javac.code.TypeTag.*;
+import static com.sun.tools.javac.code.TypeTag.WILDCARD;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** This is the main context-dependent analysis phase in GJC. It
@@ -234,7 +234,7 @@
     Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
         Type owntype = found;
-        if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) {
+        if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
             if (inferenceContext.free(found)) {
                 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
                     @Override
@@ -606,7 +606,7 @@
     /** Derived visitor method: attribute an expression tree.
      */
     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
-        return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType));
+        return attribTree(tree, env, new ResultInfo(VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
     }
 
     /** Derived visitor method: attribute an expression tree with
@@ -806,7 +806,7 @@
                    boolean checkExtensible) {
         if (t.isErroneous())
             return t;
-        if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) {
+        if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
             // check that type variable is already visible
             if (t.getUpperBound() == null) {
                 log.error(tree.pos(), "illegal.forward.ref");
@@ -1208,7 +1208,7 @@
                             }
                         } else {
                             Type pattype = attribExpr(c.pat, switchEnv, seltype);
-                            if (pattype.tag != ERROR) {
+                            if (!pattype.hasTag(ERROR)) {
                                 if (pattype.constValue() == null) {
                                     log.error(c.pat.pos(),
                                               (stringSwitch ? "string.const.req" : "const.expr.req"));
@@ -1379,10 +1379,10 @@
         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
 
         boolean standaloneConditional = !allowPoly ||
-                pt().tag == NONE && pt() != Type.recoveryType ||
+                pt().hasTag(NONE) && pt() != Type.recoveryType ||
                 isBooleanOrNumeric(env, tree);
 
-        if (!standaloneConditional && resultInfo.pt.tag == VOID) {
+        if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
             //cannot get here (i.e. it means we are returning from void method - which is already an error)
             result = tree.type = types.createErrorType(resultInfo.pt);
             return;
@@ -1416,7 +1416,8 @@
         @SuppressWarnings("fallthrough")
         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
             switch (tree.getTag()) {
-                case LITERAL: return ((JCLiteral)tree).typetag < CLASS;
+                case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
+                              ((JCLiteral)tree).typetag == BOOLEAN;
                 case LAMBDA: case REFERENCE: return false;
                 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
                 case CONDEXPR:
@@ -1426,7 +1427,7 @@
                 default:
                     Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
                     speculativeType = types.unboxedTypeOrType(speculativeType);
-                    return speculativeType.tag <= BOOLEAN;
+                    return speculativeType.isPrimitive();
             }
         }
 
@@ -1459,16 +1460,19 @@
                 // If one arm has an integer subrange type (i.e., byte,
                 // short, or char), and the other is an integer constant
                 // that fits into the subrange, return the subrange type.
-                if (thenUnboxed.tag < INT && elseUnboxed.tag == INT &&
+                if (thenUnboxed.getTag().isStrictSubRangeOf(INT) && elseUnboxed.hasTag(INT) &&
                     types.isAssignable(elseUnboxed, thenUnboxed))
                     return thenUnboxed.baseType();
-                if (elseUnboxed.tag < INT && thenUnboxed.tag == INT &&
+                if (elseUnboxed.getTag().isStrictSubRangeOf(INT) && thenUnboxed.hasTag(INT) &&
                     types.isAssignable(thenUnboxed, elseUnboxed))
                     return elseUnboxed.baseType();
 
-                for (int i = BYTE; i < VOID; i++) {
-                    Type candidate = syms.typeOfTag[i];
-                    if (types.isSubtype(thenUnboxed, candidate) &&
+                for (TypeTag tag : TypeTag.values()) {
+                    if (tag.ordinal() >= TypeTag.getTypeTagCount()) break;
+                    Type candidate = syms.typeOfTag[tag.ordinal()];
+                    if (candidate != null &&
+                        candidate.isPrimitive() &&
+                        types.isSubtype(thenUnboxed, candidate) &&
                         types.isSubtype(elseUnboxed, candidate))
                         return candidate;
                 }
@@ -1487,7 +1491,7 @@
             if (types.isSubtype(elsetype, thentype))
                 return thentype.baseType();
 
-            if (!allowBoxing || thentype.tag == VOID || elsetype.tag == VOID) {
+            if (!allowBoxing || thentype.hasTag(VOID) || elsetype.hasTag(VOID)) {
                 log.error(pos, "neither.conditional.subtype",
                           thentype, elsetype);
                 return thentype.baseType();
@@ -1601,12 +1605,12 @@
             // Attribute return expression, if it exists, and check that
             // it conforms to result type of enclosing method.
             if (tree.expr != null) {
-                if (env.info.returnResult.pt.tag == VOID) {
+                if (env.info.returnResult.pt.hasTag(VOID)) {
                     log.error(tree.expr.pos(),
                               "cant.ret.val.from.meth.decl.void");
                 }
                 attribTree(tree.expr, env, env.info.returnResult);
-            } else if (env.info.returnResult.pt.tag != VOID) {
+            } else if (!env.info.returnResult.pt.hasTag(VOID)) {
                 log.error(tree.pos(), "missing.ret.val");
             }
         }
@@ -1671,11 +1675,11 @@
                     }
                 }
 
-                if (site.tag == CLASS) {
+                if (site.hasTag(CLASS)) {
                     Type encl = site.getEnclosingType();
-                    while (encl != null && encl.tag == TYPEVAR)
+                    while (encl != null && encl.hasTag(TYPEVAR))
                         encl = encl.getUpperBound();
-                    if (encl.tag == CLASS) {
+                    if (encl.hasTag(CLASS)) {
                         // we are calling a nested class
 
                         if (tree.meth.hasTag(SELECT)) {
@@ -1740,7 +1744,7 @@
 
             // Compute the result type.
             Type restype = mtype.getReturnType();
-            if (restype.tag == WILDCARD)
+            if (restype.hasTag(WILDCARD))
                 throw new AssertionError(mtype);
 
             Type qualifier = (tree.meth.hasTag(SELECT))
@@ -1870,7 +1874,7 @@
                 }
             }
         } else if (!clazztype.tsym.isInterface() &&
-                   clazztype.getEnclosingType().tag == CLASS) {
+                   clazztype.getEnclosingType().hasTag(CLASS)) {
             // Check for the existence of an apropos outer instance
             rs.resolveImplicitThis(tree.pos(), env, clazztype);
         }
@@ -1880,7 +1884,7 @@
         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
 
         // If we have made no mistakes in the class type...
-        if (clazztype.tag == CLASS) {
+        if (clazztype.hasTag(CLASS)) {
             // Enums may not be instantiated except implicitly
             if (allowEnums &&
                 (clazztype.tsym.flags_field&Flags.ENUM) != 0 &&
@@ -2058,7 +2062,7 @@
                             resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
                     Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
                     if (!inferred.isErroneous() &&
-                        types.isAssignable(inferred, pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings)) {
+                        types.isAssignable(inferred, pt().hasTag(NONE) ? syms.objectType : pt(), Warner.noWarnings)) {
                         String key = types.isSameType(clazztype, inferred) ?
                             "diamond.redundant.args" :
                             "diamond.redundant.args.1";
@@ -2073,8 +2077,8 @@
             private void checkLambdaCandidate(JCNewClass tree, ClassSymbol csym, Type clazztype) {
                 if (allowLambda &&
                         identifyLambdaCandidate &&
-                        clazztype.tag == CLASS &&
-                        pt().tag != NONE &&
+                        clazztype.hasTag(CLASS) &&
+                        !pt().hasTag(NONE) &&
                         types.isFunctionalInterface(clazztype.tsym)) {
                     Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym);
                     int count = 0;
@@ -2125,10 +2129,10 @@
         } else {
             // we are seeing an untyped aggregate { ... }
             // this is allowed only if the prototype is an array
-            if (pt().tag == ARRAY) {
+            if (pt().hasTag(ARRAY)) {
                 elemtype = types.elemtype(pt());
             } else {
-                if (pt().tag != ERROR) {
+                if (!pt().hasTag(ERROR)) {
                     log.error(tree.pos(), "illegal.initializer.for.type",
                               pt());
                 }
@@ -2152,8 +2156,8 @@
      */
     @Override
     public void visitLambda(final JCLambda that) {
-        if (pt().isErroneous() || (pt().tag == NONE && pt() != Type.recoveryType)) {
-            if (pt().tag == NONE) {
+        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
+            if (pt().hasTag(NONE)) {
                 //lambda only allowed in assignment or method invocation/cast context
                 log.error(that.pos(), "unexpected.lambda");
             }
@@ -2328,7 +2332,7 @@
             //this amounts at checking that, if a lambda body can complete normally,
             //the descriptor's return type must be void
             if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally &&
-                    returnType.tag != VOID && returnType != Type.recoveryType) {
+                    !returnType.hasTag(VOID) && returnType != Type.recoveryType) {
                 checkContext.report(tree, diags.fragment("incompatible.ret.type.in.lambda",
                         diags.fragment("missing.ret.val", returnType)));
             }
@@ -2363,8 +2367,8 @@
 
     @Override
     public void visitReference(final JCMemberReference that) {
-        if (pt().isErroneous() || (pt().tag == NONE && pt() != Type.recoveryType)) {
-            if (pt().tag == NONE) {
+        if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
+            if (pt().hasTag(NONE)) {
                 //method reference only allowed in assignment or method invocation/cast context
                 log.error(that.pos(), "unexpected.mref");
             }
@@ -2465,7 +2469,7 @@
 
             ResultInfo checkInfo =
                     resultInfo.dup(newMethodTemplate(
-                        desc.getReturnType().tag == VOID ? Type.noType : desc.getReturnType(),
+                        desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
                         lookupHelper.argtypes,
                         typeargtypes));
 
@@ -2510,11 +2514,11 @@
 
         Type incompatibleReturnType = resType;
 
-        if (returnType.tag == VOID) {
+        if (returnType.hasTag(VOID)) {
             incompatibleReturnType = null;
         }
 
-        if (returnType.tag != VOID && resType.tag != VOID) {
+        if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
             if (resType.isErroneous() ||
                     new LambdaReturnContext(checkContext).compatible(resType, returnType, Warner.noWarnings)) {
                 incompatibleReturnType = null;
@@ -2711,7 +2715,7 @@
         attribExpr(tree.index, env, syms.intType);
         if (types.isArray(atype))
             owntype = types.elemtype(atype);
-        else if (atype.tag != ERROR)
+        else if (!atype.hasTag(ERROR))
             log.error(tree.pos(), "array.req.but.found", atype);
         if ((pkind() & VAR) == 0) owntype = capture(owntype);
         result = check(tree, owntype, VAR, resultInfo);
@@ -2721,7 +2725,7 @@
         Symbol sym;
 
         // Find symbol
-        if (pt().tag == METHOD || pt().tag == FORALL) {
+        if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
             // If we are looking for a method, the prototype `pt' will be a
             // method type with the type of the call's arguments as parameters.
             env.info.pendingResolutionPhase = null;
@@ -2811,9 +2815,9 @@
         // don't allow T.class T[].class, etc
         if (skind == TYP) {
             Type elt = site;
-            while (elt.tag == ARRAY)
+            while (elt.hasTag(ARRAY))
                 elt = ((ArrayType)elt).elemtype;
-            if (elt.tag == TYPEVAR) {
+            if (elt.hasTag(TYPEVAR)) {
                 log.error(tree.pos(), "type.var.cant.be.deref");
                 result = types.createErrorType(tree.type);
                 return;
@@ -2839,8 +2843,8 @@
         boolean varArgs = env.info.lastResolveVarargs();
         tree.sym = sym;
 
-        if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
-            while (site.tag == TYPEVAR) site = site.getUpperBound();
+        if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
+            while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
             site = capture(site);
         }
 
@@ -2929,14 +2933,14 @@
                                  ResultInfo resultInfo) {
             DiagnosticPosition pos = tree.pos();
             Name name = tree.name;
-            switch (site.tag) {
+            switch (site.getTag()) {
             case PACKAGE:
                 return rs.accessBase(
                     rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind),
                     pos, location, site, name, true);
             case ARRAY:
             case CLASS:
-                if (resultInfo.pt.tag == METHOD || resultInfo.pt.tag == FORALL) {
+                if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) {
                     return rs.resolveQualifiedMethod(
                         pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
                 } else if (name == names._this || name == names._super) {
@@ -3029,7 +3033,7 @@
                      Symbol sym,
                      Env<AttrContext> env,
                      ResultInfo resultInfo) {
-            Type pt = resultInfo.pt.tag == FORALL || resultInfo.pt.tag == METHOD ?
+            Type pt = resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD) ?
                     resultInfo.pt.map(deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)) :
                     resultInfo.pt;
 
@@ -3046,7 +3050,7 @@
                 // For types, the computed type equals the symbol's type,
                 // except for two situations:
                 owntype = sym.type;
-                if (owntype.tag == CLASS) {
+                if (owntype.hasTag(CLASS)) {
                     Type ownOuter = owntype.getEnclosingType();
 
                     // (a) If the symbol's type is parameterized, erase it
@@ -3066,9 +3070,9 @@
                     //
                     // Then the type of the last expression above is
                     // Tree<Point>.Visitor.
-                    else if (ownOuter.tag == CLASS && site != ownOuter) {
+                    else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
                         Type normOuter = site;
-                        if (normOuter.tag == CLASS)
+                        if (normOuter.hasTag(CLASS))
                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
                         if (normOuter == null) // perhaps from an import
                             normOuter = types.erasure(ownOuter);
@@ -3087,7 +3091,7 @@
                     resultInfo.pkind == VAR &&
                     v.owner.kind == TYP &&
                     (v.flags() & STATIC) == 0 &&
-                    (site.tag == CLASS || site.tag == TYPEVAR)) {
+                    (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
                     Type s = types.asOuterSuper(site, v.owner);
                     if (s != null &&
                         s.isRaw() &&
@@ -3266,7 +3270,7 @@
         // an unchecked warning if its argument types change under erasure.
         if (allowGenerics &&
             (sym.flags() & STATIC) == 0 &&
-            (site.tag == CLASS || site.tag == TYPEVAR)) {
+            (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
             Type s = types.asOuterSuper(site, sym.owner);
             if (s != null && s.isRaw() &&
                 !types.isSameTypes(sym.type.getParameterTypes(),
@@ -3312,12 +3316,12 @@
     //where
     /** Return the type of a literal with given type tag.
      */
-    Type litType(int tag) {
-        return (tag == TypeTags.CLASS) ? syms.stringType : syms.typeOfTag[tag];
+    Type litType(TypeTag tag) {
+        return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag.ordinal()];
     }
 
     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
-        result = check(tree, syms.typeOfTag[tree.typetag], TYP, resultInfo);
+        result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], TYP, resultInfo);
     }
 
     public void visitTypeArray(JCArrayTypeTree tree) {
@@ -3339,7 +3343,7 @@
         // Attribute type parameters
         List<Type> actuals = attribTypes(tree.arguments, env);
 
-        if (clazztype.tag == CLASS) {
+        if (clazztype.hasTag(CLASS)) {
             List<Type> formals = clazztype.tsym.type.getTypeArguments();
             if (actuals.isEmpty()) //diamond
                 actuals = formals;
@@ -3354,7 +3358,7 @@
                 }
                 // Compute the proper generic outer
                 Type clazzOuter = clazztype.getEnclosingType();
-                if (clazzOuter.tag == CLASS) {
+                if (clazzOuter.hasTag(CLASS)) {
                     Type site;
                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
                     if (clazz.hasTag(IDENT)) {
@@ -3362,8 +3366,8 @@
                     } else if (clazz.hasTag(SELECT)) {
                         site = ((JCFieldAccess) clazz).selected.type;
                     } else throw new AssertionError(""+tree);
-                    if (clazzOuter.tag == CLASS && site != clazzOuter) {
-                        if (site.tag == CLASS)
+                    if (clazzOuter.hasTag(CLASS) && site != clazzOuter) {
+                        if (site.hasTag(CLASS))
                             site = types.asOuterSuper(site, clazzOuter.tsym);
                         if (site == null)
                             site = types.erasure(clazzOuter);
@@ -3419,7 +3423,7 @@
             }
         }
         Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo);
-        if (t.tag == CLASS) {
+        if (t.hasTag(CLASS)) {
             List<Type> alternatives =
                 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
             t = new UnionClassType((ClassType) t, alternatives);
@@ -3440,7 +3444,7 @@
             if (b.isErroneous()) {
                 a.bound = b;
             }
-            else if (b.tag == TYPEVAR) {
+            else if (b.hasTag(TYPEVAR)) {
                 // if first bound was a typevar, do not accept further bounds.
                 if (tree.bounds.tail.nonEmpty()) {
                     log.error(tree.bounds.tail.head.pos(),
@@ -3456,7 +3460,7 @@
                     Type i = checkBase(bs.head, bound, env, false, true, false);
                     if (i.isErroneous())
                         a.bound = i;
-                    else if (i.tag == CLASS)
+                    else if (i.hasTag(CLASS))
                         chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
                 }
             }
@@ -3568,7 +3572,7 @@
      *  @param c   The class symbol whose definition will be attributed.
      */
     void attribClass(ClassSymbol c) throws CompletionFailure {
-        if (c.type.tag == ERROR) return;
+        if (c.type.hasTag(ERROR)) return;
 
         // Check for cycles in the inheritance graph, which can arise from
         // ill-formed class files.
@@ -3577,11 +3581,11 @@
         Type st = types.supertype(c.type);
         if ((c.flags_field & Flags.COMPOUND) == 0) {
             // First, attribute superclass.
-            if (st.tag == CLASS)
+            if (st.hasTag(CLASS))
                 attribClass((ClassSymbol)st.tsym);
 
             // Next attribute owner, if it is a class.
-            if (c.owner.kind == TYP && c.owner.type.tag == CLASS)
+            if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
                 attribClass((ClassSymbol)c.owner);
         }
 
@@ -3793,7 +3797,7 @@
                         TreeInfo.diagnosticPositionFor(svuid, tree), "improper.SVUID", c);
 
             // check that it is long
-            else if (svuid.type.tag != TypeTags.LONG)
+            else if (!svuid.type.hasTag(LONG))
                 log.warning(LintCategory.SERIAL,
                         TreeInfo.diagnosticPositionFor(svuid, tree), "long.SVUID", c);