970 VOLATILE)
971 &&
972 (sym.kind == TYP ||
973 checkDisjoint(pos, flags,
974 ABSTRACT | NATIVE,
975 STRICTFP))) {
976 // skip
977 }
978 return flags & (mask | ~StandardFlags) | implicit;
979 }
980
981
982 /** Determine if this enum should be implicitly final.
983 *
984 * If the enum has no specialized enum contants, it is final.
985 *
986 * If the enum does have specialized enum contants, it is
987 * <i>not</i> final.
988 */
989 private long implicitEnumFinalFlag(JCTree tree) {
990 if (tree.getTag() != JCTree.CLASSDEF) return 0;
991 class SpecialTreeVisitor extends JCTree.Visitor {
992 boolean specialized;
993 SpecialTreeVisitor() {
994 this.specialized = false;
995 };
996
997 @Override
998 public void visitTree(JCTree tree) { /* no-op */ }
999
1000 @Override
1001 public void visitVarDef(JCVariableDecl tree) {
1002 if ((tree.mods.flags & ENUM) != 0) {
1003 if (tree.init instanceof JCNewClass &&
1004 ((JCNewClass) tree.init).def != null) {
1005 specialized = true;
1006 }
1007 }
1008 }
1009 }
1010
1082 }
1083
1084 forms = tree.type.tsym.type.getTypeArguments();
1085
1086 boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
1087
1088 // For matching pairs of actual argument types `a' and
1089 // formal type parameters with declared bound `b' ...
1090 while (args.nonEmpty() && forms.nonEmpty()) {
1091 validateTree(args.head,
1092 !(isOuter && is_java_lang_Class),
1093 false);
1094 args = args.tail;
1095 forms = forms.tail;
1096 }
1097
1098 // Check that this type is either fully parameterized, or
1099 // not parameterized at all.
1100 if (tree.type.getEnclosingType().isRaw())
1101 log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
1102 if (tree.clazz.getTag() == JCTree.SELECT)
1103 visitSelectInternal((JCFieldAccess)tree.clazz);
1104 }
1105 }
1106
1107 @Override
1108 public void visitTypeParameter(JCTypeParameter tree) {
1109 validateTrees(tree.bounds, true, isOuter);
1110 checkClassBounds(tree.pos(), tree.type);
1111 }
1112
1113 @Override
1114 public void visitWildcard(JCWildcard tree) {
1115 if (tree.inner != null)
1116 validateTree(tree.inner, true, isOuter);
1117 }
1118
1119 @Override
1120 public void visitSelect(JCFieldAccess tree) {
1121 if (tree.type.tag == CLASS) {
1122 visitSelectInternal(tree);
2396 return false;
2397 }
2398
2399 /** Check an annotation value.
2400 */
2401 public void validateAnnotation(JCAnnotation a) {
2402 // collect an inventory of the members (sorted alphabetically)
2403 Set<MethodSymbol> members = new TreeSet<MethodSymbol>(new Comparator<Symbol>() {
2404 public int compare(Symbol t, Symbol t1) {
2405 return t.name.compareTo(t1.name);
2406 }
2407 });
2408 for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
2409 e != null;
2410 e = e.sibling)
2411 if (e.sym.kind == MTH)
2412 members.add((MethodSymbol) e.sym);
2413
2414 // count them off as they're annotated
2415 for (JCTree arg : a.args) {
2416 if (arg.getTag() != JCTree.ASSIGN) continue; // recovery
2417 JCAssign assign = (JCAssign) arg;
2418 Symbol m = TreeInfo.symbol(assign.lhs);
2419 if (m == null || m.type.isErroneous()) continue;
2420 if (!members.remove(m))
2421 log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
2422 m.name, a.type);
2423 }
2424
2425 // all the remaining ones better have default values
2426 ListBuffer<Name> missingDefaults = ListBuffer.lb();
2427 for (MethodSymbol m : members) {
2428 if (m.defaultValue == null && !m.type.isErroneous()) {
2429 missingDefaults.append(m.name);
2430 }
2431 }
2432 if (missingDefaults.nonEmpty()) {
2433 String key = (missingDefaults.size() > 1)
2434 ? "annotation.missing.default.value.1"
2435 : "annotation.missing.default.value";
2436 log.error(a.pos(), key, a.type, missingDefaults);
2437 }
2438
2439 // special case: java.lang.annotation.Target must not have
2440 // repeated values in its value member
2441 if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
2442 a.args.tail == null)
2443 return;
2444
2445 if (a.args.head.getTag() != JCTree.ASSIGN) return; // error recovery
2446 JCAssign assign = (JCAssign) a.args.head;
2447 Symbol m = TreeInfo.symbol(assign.lhs);
2448 if (m.name != names.value) return;
2449 JCTree rhs = assign.rhs;
2450 if (rhs.getTag() != JCTree.NEWARRAY) return;
2451 JCNewArray na = (JCNewArray) rhs;
2452 Set<Symbol> targets = new HashSet<Symbol>();
2453 for (JCTree elem : na.elems) {
2454 if (!targets.add(TreeInfo.symbol(elem))) {
2455 log.error(elem.pos(), "repeated.annotation.target");
2456 }
2457 }
2458 }
2459
2460 void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
2461 if (allowAnnotations &&
2462 lint.isEnabled(LintCategory.DEP_ANN) &&
2463 (s.flags() & DEPRECATED) != 0 &&
2464 !syms.deprecatedType.isErroneous() &&
2465 s.attribute(syms.deprecatedType.tsym) == null) {
2466 log.warning(LintCategory.DEP_ANN,
2467 pos, "missing.deprecated.annotation");
2468 }
2469 }
2470
2489 warnSunApi(pos, "sun.proprietary", s);
2490 else
2491 log.strictWarning(pos, "sun.proprietary", s);
2492 }
2493 });
2494 }
2495 }
2496
2497 /* *************************************************************************
2498 * Check for recursive annotation elements.
2499 **************************************************************************/
2500
2501 /** Check for cycles in the graph of annotation elements.
2502 */
2503 void checkNonCyclicElements(JCClassDecl tree) {
2504 if ((tree.sym.flags_field & ANNOTATION) == 0) return;
2505 Assert.check((tree.sym.flags_field & LOCKED) == 0);
2506 try {
2507 tree.sym.flags_field |= LOCKED;
2508 for (JCTree def : tree.defs) {
2509 if (def.getTag() != JCTree.METHODDEF) continue;
2510 JCMethodDecl meth = (JCMethodDecl)def;
2511 checkAnnotationResType(meth.pos(), meth.restype.type);
2512 }
2513 } finally {
2514 tree.sym.flags_field &= ~LOCKED;
2515 tree.sym.flags_field |= ACYCLIC_ANN;
2516 }
2517 }
2518
2519 void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
2520 if ((tsym.flags_field & ACYCLIC_ANN) != 0)
2521 return;
2522 if ((tsym.flags_field & LOCKED) != 0) {
2523 log.error(pos, "cyclic.annotation.element");
2524 return;
2525 }
2526 try {
2527 tsym.flags_field |= LOCKED;
2528 for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
2529 Symbol s = e.sym;
2597 }
2598 ctor.flags_field |= ACYCLIC;
2599 }
2600 }
2601
2602 /* *************************************************************************
2603 * Miscellaneous
2604 **************************************************************************/
2605
2606 /**
2607 * Return the opcode of the operator but emit an error if it is an
2608 * error.
2609 * @param pos position for error reporting.
2610 * @param operator an operator
2611 * @param tag a tree tag
2612 * @param left type of left hand side
2613 * @param right type of right hand side
2614 */
2615 int checkOperator(DiagnosticPosition pos,
2616 OperatorSymbol operator,
2617 int tag,
2618 Type left,
2619 Type right) {
2620 if (operator.opcode == ByteCodes.error) {
2621 log.error(pos,
2622 "operator.cant.be.applied.1",
2623 treeinfo.operatorName(tag),
2624 left, right);
2625 }
2626 return operator.opcode;
2627 }
2628
2629
2630 /**
2631 * Check for division by integer constant zero
2632 * @param pos Position for error reporting.
2633 * @param operator The operator for the expression
2634 * @param operand The right hand operand for the expression
2635 */
2636 void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
2637 if (operand.constValue() != null
2638 && lint.isEnabled(LintCategory.DIVZERO)
2639 && operand.tag <= LONG
2640 && ((Number) (operand.constValue())).longValue() == 0) {
2641 int opc = ((OperatorSymbol)operator).opcode;
2642 if (opc == ByteCodes.idiv || opc == ByteCodes.imod
2643 || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
2644 log.warning(LintCategory.DIVZERO, pos, "div.zero");
2645 }
2646 }
2647 }
2648
2649 /**
2650 * Check for empty statements after if
2651 */
2652 void checkEmptyIf(JCIf tree) {
2653 if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(LintCategory.EMPTY))
2654 log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
2655 }
2656
2657 /** Check that symbol is unique in given scope.
2658 * @param pos Position for error reporting.
2659 * @param sym The symbol.
2660 * @param s The scope.
2661 */
2662 boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
2663 if (sym.type.isErroneous())
2664 return true;
2665 if (sym.owner.name == names.any) return false;
2666 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
2667 if (sym != e.sym &&
2668 (e.sym.flags() & CLASH) == 0 &&
2669 sym.kind == e.sym.kind &&
2670 sym.name != names.error &&
2671 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
2672 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
2673 varargsDuplicateError(pos, sym, e.sym);
2737 log.error(pos, "already.defined.single.import", what);
2738 }
2739 else if (sym != e.sym)
2740 log.error(pos, "already.defined.this.unit", what);
2741 }
2742 return false;
2743 }
2744 }
2745 return true;
2746 }
2747
2748 /** Check that a qualified name is in canonical form (for import decls).
2749 */
2750 public void checkCanonical(JCTree tree) {
2751 if (!isCanonical(tree))
2752 log.error(tree.pos(), "import.requires.canonical",
2753 TreeInfo.symbol(tree));
2754 }
2755 // where
2756 private boolean isCanonical(JCTree tree) {
2757 while (tree.getTag() == JCTree.SELECT) {
2758 JCFieldAccess s = (JCFieldAccess) tree;
2759 if (s.sym.owner != TreeInfo.symbol(s.selected))
2760 return false;
2761 tree = s.selected;
2762 }
2763 return true;
2764 }
2765
2766 private class ConversionWarner extends Warner {
2767 final String uncheckedKey;
2768 final Type found;
2769 final Type expected;
2770 public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
2771 super(pos);
2772 this.uncheckedKey = uncheckedKey;
2773 this.found = found;
2774 this.expected = expected;
2775 }
2776
2777 @Override
|
970 VOLATILE)
971 &&
972 (sym.kind == TYP ||
973 checkDisjoint(pos, flags,
974 ABSTRACT | NATIVE,
975 STRICTFP))) {
976 // skip
977 }
978 return flags & (mask | ~StandardFlags) | implicit;
979 }
980
981
982 /** Determine if this enum should be implicitly final.
983 *
984 * If the enum has no specialized enum contants, it is final.
985 *
986 * If the enum does have specialized enum contants, it is
987 * <i>not</i> final.
988 */
989 private long implicitEnumFinalFlag(JCTree tree) {
990 if (tree.getTag() != JCTree.Tag.CLASSDEF) return 0;
991 class SpecialTreeVisitor extends JCTree.Visitor {
992 boolean specialized;
993 SpecialTreeVisitor() {
994 this.specialized = false;
995 };
996
997 @Override
998 public void visitTree(JCTree tree) { /* no-op */ }
999
1000 @Override
1001 public void visitVarDef(JCVariableDecl tree) {
1002 if ((tree.mods.flags & ENUM) != 0) {
1003 if (tree.init instanceof JCNewClass &&
1004 ((JCNewClass) tree.init).def != null) {
1005 specialized = true;
1006 }
1007 }
1008 }
1009 }
1010
1082 }
1083
1084 forms = tree.type.tsym.type.getTypeArguments();
1085
1086 boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
1087
1088 // For matching pairs of actual argument types `a' and
1089 // formal type parameters with declared bound `b' ...
1090 while (args.nonEmpty() && forms.nonEmpty()) {
1091 validateTree(args.head,
1092 !(isOuter && is_java_lang_Class),
1093 false);
1094 args = args.tail;
1095 forms = forms.tail;
1096 }
1097
1098 // Check that this type is either fully parameterized, or
1099 // not parameterized at all.
1100 if (tree.type.getEnclosingType().isRaw())
1101 log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
1102 if (tree.clazz.getTag() == JCTree.Tag.SELECT)
1103 visitSelectInternal((JCFieldAccess)tree.clazz);
1104 }
1105 }
1106
1107 @Override
1108 public void visitTypeParameter(JCTypeParameter tree) {
1109 validateTrees(tree.bounds, true, isOuter);
1110 checkClassBounds(tree.pos(), tree.type);
1111 }
1112
1113 @Override
1114 public void visitWildcard(JCWildcard tree) {
1115 if (tree.inner != null)
1116 validateTree(tree.inner, true, isOuter);
1117 }
1118
1119 @Override
1120 public void visitSelect(JCFieldAccess tree) {
1121 if (tree.type.tag == CLASS) {
1122 visitSelectInternal(tree);
2396 return false;
2397 }
2398
2399 /** Check an annotation value.
2400 */
2401 public void validateAnnotation(JCAnnotation a) {
2402 // collect an inventory of the members (sorted alphabetically)
2403 Set<MethodSymbol> members = new TreeSet<MethodSymbol>(new Comparator<Symbol>() {
2404 public int compare(Symbol t, Symbol t1) {
2405 return t.name.compareTo(t1.name);
2406 }
2407 });
2408 for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
2409 e != null;
2410 e = e.sibling)
2411 if (e.sym.kind == MTH)
2412 members.add((MethodSymbol) e.sym);
2413
2414 // count them off as they're annotated
2415 for (JCTree arg : a.args) {
2416 if (arg.getTag() != JCTree.Tag.ASSIGN) continue; // recovery
2417 JCAssign assign = (JCAssign) arg;
2418 Symbol m = TreeInfo.symbol(assign.lhs);
2419 if (m == null || m.type.isErroneous()) continue;
2420 if (!members.remove(m))
2421 log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
2422 m.name, a.type);
2423 }
2424
2425 // all the remaining ones better have default values
2426 ListBuffer<Name> missingDefaults = ListBuffer.lb();
2427 for (MethodSymbol m : members) {
2428 if (m.defaultValue == null && !m.type.isErroneous()) {
2429 missingDefaults.append(m.name);
2430 }
2431 }
2432 if (missingDefaults.nonEmpty()) {
2433 String key = (missingDefaults.size() > 1)
2434 ? "annotation.missing.default.value.1"
2435 : "annotation.missing.default.value";
2436 log.error(a.pos(), key, a.type, missingDefaults);
2437 }
2438
2439 // special case: java.lang.annotation.Target must not have
2440 // repeated values in its value member
2441 if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
2442 a.args.tail == null)
2443 return;
2444
2445 if (a.args.head.getTag() != JCTree.Tag.ASSIGN) return; // error recovery
2446 JCAssign assign = (JCAssign) a.args.head;
2447 Symbol m = TreeInfo.symbol(assign.lhs);
2448 if (m.name != names.value) return;
2449 JCTree rhs = assign.rhs;
2450 if (rhs.getTag() != JCTree.Tag.NEWARRAY) return;
2451 JCNewArray na = (JCNewArray) rhs;
2452 Set<Symbol> targets = new HashSet<Symbol>();
2453 for (JCTree elem : na.elems) {
2454 if (!targets.add(TreeInfo.symbol(elem))) {
2455 log.error(elem.pos(), "repeated.annotation.target");
2456 }
2457 }
2458 }
2459
2460 void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
2461 if (allowAnnotations &&
2462 lint.isEnabled(LintCategory.DEP_ANN) &&
2463 (s.flags() & DEPRECATED) != 0 &&
2464 !syms.deprecatedType.isErroneous() &&
2465 s.attribute(syms.deprecatedType.tsym) == null) {
2466 log.warning(LintCategory.DEP_ANN,
2467 pos, "missing.deprecated.annotation");
2468 }
2469 }
2470
2489 warnSunApi(pos, "sun.proprietary", s);
2490 else
2491 log.strictWarning(pos, "sun.proprietary", s);
2492 }
2493 });
2494 }
2495 }
2496
2497 /* *************************************************************************
2498 * Check for recursive annotation elements.
2499 **************************************************************************/
2500
2501 /** Check for cycles in the graph of annotation elements.
2502 */
2503 void checkNonCyclicElements(JCClassDecl tree) {
2504 if ((tree.sym.flags_field & ANNOTATION) == 0) return;
2505 Assert.check((tree.sym.flags_field & LOCKED) == 0);
2506 try {
2507 tree.sym.flags_field |= LOCKED;
2508 for (JCTree def : tree.defs) {
2509 if (def.getTag() != JCTree.Tag.METHODDEF) continue;
2510 JCMethodDecl meth = (JCMethodDecl)def;
2511 checkAnnotationResType(meth.pos(), meth.restype.type);
2512 }
2513 } finally {
2514 tree.sym.flags_field &= ~LOCKED;
2515 tree.sym.flags_field |= ACYCLIC_ANN;
2516 }
2517 }
2518
2519 void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
2520 if ((tsym.flags_field & ACYCLIC_ANN) != 0)
2521 return;
2522 if ((tsym.flags_field & LOCKED) != 0) {
2523 log.error(pos, "cyclic.annotation.element");
2524 return;
2525 }
2526 try {
2527 tsym.flags_field |= LOCKED;
2528 for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
2529 Symbol s = e.sym;
2597 }
2598 ctor.flags_field |= ACYCLIC;
2599 }
2600 }
2601
2602 /* *************************************************************************
2603 * Miscellaneous
2604 **************************************************************************/
2605
2606 /**
2607 * Return the opcode of the operator but emit an error if it is an
2608 * error.
2609 * @param pos position for error reporting.
2610 * @param operator an operator
2611 * @param tag a tree tag
2612 * @param left type of left hand side
2613 * @param right type of right hand side
2614 */
2615 int checkOperator(DiagnosticPosition pos,
2616 OperatorSymbol operator,
2617 JCTree.Tag tag,
2618 Type left,
2619 Type right) {
2620 if (operator.opcode == ByteCodes.error) {
2621 log.error(pos,
2622 "operator.cant.be.applied.1",
2623 treeinfo.operatorName(tag),
2624 left, right);
2625 }
2626 return operator.opcode;
2627 }
2628
2629
2630 /**
2631 * Check for division by integer constant zero
2632 * @param pos Position for error reporting.
2633 * @param operator The operator for the expression
2634 * @param operand The right hand operand for the expression
2635 */
2636 void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
2637 if (operand.constValue() != null
2638 && lint.isEnabled(LintCategory.DIVZERO)
2639 && operand.tag <= LONG
2640 && ((Number) (operand.constValue())).longValue() == 0) {
2641 int opc = ((OperatorSymbol)operator).opcode;
2642 if (opc == ByteCodes.idiv || opc == ByteCodes.imod
2643 || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
2644 log.warning(LintCategory.DIVZERO, pos, "div.zero");
2645 }
2646 }
2647 }
2648
2649 /**
2650 * Check for empty statements after if
2651 */
2652 void checkEmptyIf(JCIf tree) {
2653 if (tree.thenpart.getTag() == JCTree.Tag.SKIP && tree.elsepart == null &&
2654 lint.isEnabled(LintCategory.EMPTY))
2655 log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
2656 }
2657
2658 /** Check that symbol is unique in given scope.
2659 * @param pos Position for error reporting.
2660 * @param sym The symbol.
2661 * @param s The scope.
2662 */
2663 boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
2664 if (sym.type.isErroneous())
2665 return true;
2666 if (sym.owner.name == names.any) return false;
2667 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
2668 if (sym != e.sym &&
2669 (e.sym.flags() & CLASH) == 0 &&
2670 sym.kind == e.sym.kind &&
2671 sym.name != names.error &&
2672 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
2673 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
2674 varargsDuplicateError(pos, sym, e.sym);
2738 log.error(pos, "already.defined.single.import", what);
2739 }
2740 else if (sym != e.sym)
2741 log.error(pos, "already.defined.this.unit", what);
2742 }
2743 return false;
2744 }
2745 }
2746 return true;
2747 }
2748
2749 /** Check that a qualified name is in canonical form (for import decls).
2750 */
2751 public void checkCanonical(JCTree tree) {
2752 if (!isCanonical(tree))
2753 log.error(tree.pos(), "import.requires.canonical",
2754 TreeInfo.symbol(tree));
2755 }
2756 // where
2757 private boolean isCanonical(JCTree tree) {
2758 while (tree.getTag() == JCTree.Tag.SELECT) {
2759 JCFieldAccess s = (JCFieldAccess) tree;
2760 if (s.sym.owner != TreeInfo.symbol(s.selected))
2761 return false;
2762 tree = s.selected;
2763 }
2764 return true;
2765 }
2766
2767 private class ConversionWarner extends Warner {
2768 final String uncheckedKey;
2769 final Type found;
2770 final Type expected;
2771 public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
2772 super(pos);
2773 this.uncheckedKey = uncheckedKey;
2774 this.found = found;
2775 this.expected = expected;
2776 }
2777
2778 @Override
|