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

changeset 1492
df694c775e8a
parent 1464
f72c9c5aeaef
child 1521
71f35e4b93a5
equal deleted inserted replaced
1491:9f42a06a49c0 1492:df694c775e8a
1 /* 1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this 7 * published by the Free Software Foundation. Oracle designates this
390 new Attribute.Array(arrayOfOrigAnnoType, repeated)); 390 new Attribute.Array(arrayOfOrigAnnoType, repeated));
391 annoTree = m.Annotation(new Attribute.Compound(targetContainerType, 391 annoTree = m.Annotation(new Attribute.Compound(targetContainerType,
392 List.of(p))); 392 List.of(p)));
393 393
394 if (!chk.annotationApplicable(annoTree, on)) 394 if (!chk.annotationApplicable(annoTree, on))
395 log.error(annoTree.pos(), "invalid.containedby.annotation.incompatible.target", targetContainerType, origAnnoType); 395 log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
396 396
397 if (!chk.validateAnnotationDeferErrors(annoTree)) 397 if (!chk.validateAnnotationDeferErrors(annoTree))
398 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); 398 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
399 399
400 Attribute.Compound c = enterAnnotation(annoTree, 400 Attribute.Compound c = enterAnnotation(annoTree,
412 DiagnosticPosition pos) 412 DiagnosticPosition pos)
413 { 413 {
414 Type origAnnoType = currentAnno.type; 414 Type origAnnoType = currentAnno.type;
415 TypeSymbol origAnnoDecl = origAnnoType.tsym; 415 TypeSymbol origAnnoDecl = origAnnoType.tsym;
416 416
417 // Fetch the ContainedBy annotation from the current 417 // Fetch the Repeatable annotation from the current
418 // annotation's declaration, or null if it has none 418 // annotation's declaration, or null if it has none
419 Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym); 419 Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
420 if (ca == null) { // has no ContainedBy annotation 420 if (ca == null) { // has no Repeatable annotation
421 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType); 421 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
422 return null; 422 return null;
423 } 423 }
424 424
425 return filterSame(extractContainingType(ca, pos, origAnnoDecl), 425 return filterSame(extractContainingType(ca, pos, origAnnoDecl),
426 origAnnoType); 426 origAnnoType);
438 /** Extract the actual Type to be used for a containing annotation. */ 438 /** Extract the actual Type to be used for a containing annotation. */
439 private Type extractContainingType(Attribute.Compound ca, 439 private Type extractContainingType(Attribute.Compound ca,
440 DiagnosticPosition pos, 440 DiagnosticPosition pos,
441 TypeSymbol annoDecl) 441 TypeSymbol annoDecl)
442 { 442 {
443 // The next three checks check that the ContainedBy annotation 443 // The next three checks check that the Repeatable annotation
444 // on the declaration of the annotation type that is repeating is 444 // on the declaration of the annotation type that is repeating is
445 // valid. 445 // valid.
446 446
447 // ContainedBy must have at least one element 447 // Repeatable must have at least one element
448 if (ca.values.isEmpty()) { 448 if (ca.values.isEmpty()) {
449 log.error(pos, "invalid.containedby.annotation", annoDecl); 449 log.error(pos, "invalid.repeatable.annotation", annoDecl);
450 return null; 450 return null;
451 } 451 }
452 Pair<MethodSymbol,Attribute> p = ca.values.head; 452 Pair<MethodSymbol,Attribute> p = ca.values.head;
453 Name name = p.fst.name; 453 Name name = p.fst.name;
454 if (name != names.value) { // should contain only one element, named "value" 454 if (name != names.value) { // should contain only one element, named "value"
455 log.error(pos, "invalid.containedby.annotation", annoDecl); 455 log.error(pos, "invalid.repeatable.annotation", annoDecl);
456 return null; 456 return null;
457 } 457 }
458 if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class 458 if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
459 log.error(pos, "invalid.containedby.annotation", annoDecl); 459 log.error(pos, "invalid.repeatable.annotation", annoDecl);
460 return null; 460 return null;
461 } 461 }
462 462
463 return ((Attribute.Class)p.snd).getValue(); 463 return ((Attribute.Class)p.snd).getValue();
464 } 464 }
489 error = true; 489 error = true;
490 } 490 }
491 } 491 }
492 if (error) { 492 if (error) {
493 log.error(pos, 493 log.error(pos,
494 "invalid.containedby.annotation.multiple.values", 494 "invalid.repeatable.annotation.multiple.values",
495 targetContainerType, 495 targetContainerType,
496 nr_value_elems); 496 nr_value_elems);
497 return null; 497 return null;
498 } else if (nr_value_elems == 0) { 498 } else if (nr_value_elems == 0) {
499 log.error(pos, 499 log.error(pos,
500 "invalid.containedby.annotation.no.value", 500 "invalid.repeatable.annotation.no.value",
501 targetContainerType); 501 targetContainerType);
502 return null; 502 return null;
503 } 503 }
504 504
505 // validate that the 'value' element is a method 505 // validate that the 'value' element is a method
506 // probably "impossible" to fail this 506 // probably "impossible" to fail this
507 if (containerValueSymbol.kind != Kinds.MTH) { 507 if (containerValueSymbol.kind != Kinds.MTH) {
508 log.error(pos, 508 log.error(pos,
509 "invalid.containedby.annotation.invalid.value", 509 "invalid.repeatable.annotation.invalid.value",
510 targetContainerType); 510 targetContainerType);
511 fatalError = true; 511 fatalError = true;
512 } 512 }
513 513
514 // validate that the 'value' element has the correct return type 514 // validate that the 'value' element has the correct return type
516 Type valueRetType = containerValueSymbol.type.getReturnType(); 516 Type valueRetType = containerValueSymbol.type.getReturnType();
517 Type expectedType = types.makeArrayType(originalAnnoType); 517 Type expectedType = types.makeArrayType(originalAnnoType);
518 if (!(types.isArray(valueRetType) && 518 if (!(types.isArray(valueRetType) &&
519 types.isSameType(expectedType, valueRetType))) { 519 types.isSameType(expectedType, valueRetType))) {
520 log.error(pos, 520 log.error(pos,
521 "invalid.containedby.annotation.value.return", 521 "invalid.repeatable.annotation.value.return",
522 targetContainerType, 522 targetContainerType,
523 valueRetType, 523 valueRetType,
524 expectedType); 524 expectedType);
525 fatalError = true; 525 fatalError = true;
526 } 526 }
527 if (error) { 527 if (error) {
528 fatalError = true; 528 fatalError = true;
529 } 529 }
530 530
531 // Explicitly no check for/validity of @ContainerFor. That is 531 // The conditions for a valid containing annotation are made
532 // done on declaration of the container, and at reflect time.
533
534 // The rest of the conditions for a valid containing annotation are made
535 // in Check.validateRepeatedAnnotaton(); 532 // in Check.validateRepeatedAnnotaton();
536 533
537 return fatalError ? null : containerValueSymbol; 534 return fatalError ? null : containerValueSymbol;
538 } 535 }
539 } 536 }

mercurial