25
26 package com.sun.tools.javac.comp;
27
28 import java.util.*;
29 import java.util.Set;
30
31 import com.sun.tools.javac.code.*;
32 import com.sun.tools.javac.jvm.*;
33 import com.sun.tools.javac.tree.*;
34 import com.sun.tools.javac.util.*;
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
36 import com.sun.tools.javac.util.List;
37
38 import com.sun.tools.javac.tree.JCTree.*;
39 import com.sun.tools.javac.code.Lint;
40 import com.sun.tools.javac.code.Lint.LintCategory;
41 import com.sun.tools.javac.code.Type.*;
42 import com.sun.tools.javac.code.Symbol.*;
43
44 import static com.sun.tools.javac.code.Flags.*;
45 import static com.sun.tools.javac.code.Kinds.*;
46 import static com.sun.tools.javac.code.TypeTags.*;
47
48 import static com.sun.tools.javac.main.OptionName.*;
49
50 /** Type checking helper class for the attribution phase.
51 *
52 * <p><b>This is NOT part of any supported API.
53 * If you write code that depends on this, you do so at your own risk.
54 * This code and its internal interfaces are subject to change or
55 * deletion without notice.</b>
56 */
57 public class Check {
58 protected static final Context.Key<Check> checkKey =
59 new Context.Key<Check>();
60
61 private final Names names;
62 private final Log log;
63 private final Symtab syms;
64 private final Enter enter;
65 private final Infer infer;
66 private final Types types;
67 private final JCDiagnostic.Factory diags;
68 private final boolean skipAnnotations;
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
|
25
26 package com.sun.tools.javac.comp;
27
28 import java.util.*;
29 import java.util.Set;
30
31 import com.sun.tools.javac.code.*;
32 import com.sun.tools.javac.jvm.*;
33 import com.sun.tools.javac.tree.*;
34 import com.sun.tools.javac.util.*;
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
36 import com.sun.tools.javac.util.List;
37
38 import com.sun.tools.javac.tree.JCTree.*;
39 import com.sun.tools.javac.code.Lint;
40 import com.sun.tools.javac.code.Lint.LintCategory;
41 import com.sun.tools.javac.code.Type.*;
42 import com.sun.tools.javac.code.Symbol.*;
43
44 import static com.sun.tools.javac.code.Flags.*;
45 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
46 import static com.sun.tools.javac.code.Flags.ANNOTATION;
47 import static com.sun.tools.javac.code.Kinds.*;
48 import static com.sun.tools.javac.code.TypeTags.*;
49 import static com.sun.tools.javac.code.TypeTags.WILDCARD;
50
51 import static com.sun.tools.javac.main.OptionName.*;
52 import static com.sun.tools.javac.tree.JCTree.Tag.*;
53
54 /** Type checking helper class for the attribution phase.
55 *
56 * <p><b>This is NOT part of any supported API.
57 * If you write code that depends on this, you do so at your own risk.
58 * This code and its internal interfaces are subject to change or
59 * deletion without notice.</b>
60 */
61 public class Check {
62 protected static final Context.Key<Check> checkKey =
63 new Context.Key<Check>();
64
65 private final Names names;
66 private final Log log;
67 private final Symtab syms;
68 private final Enter enter;
69 private final Infer infer;
70 private final Types types;
71 private final JCDiagnostic.Factory diags;
72 private final boolean skipAnnotations;
974 VOLATILE)
975 &&
976 (sym.kind == TYP ||
977 checkDisjoint(pos, flags,
978 ABSTRACT | NATIVE,
979 STRICTFP))) {
980 // skip
981 }
982 return flags & (mask | ~StandardFlags) | implicit;
983 }
984
985
986 /** Determine if this enum should be implicitly final.
987 *
988 * If the enum has no specialized enum contants, it is final.
989 *
990 * If the enum does have specialized enum contants, it is
991 * <i>not</i> final.
992 */
993 private long implicitEnumFinalFlag(JCTree tree) {
994 if (!tree.hasTag(CLASSDEF)) return 0;
995 class SpecialTreeVisitor extends JCTree.Visitor {
996 boolean specialized;
997 SpecialTreeVisitor() {
998 this.specialized = false;
999 };
1000
1001 @Override
1002 public void visitTree(JCTree tree) { /* no-op */ }
1003
1004 @Override
1005 public void visitVarDef(JCVariableDecl tree) {
1006 if ((tree.mods.flags & ENUM) != 0) {
1007 if (tree.init instanceof JCNewClass &&
1008 ((JCNewClass) tree.init).def != null) {
1009 specialized = true;
1010 }
1011 }
1012 }
1013 }
1014
1086 }
1087
1088 forms = tree.type.tsym.type.getTypeArguments();
1089
1090 boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
1091
1092 // For matching pairs of actual argument types `a' and
1093 // formal type parameters with declared bound `b' ...
1094 while (args.nonEmpty() && forms.nonEmpty()) {
1095 validateTree(args.head,
1096 !(isOuter && is_java_lang_Class),
1097 false);
1098 args = args.tail;
1099 forms = forms.tail;
1100 }
1101
1102 // Check that this type is either fully parameterized, or
1103 // not parameterized at all.
1104 if (tree.type.getEnclosingType().isRaw())
1105 log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
1106 if (tree.clazz.hasTag(SELECT))
1107 visitSelectInternal((JCFieldAccess)tree.clazz);
1108 }
1109 }
1110
1111 @Override
1112 public void visitTypeParameter(JCTypeParameter tree) {
1113 validateTrees(tree.bounds, true, isOuter);
1114 checkClassBounds(tree.pos(), tree.type);
1115 }
1116
1117 @Override
1118 public void visitWildcard(JCWildcard tree) {
1119 if (tree.inner != null)
1120 validateTree(tree.inner, true, isOuter);
1121 }
1122
1123 @Override
1124 public void visitSelect(JCFieldAccess tree) {
1125 if (tree.type.tag == CLASS) {
1126 visitSelectInternal(tree);
2400 return false;
2401 }
2402
2403 /** Check an annotation value.
2404 */
2405 public void validateAnnotation(JCAnnotation a) {
2406 // collect an inventory of the members (sorted alphabetically)
2407 Set<MethodSymbol> members = new TreeSet<MethodSymbol>(new Comparator<Symbol>() {
2408 public int compare(Symbol t, Symbol t1) {
2409 return t.name.compareTo(t1.name);
2410 }
2411 });
2412 for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
2413 e != null;
2414 e = e.sibling)
2415 if (e.sym.kind == MTH)
2416 members.add((MethodSymbol) e.sym);
2417
2418 // count them off as they're annotated
2419 for (JCTree arg : a.args) {
2420 if (!arg.hasTag(ASSIGN)) continue; // recovery
2421 JCAssign assign = (JCAssign) arg;
2422 Symbol m = TreeInfo.symbol(assign.lhs);
2423 if (m == null || m.type.isErroneous()) continue;
2424 if (!members.remove(m))
2425 log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
2426 m.name, a.type);
2427 }
2428
2429 // all the remaining ones better have default values
2430 ListBuffer<Name> missingDefaults = ListBuffer.lb();
2431 for (MethodSymbol m : members) {
2432 if (m.defaultValue == null && !m.type.isErroneous()) {
2433 missingDefaults.append(m.name);
2434 }
2435 }
2436 if (missingDefaults.nonEmpty()) {
2437 String key = (missingDefaults.size() > 1)
2438 ? "annotation.missing.default.value.1"
2439 : "annotation.missing.default.value";
2440 log.error(a.pos(), key, a.type, missingDefaults);
2441 }
2442
2443 // special case: java.lang.annotation.Target must not have
2444 // repeated values in its value member
2445 if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
2446 a.args.tail == null)
2447 return;
2448
2449 if (!a.args.head.hasTag(ASSIGN)) return; // error recovery
2450 JCAssign assign = (JCAssign) a.args.head;
2451 Symbol m = TreeInfo.symbol(assign.lhs);
2452 if (m.name != names.value) return;
2453 JCTree rhs = assign.rhs;
2454 if (!rhs.hasTag(NEWARRAY)) return;
2455 JCNewArray na = (JCNewArray) rhs;
2456 Set<Symbol> targets = new HashSet<Symbol>();
2457 for (JCTree elem : na.elems) {
2458 if (!targets.add(TreeInfo.symbol(elem))) {
2459 log.error(elem.pos(), "repeated.annotation.target");
2460 }
2461 }
2462 }
2463
2464 void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
2465 if (allowAnnotations &&
2466 lint.isEnabled(LintCategory.DEP_ANN) &&
2467 (s.flags() & DEPRECATED) != 0 &&
2468 !syms.deprecatedType.isErroneous() &&
2469 s.attribute(syms.deprecatedType.tsym) == null) {
2470 log.warning(LintCategory.DEP_ANN,
2471 pos, "missing.deprecated.annotation");
2472 }
2473 }
2474
2493 warnSunApi(pos, "sun.proprietary", s);
2494 else
2495 log.strictWarning(pos, "sun.proprietary", s);
2496 }
2497 });
2498 }
2499 }
2500
2501 /* *************************************************************************
2502 * Check for recursive annotation elements.
2503 **************************************************************************/
2504
2505 /** Check for cycles in the graph of annotation elements.
2506 */
2507 void checkNonCyclicElements(JCClassDecl tree) {
2508 if ((tree.sym.flags_field & ANNOTATION) == 0) return;
2509 Assert.check((tree.sym.flags_field & LOCKED) == 0);
2510 try {
2511 tree.sym.flags_field |= LOCKED;
2512 for (JCTree def : tree.defs) {
2513 if (!def.hasTag(METHODDEF)) continue;
2514 JCMethodDecl meth = (JCMethodDecl)def;
2515 checkAnnotationResType(meth.pos(), meth.restype.type);
2516 }
2517 } finally {
2518 tree.sym.flags_field &= ~LOCKED;
2519 tree.sym.flags_field |= ACYCLIC_ANN;
2520 }
2521 }
2522
2523 void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
2524 if ((tsym.flags_field & ACYCLIC_ANN) != 0)
2525 return;
2526 if ((tsym.flags_field & LOCKED) != 0) {
2527 log.error(pos, "cyclic.annotation.element");
2528 return;
2529 }
2530 try {
2531 tsym.flags_field |= LOCKED;
2532 for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
2533 Symbol s = e.sym;
2601 }
2602 ctor.flags_field |= ACYCLIC;
2603 }
2604 }
2605
2606 /* *************************************************************************
2607 * Miscellaneous
2608 **************************************************************************/
2609
2610 /**
2611 * Return the opcode of the operator but emit an error if it is an
2612 * error.
2613 * @param pos position for error reporting.
2614 * @param operator an operator
2615 * @param tag a tree tag
2616 * @param left type of left hand side
2617 * @param right type of right hand side
2618 */
2619 int checkOperator(DiagnosticPosition pos,
2620 OperatorSymbol operator,
2621 JCTree.Tag tag,
2622 Type left,
2623 Type right) {
2624 if (operator.opcode == ByteCodes.error) {
2625 log.error(pos,
2626 "operator.cant.be.applied.1",
2627 treeinfo.operatorName(tag),
2628 left, right);
2629 }
2630 return operator.opcode;
2631 }
2632
2633
2634 /**
2635 * Check for division by integer constant zero
2636 * @param pos Position for error reporting.
2637 * @param operator The operator for the expression
2638 * @param operand The right hand operand for the expression
2639 */
2640 void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
2641 if (operand.constValue() != null
2642 && lint.isEnabled(LintCategory.DIVZERO)
2643 && operand.tag <= LONG
2644 && ((Number) (operand.constValue())).longValue() == 0) {
2645 int opc = ((OperatorSymbol)operator).opcode;
2646 if (opc == ByteCodes.idiv || opc == ByteCodes.imod
2647 || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
2648 log.warning(LintCategory.DIVZERO, pos, "div.zero");
2649 }
2650 }
2651 }
2652
2653 /**
2654 * Check for empty statements after if
2655 */
2656 void checkEmptyIf(JCIf tree) {
2657 if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
2658 lint.isEnabled(LintCategory.EMPTY))
2659 log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
2660 }
2661
2662 /** Check that symbol is unique in given scope.
2663 * @param pos Position for error reporting.
2664 * @param sym The symbol.
2665 * @param s The scope.
2666 */
2667 boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
2668 if (sym.type.isErroneous())
2669 return true;
2670 if (sym.owner.name == names.any) return false;
2671 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
2672 if (sym != e.sym &&
2673 (e.sym.flags() & CLASH) == 0 &&
2674 sym.kind == e.sym.kind &&
2675 sym.name != names.error &&
2676 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
2677 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
2678 varargsDuplicateError(pos, sym, e.sym);
2742 log.error(pos, "already.defined.single.import", what);
2743 }
2744 else if (sym != e.sym)
2745 log.error(pos, "already.defined.this.unit", what);
2746 }
2747 return false;
2748 }
2749 }
2750 return true;
2751 }
2752
2753 /** Check that a qualified name is in canonical form (for import decls).
2754 */
2755 public void checkCanonical(JCTree tree) {
2756 if (!isCanonical(tree))
2757 log.error(tree.pos(), "import.requires.canonical",
2758 TreeInfo.symbol(tree));
2759 }
2760 // where
2761 private boolean isCanonical(JCTree tree) {
2762 while (tree.hasTag(SELECT)) {
2763 JCFieldAccess s = (JCFieldAccess) tree;
2764 if (s.sym.owner != TreeInfo.symbol(s.selected))
2765 return false;
2766 tree = s.selected;
2767 }
2768 return true;
2769 }
2770
2771 private class ConversionWarner extends Warner {
2772 final String uncheckedKey;
2773 final Type found;
2774 final Type expected;
2775 public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
2776 super(pos);
2777 this.uncheckedKey = uncheckedKey;
2778 this.found = found;
2779 this.expected = expected;
2780 }
2781
2782 @Override
|