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); |
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 } |