langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 10950 e87b50888909
parent 10459 3908f37df0fc
child 11143 9dbe313bfb74
equal deleted inserted replaced
10949:42f7cc0468dd 10950:e87b50888909
    47 import com.sun.source.tree.MemberSelectTree;
    47 import com.sun.source.tree.MemberSelectTree;
    48 import com.sun.source.tree.TreeVisitor;
    48 import com.sun.source.tree.TreeVisitor;
    49 import com.sun.source.util.SimpleTreeVisitor;
    49 import com.sun.source.util.SimpleTreeVisitor;
    50 
    50 
    51 import static com.sun.tools.javac.code.Flags.*;
    51 import static com.sun.tools.javac.code.Flags.*;
       
    52 import static com.sun.tools.javac.code.Flags.ANNOTATION;
       
    53 import static com.sun.tools.javac.code.Flags.BLOCK;
    52 import static com.sun.tools.javac.code.Kinds.*;
    54 import static com.sun.tools.javac.code.Kinds.*;
       
    55 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
    53 import static com.sun.tools.javac.code.TypeTags.*;
    56 import static com.sun.tools.javac.code.TypeTags.*;
       
    57 import static com.sun.tools.javac.code.TypeTags.WILDCARD;
       
    58 import static com.sun.tools.javac.tree.JCTree.Tag.*;
    54 
    59 
    55 /** This is the main context-dependent analysis phase in GJC. It
    60 /** This is the main context-dependent analysis phase in GJC. It
    56  *  encompasses name resolution, type checking and constant folding as
    61  *  encompasses name resolution, type checking and constant folding as
    57  *  subtasks. Some subtasks involve auxiliary classes.
    62  *  subtasks. Some subtasks involve auxiliary classes.
    58  *  @see Check
    63  *  @see Check
   243     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
   248     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
   244         if ((v.flags() & FINAL) != 0 &&
   249         if ((v.flags() & FINAL) != 0 &&
   245             ((v.flags() & HASINIT) != 0
   250             ((v.flags() & HASINIT) != 0
   246              ||
   251              ||
   247              !((base == null ||
   252              !((base == null ||
   248                (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
   253                (base.hasTag(IDENT) && TreeInfo.name(base) == names._this)) &&
   249                isAssignableAsBlankFinal(v, env)))) {
   254                isAssignableAsBlankFinal(v, env)))) {
   250             if (v.isResourceVariable()) { //TWR resource
   255             if (v.isResourceVariable()) { //TWR resource
   251                 log.error(pos, "try.resource.may.not.be.assigned", v);
   256                 log.error(pos, "try.resource.may.not.be.assigned", v);
   252             } else {
   257             } else {
   253                 log.error(pos, "cant.assign.val.to.final.var", v);
   258                 log.error(pos, "cant.assign.val.to.final.var", v);
   261      *  It is assumed that tree is either a SELECT or an IDENT.
   266      *  It is assumed that tree is either a SELECT or an IDENT.
   262      *  We have to weed out selects from non-type names here.
   267      *  We have to weed out selects from non-type names here.
   263      *  @param tree    The candidate tree.
   268      *  @param tree    The candidate tree.
   264      */
   269      */
   265     boolean isStaticReference(JCTree tree) {
   270     boolean isStaticReference(JCTree tree) {
   266         if (tree.getTag() == JCTree.SELECT) {
   271         if (tree.hasTag(SELECT)) {
   267             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
   272             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
   268             if (lsym == null || lsym.kind != TYP) {
   273             if (lsym == null || lsym.kind != TYP) {
   269                 return false;
   274                 return false;
   270             }
   275             }
   271         }
   276         }
   691             // in a superclass constructor call where
   696             // in a superclass constructor call where
   692             // no explicit outer instance is given,
   697             // no explicit outer instance is given,
   693             // disable implicit outer instance from being passed.
   698             // disable implicit outer instance from being passed.
   694             // (This would be an illegal access to "this before super").
   699             // (This would be an illegal access to "this before super").
   695             if (env.info.isSelfCall &&
   700             if (env.info.isSelfCall &&
   696                 env.tree.getTag() == JCTree.NEWCLASS &&
   701                 env.tree.hasTag(NEWCLASS) &&
   697                 ((JCNewClass) env.tree).encl == null)
   702                 ((JCNewClass) env.tree).encl == null)
   698             {
   703             {
   699                 c.flags_field |= NOOUTERTHIS;
   704                 c.flags_field |= NOOUTERTHIS;
   700             }
   705             }
   701             attribClass(tree.pos(), c);
   706             attribClass(tree.pos(), c);
   861 
   866 
   862         try {
   867         try {
   863             chk.checkDeprecatedAnnotation(tree.pos(), v);
   868             chk.checkDeprecatedAnnotation(tree.pos(), v);
   864 
   869 
   865             if (tree.init != null) {
   870             if (tree.init != null) {
   866                 if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) {
   871                 if ((v.flags_field & FINAL) != 0 && !tree.init.hasTag(NEWCLASS)) {
   867                     // In this case, `v' is final.  Ensure that it's initializer is
   872                     // In this case, `v' is final.  Ensure that it's initializer is
   868                     // evaluated.
   873                     // evaluated.
   869                     v.getConstValue(); // ensure initializer is evaluated
   874                     v.getConstValue(); // ensure initializer is evaluated
   870                 } else {
   875                 } else {
   871                     // Attribute initializer in a new environment
   876                     // Attribute initializer in a new environment
   969     }
   974     }
   970 
   975 
   971     public void visitLabelled(JCLabeledStatement tree) {
   976     public void visitLabelled(JCLabeledStatement tree) {
   972         // Check that label is not used in an enclosing statement
   977         // Check that label is not used in an enclosing statement
   973         Env<AttrContext> env1 = env;
   978         Env<AttrContext> env1 = env;
   974         while (env1 != null && env1.tree.getTag() != JCTree.CLASSDEF) {
   979         while (env1 != null && !env1.tree.hasTag(CLASSDEF)) {
   975             if (env1.tree.getTag() == JCTree.LABELLED &&
   980             if (env1.tree.hasTag(LABELLED) &&
   976                 ((JCLabeledStatement) env1.tree).label == tree.label) {
   981                 ((JCLabeledStatement) env1.tree).label == tree.label) {
   977                 log.error(tree.pos(), "label.already.in.use",
   982                 log.error(tree.pos(), "label.already.in.use",
   978                           tree.label);
   983                           tree.label);
   979                 break;
   984                 break;
   980             }
   985             }
  1050     // where
  1055     // where
  1051         /** Add any variables defined in stats to the switch scope. */
  1056         /** Add any variables defined in stats to the switch scope. */
  1052         private static void addVars(List<JCStatement> stats, Scope switchScope) {
  1057         private static void addVars(List<JCStatement> stats, Scope switchScope) {
  1053             for (;stats.nonEmpty(); stats = stats.tail) {
  1058             for (;stats.nonEmpty(); stats = stats.tail) {
  1054                 JCTree stat = stats.head;
  1059                 JCTree stat = stats.head;
  1055                 if (stat.getTag() == JCTree.VARDEF)
  1060                 if (stat.hasTag(VARDEF))
  1056                     switchScope.enter(((JCVariableDecl) stat).sym);
  1061                     switchScope.enter(((JCVariableDecl) stat).sym);
  1057             }
  1062             }
  1058         }
  1063         }
  1059     // where
  1064     // where
  1060     /** Return the selected enumeration constant symbol, or null. */
  1065     /** Return the selected enumeration constant symbol, or null. */
  1061     private Symbol enumConstant(JCTree tree, Type enumType) {
  1066     private Symbol enumConstant(JCTree tree, Type enumType) {
  1062         if (tree.getTag() != JCTree.IDENT) {
  1067         if (!tree.hasTag(IDENT)) {
  1063             log.error(tree.pos(), "enum.label.must.be.unqualified.enum");
  1068             log.error(tree.pos(), "enum.label.must.be.unqualified.enum");
  1064             return syms.errSymbol;
  1069             return syms.errSymbol;
  1065         }
  1070         }
  1066         JCIdent ident = (JCIdent)tree;
  1071         JCIdent ident = (JCIdent)tree;
  1067         Name name = ident.name;
  1072         Name name = ident.name;
  1092         Env<AttrContext> tryEnv = isTryWithResource ?
  1097         Env<AttrContext> tryEnv = isTryWithResource ?
  1093             env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
  1098             env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
  1094             localEnv;
  1099             localEnv;
  1095         // Attribute resource declarations
  1100         // Attribute resource declarations
  1096         for (JCTree resource : tree.resources) {
  1101         for (JCTree resource : tree.resources) {
  1097             if (resource.getTag() == JCTree.VARDEF) {
  1102             if (resource.hasTag(VARDEF)) {
  1098                 attribStat(resource, tryEnv);
  1103                 attribStat(resource, tryEnv);
  1099                 chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type");
  1104                 chk.checkType(resource, resource.type, syms.autoCloseableType, "try.not.applicable.to.type");
  1100 
  1105 
  1101                 //check that resource type cannot throw InterruptedException
  1106                 //check that resource type cannot throw InterruptedException
  1102                 checkAutoCloseable(resource.pos(), localEnv, resource.type);
  1107                 checkAutoCloseable(resource.pos(), localEnv, resource.type);
  1310          *  @param label   The label of the jump statement, or null if no
  1315          *  @param label   The label of the jump statement, or null if no
  1311          *                 label is given.
  1316          *                 label is given.
  1312          *  @param env     The environment current at the jump statement.
  1317          *  @param env     The environment current at the jump statement.
  1313          */
  1318          */
  1314         private JCTree findJumpTarget(DiagnosticPosition pos,
  1319         private JCTree findJumpTarget(DiagnosticPosition pos,
  1315                                     int tag,
  1320                                     JCTree.Tag tag,
  1316                                     Name label,
  1321                                     Name label,
  1317                                     Env<AttrContext> env) {
  1322                                     Env<AttrContext> env) {
  1318             // Search environments outwards from the point of jump.
  1323             // Search environments outwards from the point of jump.
  1319             Env<AttrContext> env1 = env;
  1324             Env<AttrContext> env1 = env;
  1320             LOOP:
  1325             LOOP:
  1321             while (env1 != null) {
  1326             while (env1 != null) {
  1322                 switch (env1.tree.getTag()) {
  1327                 switch (env1.tree.getTag()) {
  1323                 case JCTree.LABELLED:
  1328                 case LABELLED:
  1324                     JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
  1329                     JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
  1325                     if (label == labelled.label) {
  1330                     if (label == labelled.label) {
  1326                         // If jump is a continue, check that target is a loop.
  1331                         // If jump is a continue, check that target is a loop.
  1327                         if (tag == JCTree.CONTINUE) {
  1332                         if (tag == CONTINUE) {
  1328                             if (labelled.body.getTag() != JCTree.DOLOOP &&
  1333                             if (!labelled.body.hasTag(DOLOOP) &&
  1329                                 labelled.body.getTag() != JCTree.WHILELOOP &&
  1334                                 !labelled.body.hasTag(WHILELOOP) &&
  1330                                 labelled.body.getTag() != JCTree.FORLOOP &&
  1335                                 !labelled.body.hasTag(FORLOOP) &&
  1331                                 labelled.body.getTag() != JCTree.FOREACHLOOP)
  1336                                 !labelled.body.hasTag(FOREACHLOOP))
  1332                                 log.error(pos, "not.loop.label", label);
  1337                                 log.error(pos, "not.loop.label", label);
  1333                             // Found labelled statement target, now go inwards
  1338                             // Found labelled statement target, now go inwards
  1334                             // to next non-labelled tree.
  1339                             // to next non-labelled tree.
  1335                             return TreeInfo.referencedStatement(labelled);
  1340                             return TreeInfo.referencedStatement(labelled);
  1336                         } else {
  1341                         } else {
  1337                             return labelled;
  1342                             return labelled;
  1338                         }
  1343                         }
  1339                     }
  1344                     }
  1340                     break;
  1345                     break;
  1341                 case JCTree.DOLOOP:
  1346                 case DOLOOP:
  1342                 case JCTree.WHILELOOP:
  1347                 case WHILELOOP:
  1343                 case JCTree.FORLOOP:
  1348                 case FORLOOP:
  1344                 case JCTree.FOREACHLOOP:
  1349                 case FOREACHLOOP:
  1345                     if (label == null) return env1.tree;
  1350                     if (label == null) return env1.tree;
  1346                     break;
  1351                     break;
  1347                 case JCTree.SWITCH:
  1352                 case SWITCH:
  1348                     if (label == null && tag == JCTree.BREAK) return env1.tree;
  1353                     if (label == null && tag == BREAK) return env1.tree;
  1349                     break;
  1354                     break;
  1350                 case JCTree.METHODDEF:
  1355                 case METHODDEF:
  1351                 case JCTree.CLASSDEF:
  1356                 case CLASSDEF:
  1352                     break LOOP;
  1357                     break LOOP;
  1353                 default:
  1358                 default:
  1354                 }
  1359                 }
  1355                 env1 = env1.next;
  1360                 env1 = env1.next;
  1356             }
  1361             }
  1357             if (label != null)
  1362             if (label != null)
  1358                 log.error(pos, "undef.label", label);
  1363                 log.error(pos, "undef.label", label);
  1359             else if (tag == JCTree.CONTINUE)
  1364             else if (tag == CONTINUE)
  1360                 log.error(pos, "cont.outside.loop");
  1365                 log.error(pos, "cont.outside.loop");
  1361             else
  1366             else
  1362                 log.error(pos, "break.outside.switch.loop");
  1367                 log.error(pos, "break.outside.switch.loop");
  1363             return null;
  1368             return null;
  1364         }
  1369         }
  1450                     while (encl != null && encl.tag == TYPEVAR)
  1455                     while (encl != null && encl.tag == TYPEVAR)
  1451                         encl = encl.getUpperBound();
  1456                         encl = encl.getUpperBound();
  1452                     if (encl.tag == CLASS) {
  1457                     if (encl.tag == CLASS) {
  1453                         // we are calling a nested class
  1458                         // we are calling a nested class
  1454 
  1459 
  1455                         if (tree.meth.getTag() == JCTree.SELECT) {
  1460                         if (tree.meth.hasTag(SELECT)) {
  1456                             JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
  1461                             JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
  1457 
  1462 
  1458                             // We are seeing a prefixed call, of the form
  1463                             // We are seeing a prefixed call, of the form
  1459                             //     <expr>.super(...).
  1464                             //     <expr>.super(...).
  1460                             // Check that the prefix expression conforms
  1465                             // Check that the prefix expression conforms
  1466                             // qualifier omitted; check for existence
  1471                             // qualifier omitted; check for existence
  1467                             // of an appropriate implicit qualifier.
  1472                             // of an appropriate implicit qualifier.
  1468                             rs.resolveImplicitThis(tree.meth.pos(),
  1473                             rs.resolveImplicitThis(tree.meth.pos(),
  1469                                                    localEnv, site, true);
  1474                                                    localEnv, site, true);
  1470                         }
  1475                         }
  1471                     } else if (tree.meth.getTag() == JCTree.SELECT) {
  1476                     } else if (tree.meth.hasTag(SELECT)) {
  1472                         log.error(tree.meth.pos(), "illegal.qual.not.icls",
  1477                         log.error(tree.meth.pos(), "illegal.qual.not.icls",
  1473                                   site.tsym);
  1478                                   site.tsym);
  1474                     }
  1479                     }
  1475 
  1480 
  1476                     // if we're calling a java.lang.Enum constructor,
  1481                     // if we're calling a java.lang.Enum constructor,
  1520             if (restype.tag == WILDCARD)
  1525             if (restype.tag == WILDCARD)
  1521                 throw new AssertionError(mtype);
  1526                 throw new AssertionError(mtype);
  1522 
  1527 
  1523             // as a special case, array.clone() has a result that is
  1528             // as a special case, array.clone() has a result that is
  1524             // the same as static type of the array being cloned
  1529             // the same as static type of the array being cloned
  1525             if (tree.meth.getTag() == JCTree.SELECT &&
  1530             if (tree.meth.hasTag(SELECT) &&
  1526                 allowCovariantReturns &&
  1531                 allowCovariantReturns &&
  1527                 methName == names.clone &&
  1532                 methName == names.clone &&
  1528                 types.isArray(((JCFieldAccess) tree.meth).selected.type))
  1533                 types.isArray(((JCFieldAccess) tree.meth).selected.type))
  1529                 restype = ((JCFieldAccess) tree.meth).selected.type;
  1534                 restype = ((JCFieldAccess) tree.meth).selected.type;
  1530 
  1535 
  1531             // as a special case, x.getClass() has type Class<? extends |X|>
  1536             // as a special case, x.getClass() has type Class<? extends |X|>
  1532             if (allowGenerics &&
  1537             if (allowGenerics &&
  1533                 methName == names.getClass && tree.args.isEmpty()) {
  1538                 methName == names.getClass && tree.args.isEmpty()) {
  1534                 Type qualifier = (tree.meth.getTag() == JCTree.SELECT)
  1539                 Type qualifier = (tree.meth.hasTag(SELECT))
  1535                     ? ((JCFieldAccess) tree.meth).selected.type
  1540                     ? ((JCFieldAccess) tree.meth).selected.type
  1536                     : env.enclClass.sym.type;
  1541                     : env.enclClass.sym.type;
  1537                 restype = new
  1542                 restype = new
  1538                     ClassType(restype.getEnclosingType(),
  1543                     ClassType(restype.getEnclosingType(),
  1539                               List.<Type>of(new WildcardType(types.erasure(qualifier),
  1544                               List.<Type>of(new WildcardType(types.erasure(qualifier),
  1558          */
  1563          */
  1559         boolean checkFirstConstructorStat(JCMethodInvocation tree, Env<AttrContext> env) {
  1564         boolean checkFirstConstructorStat(JCMethodInvocation tree, Env<AttrContext> env) {
  1560             JCMethodDecl enclMethod = env.enclMethod;
  1565             JCMethodDecl enclMethod = env.enclMethod;
  1561             if (enclMethod != null && enclMethod.name == names.init) {
  1566             if (enclMethod != null && enclMethod.name == names.init) {
  1562                 JCBlock body = enclMethod.body;
  1567                 JCBlock body = enclMethod.body;
  1563                 if (body.stats.head.getTag() == JCTree.EXEC &&
  1568                 if (body.stats.head.hasTag(EXEC) &&
  1564                     ((JCExpressionStatement) body.stats.head).expr == tree)
  1569                     ((JCExpressionStatement) body.stats.head).expr == tree)
  1565                     return true;
  1570                     return true;
  1566             }
  1571             }
  1567             log.error(tree.pos(),"call.must.be.first.stmt.in.ctor",
  1572             log.error(tree.pos(),"call.must.be.first.stmt.in.ctor",
  1568                       TreeInfo.name(tree.meth));
  1573                       TreeInfo.name(tree.meth));
  1589 
  1594 
  1590         // If enclosing class is given, attribute it, and
  1595         // If enclosing class is given, attribute it, and
  1591         // complete class name to be fully qualified
  1596         // complete class name to be fully qualified
  1592         JCExpression clazz = tree.clazz; // Class field following new
  1597         JCExpression clazz = tree.clazz; // Class field following new
  1593         JCExpression clazzid =          // Identifier in class field
  1598         JCExpression clazzid =          // Identifier in class field
  1594             (clazz.getTag() == JCTree.TYPEAPPLY)
  1599             (clazz.hasTag(TYPEAPPLY))
  1595             ? ((JCTypeApply) clazz).clazz
  1600             ? ((JCTypeApply) clazz).clazz
  1596             : clazz;
  1601             : clazz;
  1597 
  1602 
  1598         JCExpression clazzid1 = clazzid; // The same in fully qualified form
  1603         JCExpression clazzid1 = clazzid; // The same in fully qualified form
  1599 
  1604 
  1608             // yields a clazz T.C.
  1613             // yields a clazz T.C.
  1609             Type encltype = chk.checkRefType(tree.encl.pos(),
  1614             Type encltype = chk.checkRefType(tree.encl.pos(),
  1610                                              attribExpr(tree.encl, env));
  1615                                              attribExpr(tree.encl, env));
  1611             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
  1616             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
  1612                                                  ((JCIdent) clazzid).name);
  1617                                                  ((JCIdent) clazzid).name);
  1613             if (clazz.getTag() == JCTree.TYPEAPPLY)
  1618             if (clazz.hasTag(TYPEAPPLY))
  1614                 clazz = make.at(tree.pos).
  1619                 clazz = make.at(tree.pos).
  1615                     TypeApply(clazzid1,
  1620                     TypeApply(clazzid1,
  1616                               ((JCTypeApply) clazz).arguments);
  1621                               ((JCTypeApply) clazz).arguments);
  1617             else
  1622             else
  1618                 clazz = clazzid1;
  1623                 clazz = clazzid1;
  1687         // If we have made no mistakes in the class type...
  1692         // If we have made no mistakes in the class type...
  1688         if (clazztype.tag == CLASS) {
  1693         if (clazztype.tag == CLASS) {
  1689             // Enums may not be instantiated except implicitly
  1694             // Enums may not be instantiated except implicitly
  1690             if (allowEnums &&
  1695             if (allowEnums &&
  1691                 (clazztype.tsym.flags_field&Flags.ENUM) != 0 &&
  1696                 (clazztype.tsym.flags_field&Flags.ENUM) != 0 &&
  1692                 (env.tree.getTag() != JCTree.VARDEF ||
  1697                 (!env.tree.hasTag(VARDEF) ||
  1693                  (((JCVariableDecl) env.tree).mods.flags&Flags.ENUM) == 0 ||
  1698                  (((JCVariableDecl) env.tree).mods.flags&Flags.ENUM) == 0 ||
  1694                  ((JCVariableDecl) env.tree).init != tree))
  1699                  ((JCVariableDecl) env.tree).init != tree))
  1695                 log.error(tree.pos(), "enum.cant.be.instantiated");
  1700                 log.error(tree.pos(), "enum.cant.be.instantiated");
  1696             // Check that class is not abstract
  1701             // Check that class is not abstract
  1697             if (cdef == null &&
  1702             if (cdef == null &&
  1928     public JCExpression makeNullCheck(JCExpression arg) {
  1933     public JCExpression makeNullCheck(JCExpression arg) {
  1929         // optimization: X.this is never null; skip null check
  1934         // optimization: X.this is never null; skip null check
  1930         Name name = TreeInfo.name(arg);
  1935         Name name = TreeInfo.name(arg);
  1931         if (name == names._this || name == names._super) return arg;
  1936         if (name == names._this || name == names._super) return arg;
  1932 
  1937 
  1933         int optag = JCTree.NULLCHK;
  1938         JCTree.Tag optag = NULLCHK;
  1934         JCUnary tree = make.at(arg.pos).Unary(optag, arg);
  1939         JCUnary tree = make.at(arg.pos).Unary(optag, arg);
  1935         tree.operator = syms.nullcheck;
  1940         tree.operator = syms.nullcheck;
  1936         tree.type = arg.type;
  1941         tree.type = arg.type;
  1937         return tree;
  1942         return tree;
  1938     }
  1943     }
  1989         // Attribute arguments.
  1994         // Attribute arguments.
  1990         Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
  1995         Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
  1991         Type operand = attribExpr(tree.rhs, env);
  1996         Type operand = attribExpr(tree.rhs, env);
  1992         // Find operator.
  1997         // Find operator.
  1993         Symbol operator = tree.operator = rs.resolveBinaryOperator(
  1998         Symbol operator = tree.operator = rs.resolveBinaryOperator(
  1994             tree.pos(), tree.getTag() - JCTree.ASGOffset, env,
  1999             tree.pos(), tree.getTag().noAssignOp(), env,
  1995             owntype, operand);
  2000             owntype, operand);
  1996 
  2001 
  1997         if (operator.kind == MTH &&
  2002         if (operator.kind == MTH &&
  1998                 !owntype.isErroneous() &&
  2003                 !owntype.isErroneous() &&
  1999                 !operand.isErroneous()) {
  2004                 !operand.isErroneous()) {
  2000             chk.checkOperator(tree.pos(),
  2005             chk.checkOperator(tree.pos(),
  2001                               (OperatorSymbol)operator,
  2006                               (OperatorSymbol)operator,
  2002                               tree.getTag() - JCTree.ASGOffset,
  2007                               tree.getTag().noAssignOp(),
  2003                               owntype,
  2008                               owntype,
  2004                               operand);
  2009                               operand);
  2005             chk.checkDivZero(tree.rhs.pos(), operator, operand);
  2010             chk.checkDivZero(tree.rhs.pos(), operator, operand);
  2006             chk.checkCastable(tree.rhs.pos(),
  2011             chk.checkCastable(tree.rhs.pos(),
  2007                               operator.type.getReturnType(),
  2012                               operator.type.getReturnType(),
  2010         result = check(tree, owntype, VAL, pkind, pt);
  2015         result = check(tree, owntype, VAL, pkind, pt);
  2011     }
  2016     }
  2012 
  2017 
  2013     public void visitUnary(JCUnary tree) {
  2018     public void visitUnary(JCUnary tree) {
  2014         // Attribute arguments.
  2019         // Attribute arguments.
  2015         Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
  2020         Type argtype = (tree.getTag().isIncOrDecUnaryOp())
  2016             ? attribTree(tree.arg, env, VAR, Type.noType)
  2021             ? attribTree(tree.arg, env, VAR, Type.noType)
  2017             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
  2022             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
  2018 
  2023 
  2019         // Find operator.
  2024         // Find operator.
  2020         Symbol operator = tree.operator =
  2025         Symbol operator = tree.operator =
  2021             rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
  2026             rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
  2022 
  2027 
  2023         Type owntype = types.createErrorType(tree.type);
  2028         Type owntype = types.createErrorType(tree.type);
  2024         if (operator.kind == MTH &&
  2029         if (operator.kind == MTH &&
  2025                 !argtype.isErroneous()) {
  2030                 !argtype.isErroneous()) {
  2026             owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
  2031             owntype = (tree.getTag().isIncOrDecUnaryOp())
  2027                 ? tree.arg.type
  2032                 ? tree.arg.type
  2028                 : operator.type.getReturnType();
  2033                 : operator.type.getReturnType();
  2029             int opc = ((OperatorSymbol)operator).opcode;
  2034             int opc = ((OperatorSymbol)operator).opcode;
  2030 
  2035 
  2031             // If the argument is constant, fold it.
  2036             // If the argument is constant, fold it.
  2619             if ((env.info.enclVar == v || v.pos > tree.pos) &&
  2624             if ((env.info.enclVar == v || v.pos > tree.pos) &&
  2620                 v.owner.kind == TYP &&
  2625                 v.owner.kind == TYP &&
  2621                 canOwnInitializer(env.info.scope.owner) &&
  2626                 canOwnInitializer(env.info.scope.owner) &&
  2622                 v.owner == env.info.scope.owner.enclClass() &&
  2627                 v.owner == env.info.scope.owner.enclClass() &&
  2623                 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
  2628                 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
  2624                 (env.tree.getTag() != JCTree.ASSIGN ||
  2629                 (!env.tree.hasTag(ASSIGN) ||
  2625                  TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
  2630                  TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
  2626                 String suffix = (env.info.enclVar == v) ?
  2631                 String suffix = (env.info.enclVar == v) ?
  2627                                 "self.ref" : "forward.ref";
  2632                                 "self.ref" : "forward.ref";
  2628                 if (!onlyWarning || isStaticEnumField(v)) {
  2633                 if (!onlyWarning || isStaticEnumField(v)) {
  2629                     log.error(tree.pos(), "illegal." + suffix);
  2634                     log.error(tree.pos(), "illegal." + suffix);
  2810                 if (owntype.getReturnType().tag != FORALL || warned) {
  2815                 if (owntype.getReturnType().tag != FORALL || warned) {
  2811                     chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
  2816                     chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym);
  2812                 }
  2817                 }
  2813                 Type elemtype = types.elemtype(argtype);
  2818                 Type elemtype = types.elemtype(argtype);
  2814                 switch (tree.getTag()) {
  2819                 switch (tree.getTag()) {
  2815                 case JCTree.APPLY:
  2820                 case APPLY:
  2816                     ((JCMethodInvocation) tree).varargsElement = elemtype;
  2821                     ((JCMethodInvocation) tree).varargsElement = elemtype;
  2817                     break;
  2822                     break;
  2818                 case JCTree.NEWCLASS:
  2823                 case NEWCLASS:
  2819                     ((JCNewClass) tree).varargsElement = elemtype;
  2824                     ((JCNewClass) tree).varargsElement = elemtype;
  2820                     break;
  2825                     break;
  2821                 default:
  2826                 default:
  2822                     throw new AssertionError(""+tree);
  2827                     throw new AssertionError(""+tree);
  2823                 }
  2828                 }
  2894                 // Compute the proper generic outer
  2899                 // Compute the proper generic outer
  2895                 Type clazzOuter = clazztype.getEnclosingType();
  2900                 Type clazzOuter = clazztype.getEnclosingType();
  2896                 if (clazzOuter.tag == CLASS) {
  2901                 if (clazzOuter.tag == CLASS) {
  2897                     Type site;
  2902                     Type site;
  2898                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
  2903                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
  2899                     if (clazz.getTag() == JCTree.IDENT) {
  2904                     if (clazz.hasTag(IDENT)) {
  2900                         site = env.enclClass.sym.type;
  2905                         site = env.enclClass.sym.type;
  2901                     } else if (clazz.getTag() == JCTree.SELECT) {
  2906                     } else if (clazz.hasTag(SELECT)) {
  2902                         site = ((JCFieldAccess) clazz).selected.type;
  2907                         site = ((JCFieldAccess) clazz).selected.type;
  2903                     } else throw new AssertionError(""+tree);
  2908                     } else throw new AssertionError(""+tree);
  2904                     if (clazzOuter.tag == CLASS && site != clazzOuter) {
  2909                     if (clazzOuter.tag == CLASS && site != clazzOuter) {
  2905                         if (site.tag == CLASS)
  2910                         if (site.tag == CLASS)
  2906                             site = types.asOuterSuper(site, clazzOuter.tsym);
  2911                             site = types.asOuterSuper(site, clazzOuter.tsym);
  3066 
  3071 
  3067     /**
  3072     /**
  3068      * Attribute an env for either a top level tree or class declaration.
  3073      * Attribute an env for either a top level tree or class declaration.
  3069      */
  3074      */
  3070     public void attrib(Env<AttrContext> env) {
  3075     public void attrib(Env<AttrContext> env) {
  3071         if (env.tree.getTag() == JCTree.TOPLEVEL)
  3076         if (env.tree.hasTag(TOPLEVEL))
  3072             attribTopLevel(env);
  3077             attribTopLevel(env);
  3073         else
  3078         else
  3074             attribClass(env.tree.pos(), env.enclClass.sym);
  3079             attribClass(env.tree.pos(), env.enclClass.sym);
  3075     }
  3080     }
  3076 
  3081 
  3243             // Make an exception for static constants.
  3248             // Make an exception for static constants.
  3244             if (c.owner.kind != PCK &&
  3249             if (c.owner.kind != PCK &&
  3245                 ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
  3250                 ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
  3246                 (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
  3251                 (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
  3247                 Symbol sym = null;
  3252                 Symbol sym = null;
  3248                 if (l.head.getTag() == JCTree.VARDEF) sym = ((JCVariableDecl) l.head).sym;
  3253                 if (l.head.hasTag(VARDEF)) sym = ((JCVariableDecl) l.head).sym;
  3249                 if (sym == null ||
  3254                 if (sym == null ||
  3250                     sym.kind != VAR ||
  3255                     sym.kind != VAR ||
  3251                     ((VarSymbol) sym).getConstValue() == null)
  3256                     ((VarSymbol) sym).getConstValue() == null)
  3252                     log.error(l.head.pos(), "icls.cant.have.static.decl", c);
  3257                     log.error(l.head.pos(), "icls.cant.have.static.decl", c);
  3253             }
  3258             }