src/share/classes/com/sun/tools/javac/comp/Check.java

changeset 1313
873ddd9f4900
parent 1296
cddc2c894cc6
child 1326
30c36e23f154
equal deleted inserted replaced
1310:542c87b8ce7f 1313:873ddd9f4900
67 private final Symtab syms; 67 private final Symtab syms;
68 private final Enter enter; 68 private final Enter enter;
69 private final Infer infer; 69 private final Infer infer;
70 private final Types types; 70 private final Types types;
71 private final JCDiagnostic.Factory diags; 71 private final JCDiagnostic.Factory diags;
72 private final boolean skipAnnotations;
73 private boolean warnOnSyntheticConflicts; 72 private boolean warnOnSyntheticConflicts;
74 private boolean suppressAbortOnBadClassFile; 73 private boolean suppressAbortOnBadClassFile;
75 private boolean enableSunApiLintControl; 74 private boolean enableSunApiLintControl;
76 private final TreeInfo treeinfo; 75 private final TreeInfo treeinfo;
77 76
111 allowVarargs = source.allowVarargs(); 110 allowVarargs = source.allowVarargs();
112 allowAnnotations = source.allowAnnotations(); 111 allowAnnotations = source.allowAnnotations();
113 allowCovariantReturns = source.allowCovariantReturns(); 112 allowCovariantReturns = source.allowCovariantReturns();
114 allowSimplifiedVarargs = source.allowSimplifiedVarargs(); 113 allowSimplifiedVarargs = source.allowSimplifiedVarargs();
115 complexInference = options.isSet("complexinference"); 114 complexInference = options.isSet("complexinference");
116 skipAnnotations = options.isSet("skipAnnotations");
117 warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); 115 warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
118 suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); 116 suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
119 enableSunApiLintControl = options.isSet("enableSunApiLintControl"); 117 enableSunApiLintControl = options.isSet("enableSunApiLintControl");
120 118
121 Target target = Target.instance(context); 119 Target target = Target.instance(context);
2420 } 2418 }
2421 2419
2422 /** Check the annotations of a symbol. 2420 /** Check the annotations of a symbol.
2423 */ 2421 */
2424 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) { 2422 public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2425 if (skipAnnotations) return;
2426 for (JCAnnotation a : annotations) 2423 for (JCAnnotation a : annotations)
2427 validateAnnotation(a, s); 2424 validateAnnotation(a, s);
2428 } 2425 }
2429 2426
2430 /** Check an annotation of a symbol. 2427 /** Check an annotation of a symbol.
2431 */ 2428 */
2432 public void validateAnnotation(JCAnnotation a, Symbol s) { 2429 private void validateAnnotation(JCAnnotation a, Symbol s) {
2433 validateAnnotationTree(a); 2430 validateAnnotationTree(a);
2434 2431
2435 if (!annotationApplicable(a, s)) 2432 if (!annotationApplicable(a, s))
2436 log.error(a.pos(), "annotation.type.not.applicable"); 2433 log.error(a.pos(), "annotation.type.not.applicable");
2437 2434
2438 if (a.annotationType.type.tsym == syms.overrideType.tsym) { 2435 if (a.annotationType.type.tsym == syms.overrideType.tsym) {
2439 if (!isOverrider(s)) 2436 if (!isOverrider(s))
2440 log.error(a.pos(), "method.does.not.override.superclass"); 2437 log.error(a.pos(), "method.does.not.override.superclass");
2441 } 2438 }
2439 }
2440
2441 /**
2442 * Validate the proposed container 'containedBy' on the
2443 * annotation type symbol 's'. Report errors at position
2444 * 'pos'.
2445 *
2446 * @param s The (annotation)type declaration annotated with a @ContainedBy
2447 * @param containerAnno the @ContainedBy on 's'
2448 * @param pos where to report errors
2449 */
2450 public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
2451 Assert.check(types.isSameType(containedBy.type, syms.containedByType));
2452
2453 Type t = null;
2454 List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
2455 if (!l.isEmpty()) {
2456 Assert.check(l.head.fst.name == names.value);
2457 t = ((Attribute.Class)l.head.snd).getValue();
2458 }
2459
2460 if (t == null) {
2461 log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
2462 return;
2463 }
2464
2465 validateHasContainerFor(t.tsym, s, pos);
2466 validateRetention(t.tsym, s, pos);
2467 validateDocumented(t.tsym, s, pos);
2468 validateInherited(t.tsym, s, pos);
2469 validateTarget(t.tsym, s, pos);
2470 }
2471
2472 /**
2473 * Validate the proposed container 'containerFor' on the
2474 * annotation type symbol 's'. Report errors at position
2475 * 'pos'.
2476 *
2477 * @param s The (annotation)type declaration annotated with a @ContainerFor
2478 * @param containerFor the @ContainedFor on 's'
2479 * @param pos where to report errors
2480 */
2481 public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
2482 Assert.check(types.isSameType(containerFor.type, syms.containerForType));
2483
2484 Type t = null;
2485 List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
2486 if (!l.isEmpty()) {
2487 Assert.check(l.head.fst.name == names.value);
2488 t = ((Attribute.Class)l.head.snd).getValue();
2489 }
2490
2491 if (t == null) {
2492 log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
2493 return;
2494 }
2495
2496 validateHasContainedBy(t.tsym, s, pos);
2497 }
2498
2499 private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2500 Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
2501
2502 if (containedBy == null) {
2503 log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
2504 return;
2505 }
2506
2507 Type t = null;
2508 List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
2509 if (!l.isEmpty()) {
2510 Assert.check(l.head.fst.name == names.value);
2511 t = ((Attribute.Class)l.head.snd).getValue();
2512 }
2513
2514 if (t == null) {
2515 log.error(pos, "invalid.container.wrong.containedby", container, contained);
2516 return;
2517 }
2518
2519 if (!types.isSameType(t, contained.type))
2520 log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
2521 }
2522
2523 private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2524 Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
2525
2526 if (containerFor == null) {
2527 log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
2528 return;
2529 }
2530
2531 Type t = null;
2532 List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
2533 if (!l.isEmpty()) {
2534 Assert.check(l.head.fst.name == names.value);
2535 t = ((Attribute.Class)l.head.snd).getValue();
2536 }
2537
2538 if (t == null) {
2539 log.error(pos, "invalid.container.wrong.containerfor", container, contained);
2540 return;
2541 }
2542
2543 if (!types.isSameType(t, contained.type))
2544 log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
2545 }
2546
2547 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
2548 Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2549 Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2550
2551 boolean error = false;
2552 switch (containedRetention) {
2553 case RUNTIME:
2554 if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2555 error = true;
2556 }
2557 break;
2558 case CLASS:
2559 if (containerRetention == Attribute.RetentionPolicy.SOURCE) {
2560 error = true;
2561 }
2562 }
2563 if (error ) {
2564 log.error(pos, "invalid.containedby.annotation.retention",
2565 container, containerRetention,
2566 contained, containedRetention);
2567 }
2568 }
2569
2570 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2571 if (contained.attribute(syms.documentedType.tsym) != null) {
2572 if (container.attribute(syms.documentedType.tsym) == null) {
2573 log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
2574 }
2575 }
2576 }
2577
2578 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2579 if (contained.attribute(syms.inheritedType.tsym) != null) {
2580 if (container.attribute(syms.inheritedType.tsym) == null) {
2581 log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
2582 }
2583 }
2584 }
2585
2586 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
2587 Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2588
2589 // If contained has no Target, we are done
2590 if (containedTarget == null) {
2591 return;
2592 }
2593
2594 // If contained has Target m1, container must have a Target
2595 // annotation, m2, and m2 must be a subset of m1. (This is
2596 // trivially true if contained has no target as per above).
2597
2598 // contained has target, but container has not, error
2599 Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2600 if (containerTarget == null) {
2601 log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
2602 return;
2603 }
2604
2605 Set<Name> containerTargets = new HashSet<Name>();
2606 for (Attribute app : containerTarget.values) {
2607 if (!(app instanceof Attribute.Enum)) {
2608 continue; // recovery
2609 }
2610 Attribute.Enum e = (Attribute.Enum)app;
2611 containerTargets.add(e.value.name);
2612 }
2613
2614 Set<Name> containedTargets = new HashSet<Name>();
2615 for (Attribute app : containedTarget.values) {
2616 if (!(app instanceof Attribute.Enum)) {
2617 continue; // recovery
2618 }
2619 Attribute.Enum e = (Attribute.Enum)app;
2620 containedTargets.add(e.value.name);
2621 }
2622
2623 if (!isTargetSubset(containedTargets, containerTargets)) {
2624 log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
2625 }
2626 }
2627
2628 /** Checks that t is a subset of s, with respect to ElementType
2629 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
2630 */
2631 private boolean isTargetSubset(Set<Name> s, Set<Name> t) {
2632 // Check that all elements in t are present in s
2633 for (Name n2 : t) {
2634 boolean currentElementOk = false;
2635 for (Name n1 : s) {
2636 if (n1 == n2) {
2637 currentElementOk = true;
2638 break;
2639 } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
2640 currentElementOk = true;
2641 break;
2642 }
2643 }
2644 if (!currentElementOk)
2645 return false;
2646 }
2647 return true;
2442 } 2648 }
2443 2649
2444 /** Is s a method symbol that overrides a method in a superclass? */ 2650 /** Is s a method symbol that overrides a method in a superclass? */
2445 boolean isOverrider(Symbol s) { 2651 boolean isOverrider(Symbol s) {
2446 if (s.kind != MTH || s.isStatic()) 2652 if (s.kind != MTH || s.isStatic())
2459 return false; 2665 return false;
2460 } 2666 }
2461 2667
2462 /** Is the annotation applicable to the symbol? */ 2668 /** Is the annotation applicable to the symbol? */
2463 boolean annotationApplicable(JCAnnotation a, Symbol s) { 2669 boolean annotationApplicable(JCAnnotation a, Symbol s) {
2464 Attribute.Compound atTarget = 2670 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
2465 a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); 2671 if (arr == null) {
2466 if (atTarget == null) return true; 2672 return true;
2467 Attribute atValue = atTarget.member(names.value); 2673 }
2468 if (!(atValue instanceof Attribute.Array)) return true; // error recovery
2469 Attribute.Array arr = (Attribute.Array) atValue;
2470 for (Attribute app : arr.values) { 2674 for (Attribute app : arr.values) {
2471 if (!(app instanceof Attribute.Enum)) return true; // recovery 2675 if (!(app instanceof Attribute.Enum)) return true; // recovery
2472 Attribute.Enum e = (Attribute.Enum) app; 2676 Attribute.Enum e = (Attribute.Enum) app;
2473 if (e.value.name == names.TYPE) 2677 if (e.value.name == names.TYPE)
2474 { if (s.kind == TYP) return true; } 2678 { if (s.kind == TYP) return true; }
2504 } 2708 }
2505 else 2709 else
2506 return true; // recovery 2710 return true; // recovery
2507 } 2711 }
2508 return false; 2712 return false;
2713 }
2714
2715
2716 Attribute.Array getAttributeTargetAttribute(Symbol s) {
2717 Attribute.Compound atTarget =
2718 s.attribute(syms.annotationTargetType.tsym);
2719 if (atTarget == null) return null; // ok, is applicable
2720 Attribute atValue = atTarget.member(names.value);
2721 if (!(atValue instanceof Attribute.Array)) return null; // error recovery
2722 return (Attribute.Array) atValue;
2509 } 2723 }
2510 2724
2511 /** Check an annotation value. 2725 /** Check an annotation value.
2512 */ 2726 */
2513 public void validateAnnotation(JCAnnotation a) { 2727 public void validateAnnotation(JCAnnotation a) {

mercurial