252 ? deferredLintHandler.setPos(deferPos) |
252 ? deferredLintHandler.setPos(deferPos) |
253 : deferredLintHandler.immediate(); |
253 : deferredLintHandler.immediate(); |
254 Lint prevLint = deferPos != null ? null : chk.setLint(lint); |
254 Lint prevLint = deferPos != null ? null : chk.setLint(lint); |
255 try { |
255 try { |
256 if (s.hasAnnotations() && annotations.nonEmpty()) |
256 if (s.hasAnnotations() && annotations.nonEmpty()) |
257 log.error(annotations.head.pos, "already.annotated", Kinds.kindName(s), s); |
257 log.error(annotations.head.pos, Errors.AlreadyAnnotated(Kinds.kindName(s), s)); |
258 |
258 |
259 Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null"); |
259 Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null"); |
260 |
260 |
261 // false is passed as fifth parameter since annotateLater is |
261 // false is passed as fifth parameter since annotateLater is |
262 // never called for a type parameter |
262 // never called for a type parameter |
340 |
340 |
341 Assert.checkNonNull(c, "Failed to create annotation"); |
341 Assert.checkNonNull(c, "Failed to create annotation"); |
342 |
342 |
343 if (annotated.containsKey(a.type.tsym)) { |
343 if (annotated.containsKey(a.type.tsym)) { |
344 if (!allowRepeatedAnnos) { |
344 if (!allowRepeatedAnnos) { |
345 log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), "repeatable.annotations.not.supported.in.source", sourceName); |
345 log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Errors.RepeatableAnnotationsNotSupportedInSource(sourceName)); |
346 } |
346 } |
347 ListBuffer<T> l = annotated.get(a.type.tsym); |
347 ListBuffer<T> l = annotated.get(a.type.tsym); |
348 l = l.append(c); |
348 l = l.append(c); |
349 annotated.put(a.type.tsym, l); |
349 annotated.put(a.type.tsym, l); |
350 pos.put(c, a.pos()); |
350 pos.put(c, a.pos()); |
454 a.annotationType.type : attr.attribType(a.annotationType, env)); |
454 a.annotationType.type : attr.attribType(a.annotationType, env)); |
455 a.type = chk.checkType(a.annotationType.pos(), at, expected); |
455 a.type = chk.checkType(a.annotationType.pos(), at, expected); |
456 |
456 |
457 boolean isError = a.type.isErroneous(); |
457 boolean isError = a.type.isErroneous(); |
458 if (!a.type.tsym.isAnnotationType() && !isError) { |
458 if (!a.type.tsym.isAnnotationType() && !isError) { |
459 log.error(a.annotationType.pos(), |
459 log.error(a.annotationType.pos(), Errors.NotAnnotationType(a.type)); |
460 "not.annotation.type", a.type.toString()); |
|
461 isError = true; |
460 isError = true; |
462 } |
461 } |
463 |
462 |
464 // List of name=value pairs (or implicit "value=" if size 1) |
463 // List of name=value pairs (or implicit "value=" if size 1) |
465 List<JCExpression> args = a.args; |
464 List<JCExpression> args = a.args; |
484 // where |
483 // where |
485 private Pair<MethodSymbol, Attribute> attributeAnnotationNameValuePair(JCExpression nameValuePair, |
484 private Pair<MethodSymbol, Attribute> attributeAnnotationNameValuePair(JCExpression nameValuePair, |
486 Type thisAnnotationType, boolean badAnnotation, Env<AttrContext> env, boolean elidedValue) |
485 Type thisAnnotationType, boolean badAnnotation, Env<AttrContext> env, boolean elidedValue) |
487 { |
486 { |
488 if (!nameValuePair.hasTag(ASSIGN)) { |
487 if (!nameValuePair.hasTag(ASSIGN)) { |
489 log.error(nameValuePair.pos(), "annotation.value.must.be.name.value"); |
488 log.error(nameValuePair.pos(), Errors.AnnotationValueMustBeNameValue); |
490 attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env); |
489 attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env); |
491 return null; |
490 return null; |
492 } |
491 } |
493 JCAssign assign = (JCAssign)nameValuePair; |
492 JCAssign assign = (JCAssign)nameValuePair; |
494 if (!assign.lhs.hasTag(IDENT)) { |
493 if (!assign.lhs.hasTag(IDENT)) { |
495 log.error(nameValuePair.pos(), "annotation.value.must.be.name.value"); |
494 log.error(nameValuePair.pos(), Errors.AnnotationValueMustBeNameValue); |
496 attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env); |
495 attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env); |
497 return null; |
496 return null; |
498 } |
497 } |
499 |
498 |
500 // Resolve element to MethodSym |
499 // Resolve element to MethodSym |
503 env, thisAnnotationType, |
502 env, thisAnnotationType, |
504 left.name, List.nil(), null); |
503 left.name, List.nil(), null); |
505 left.sym = method; |
504 left.sym = method; |
506 left.type = method.type; |
505 left.type = method.type; |
507 if (method.owner != thisAnnotationType.tsym && !badAnnotation) |
506 if (method.owner != thisAnnotationType.tsym && !badAnnotation) |
508 log.error(left.pos(), "no.annotation.member", left.name, thisAnnotationType); |
507 log.error(left.pos(), Errors.NoAnnotationMember(left.name, thisAnnotationType)); |
509 Type resultType = method.type.getReturnType(); |
508 Type resultType = method.type.getReturnType(); |
510 |
509 |
511 // Compute value part |
510 // Compute value part |
512 Attribute value = attributeAnnotationValue(resultType, assign.rhs, env); |
511 Attribute value = attributeAnnotationValue(resultType, assign.rhs, env); |
513 nameValuePair.type = resultType; |
512 nameValuePair.type = resultType; |
524 //error is thrown, we should recover gracefully, and display an |
523 //error is thrown, we should recover gracefully, and display an |
525 //ordinary resolution diagnostic. |
524 //ordinary resolution diagnostic. |
526 try { |
525 try { |
527 expectedElementType.tsym.complete(); |
526 expectedElementType.tsym.complete(); |
528 } catch(CompletionFailure e) { |
527 } catch(CompletionFailure e) { |
529 log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym); |
528 log.error(tree.pos(), Errors.CantResolve(Kinds.kindName(e.sym), e.sym.getQualifiedName(), null, null)); |
530 expectedElementType = syms.errType; |
529 expectedElementType = syms.errType; |
531 } |
530 } |
532 |
531 |
533 if (expectedElementType.hasTag(ARRAY)) { |
532 if (expectedElementType.hasTag(ARRAY)) { |
534 return getAnnotationArrayValue(expectedElementType, tree, env); |
533 return getAnnotationArrayValue(expectedElementType, tree, env); |
536 } |
535 } |
537 |
536 |
538 //error recovery |
537 //error recovery |
539 if (tree.hasTag(NEWARRAY)) { |
538 if (tree.hasTag(NEWARRAY)) { |
540 if (!expectedElementType.isErroneous()) |
539 if (!expectedElementType.isErroneous()) |
541 log.error(tree.pos(), "annotation.value.not.allowable.type"); |
540 log.error(tree.pos(), Errors.AnnotationValueNotAllowableType); |
542 JCNewArray na = (JCNewArray)tree; |
541 JCNewArray na = (JCNewArray)tree; |
543 if (na.elemtype != null) { |
542 if (na.elemtype != null) { |
544 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); |
543 log.error(na.elemtype.pos(), Errors.NewNotAllowedInAnnotation); |
545 } |
544 } |
546 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { |
545 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { |
547 attributeAnnotationValue(syms.errType, |
546 attributeAnnotationValue(syms.errType, |
548 l.head, |
547 l.head, |
549 env); |
548 env); |
553 |
552 |
554 if (expectedElementType.tsym.isAnnotationType()) { |
553 if (expectedElementType.tsym.isAnnotationType()) { |
555 if (tree.hasTag(ANNOTATION)) { |
554 if (tree.hasTag(ANNOTATION)) { |
556 return attributeAnnotation((JCAnnotation)tree, expectedElementType, env); |
555 return attributeAnnotation((JCAnnotation)tree, expectedElementType, env); |
557 } else { |
556 } else { |
558 log.error(tree.pos(), "annotation.value.must.be.annotation"); |
557 log.error(tree.pos(), Errors.AnnotationValueMustBeAnnotation); |
559 expectedElementType = syms.errType; |
558 expectedElementType = syms.errType; |
560 } |
559 } |
561 } |
560 } |
562 |
561 |
563 //error recovery |
562 //error recovery |
564 if (tree.hasTag(ANNOTATION)) { |
563 if (tree.hasTag(ANNOTATION)) { |
565 if (!expectedElementType.isErroneous()) |
564 if (!expectedElementType.isErroneous()) |
566 log.error(tree.pos(), "annotation.not.valid.for.type", expectedElementType); |
565 log.error(tree.pos(), Errors.AnnotationNotValidForType(expectedElementType)); |
567 attributeAnnotation((JCAnnotation)tree, syms.errType, env); |
566 attributeAnnotation((JCAnnotation)tree, syms.errType, env); |
568 return new Attribute.Error(((JCAnnotation)tree).annotationType.type); |
567 return new Attribute.Error(((JCAnnotation)tree).annotationType.type); |
569 } |
568 } |
570 |
569 |
571 MemberEnter.InitTreeVisitor initTreeVisitor = new MemberEnter.InitTreeVisitor() { |
570 MemberEnter.InitTreeVisitor initTreeVisitor = new MemberEnter.InitTreeVisitor() { |
596 return getAnnotationEnumValue(expectedElementType, tree, env); |
595 return getAnnotationEnumValue(expectedElementType, tree, env); |
597 } |
596 } |
598 |
597 |
599 //error recovery: |
598 //error recovery: |
600 if (!expectedElementType.isErroneous()) |
599 if (!expectedElementType.isErroneous()) |
601 log.error(tree.pos(), "annotation.value.not.allowable.type"); |
600 log.error(tree.pos(), Errors.AnnotationValueNotAllowableType); |
602 return new Attribute.Error(attr.attribExpr(tree, env, expectedElementType)); |
601 return new Attribute.Error(attr.attribExpr(tree, env, expectedElementType)); |
603 } |
602 } |
604 |
603 |
605 private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) { |
604 private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) { |
606 Type result = attr.attribExpr(tree, env, expectedElementType); |
605 Type result = attr.attribExpr(tree, env, expectedElementType); |
607 Symbol sym = TreeInfo.symbol(tree); |
606 Symbol sym = TreeInfo.symbol(tree); |
608 if (sym == null || |
607 if (sym == null || |
609 TreeInfo.nonstaticSelect(tree) || |
608 TreeInfo.nonstaticSelect(tree) || |
610 sym.kind != VAR || |
609 sym.kind != VAR || |
611 (sym.flags() & Flags.ENUM) == 0) { |
610 (sym.flags() & Flags.ENUM) == 0) { |
612 log.error(tree.pos(), "enum.annotation.must.be.enum.constant"); |
611 log.error(tree.pos(), Errors.EnumAnnotationMustBeEnumConstant); |
613 return new Attribute.Error(result.getOriginalType()); |
612 return new Attribute.Error(result.getOriginalType()); |
614 } |
613 } |
615 VarSymbol enumerator = (VarSymbol) sym; |
614 VarSymbol enumerator = (VarSymbol) sym; |
616 return new Attribute.Enum(expectedElementType, enumerator); |
615 return new Attribute.Enum(expectedElementType, enumerator); |
617 } |
616 } |
638 private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) { |
637 private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) { |
639 Type result = attr.attribExpr(tree, env, expectedElementType); |
638 Type result = attr.attribExpr(tree, env, expectedElementType); |
640 if (result.isErroneous()) |
639 if (result.isErroneous()) |
641 return new Attribute.Error(result.getOriginalType()); |
640 return new Attribute.Error(result.getOriginalType()); |
642 if (result.constValue() == null) { |
641 if (result.constValue() == null) { |
643 log.error(tree.pos(), "attribute.value.must.be.constant"); |
642 log.error(tree.pos(), Errors.AttributeValueMustBeConstant); |
644 return new Attribute.Error(expectedElementType); |
643 return new Attribute.Error(expectedElementType); |
645 } |
644 } |
646 result = cfolder.coerce(result, expectedElementType); |
645 result = cfolder.coerce(result, expectedElementType); |
647 return new Attribute.Constant(expectedElementType, result.constValue()); |
646 return new Attribute.Constant(expectedElementType, result.constValue()); |
648 } |
647 } |
654 NewArray(null, List.nil(), List.of(tree)); |
653 NewArray(null, List.nil(), List.of(tree)); |
655 } |
654 } |
656 |
655 |
657 JCNewArray na = (JCNewArray)tree; |
656 JCNewArray na = (JCNewArray)tree; |
658 if (na.elemtype != null) { |
657 if (na.elemtype != null) { |
659 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); |
658 log.error(na.elemtype.pos(), Errors.NewNotAllowedInAnnotation); |
660 } |
659 } |
661 ListBuffer<Attribute> buf = new ListBuffer<>(); |
660 ListBuffer<Attribute> buf = new ListBuffer<>(); |
662 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { |
661 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { |
663 buf.append(attributeAnnotationValue(types.elemtype(expectedElementType), |
662 buf.append(attributeAnnotationValue(types.elemtype(expectedElementType), |
664 l.head, |
663 l.head, |
749 |
748 |
750 repeated = repeated.prepend(currentAnno); |
749 repeated = repeated.prepend(currentAnno); |
751 } |
750 } |
752 |
751 |
753 if (!repeated.isEmpty() && targetContainerType == null) { |
752 if (!repeated.isEmpty() && targetContainerType == null) { |
754 log.error(ctx.pos.get(annotations.head), "duplicate.annotation.invalid.repeated", origAnnoType); |
753 log.error(ctx.pos.get(annotations.head), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType)); |
755 return null; |
754 return null; |
756 } |
755 } |
757 |
756 |
758 if (!repeated.isEmpty()) { |
757 if (!repeated.isEmpty()) { |
759 repeated = repeated.reverse(); |
758 repeated = repeated.reverse(); |
796 log.error(annoTree.pos(), |
795 log.error(annoTree.pos(), |
797 Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)); |
796 Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)); |
798 } |
797 } |
799 |
798 |
800 if (!chk.validateAnnotationDeferErrors(annoTree)) |
799 if (!chk.validateAnnotationDeferErrors(annoTree)) |
801 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); |
800 log.error(annoTree.pos(), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType)); |
802 |
801 |
803 c = attributeAnnotation(annoTree, targetContainerType, ctx.env); |
802 c = attributeAnnotation(annoTree, targetContainerType, ctx.env); |
804 c.setSynthesized(true); |
803 c.setSynthesized(true); |
805 |
804 |
806 @SuppressWarnings("unchecked") |
805 @SuppressWarnings("unchecked") |
825 // Fetch the Repeatable annotation from the current |
824 // Fetch the Repeatable annotation from the current |
826 // annotation's declaration, or null if it has none |
825 // annotation's declaration, or null if it has none |
827 Attribute.Compound ca = origAnnoDecl.getAnnotationTypeMetadata().getRepeatable(); |
826 Attribute.Compound ca = origAnnoDecl.getAnnotationTypeMetadata().getRepeatable(); |
828 if (ca == null) { // has no Repeatable annotation |
827 if (ca == null) { // has no Repeatable annotation |
829 if (reportError) |
828 if (reportError) |
830 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType); |
829 log.error(pos, Errors.DuplicateAnnotationMissingContainer(origAnnoType)); |
831 return null; |
830 return null; |
832 } |
831 } |
833 |
832 |
834 return filterSame(extractContainingType(ca, pos, origAnnoDecl), |
833 return filterSame(extractContainingType(ca, pos, origAnnoDecl), |
835 origAnnoType); |
834 origAnnoType); |
853 // on the declaration of the annotation type that is repeating is |
852 // on the declaration of the annotation type that is repeating is |
854 // valid. |
853 // valid. |
855 |
854 |
856 // Repeatable must have at least one element |
855 // Repeatable must have at least one element |
857 if (ca.values.isEmpty()) { |
856 if (ca.values.isEmpty()) { |
858 log.error(pos, "invalid.repeatable.annotation", annoDecl); |
857 log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl)); |
859 return null; |
858 return null; |
860 } |
859 } |
861 Pair<MethodSymbol,Attribute> p = ca.values.head; |
860 Pair<MethodSymbol,Attribute> p = ca.values.head; |
862 Name name = p.fst.name; |
861 Name name = p.fst.name; |
863 if (name != names.value) { // should contain only one element, named "value" |
862 if (name != names.value) { // should contain only one element, named "value" |
864 log.error(pos, "invalid.repeatable.annotation", annoDecl); |
863 log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl)); |
865 return null; |
864 return null; |
866 } |
865 } |
867 if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class |
866 if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class |
868 log.error(pos, "invalid.repeatable.annotation", annoDecl); |
867 log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl)); |
869 return null; |
868 return null; |
870 } |
869 } |
871 |
870 |
872 return ((Attribute.Class)p.snd).getValue(); |
871 return ((Attribute.Class)p.snd).getValue(); |
873 } |
872 } |
898 error = true; |
897 error = true; |
899 } |
898 } |
900 } |
899 } |
901 if (error) { |
900 if (error) { |
902 log.error(pos, |
901 log.error(pos, |
903 "invalid.repeatable.annotation.multiple.values", |
902 Errors.InvalidRepeatableAnnotationMultipleValues(targetContainerType, |
904 targetContainerType, |
903 nr_value_elems)); |
905 nr_value_elems); |
|
906 return null; |
904 return null; |
907 } else if (nr_value_elems == 0) { |
905 } else if (nr_value_elems == 0) { |
908 log.error(pos, |
906 log.error(pos, |
909 "invalid.repeatable.annotation.no.value", |
907 Errors.InvalidRepeatableAnnotationNoValue(targetContainerType)); |
910 targetContainerType); |
|
911 return null; |
908 return null; |
912 } |
909 } |
913 |
910 |
914 // validate that the 'value' element is a method |
911 // validate that the 'value' element is a method |
915 // probably "impossible" to fail this |
912 // probably "impossible" to fail this |
916 if (containerValueSymbol.kind != MTH) { |
913 if (containerValueSymbol.kind != MTH) { |
917 log.error(pos, |
914 log.error(pos, |
918 "invalid.repeatable.annotation.invalid.value", |
915 Errors.InvalidRepeatableAnnotationInvalidValue(targetContainerType)); |
919 targetContainerType); |
|
920 fatalError = true; |
916 fatalError = true; |
921 } |
917 } |
922 |
918 |
923 // validate that the 'value' element has the correct return type |
919 // validate that the 'value' element has the correct return type |
924 // i.e. array of original anno |
920 // i.e. array of original anno |
925 Type valueRetType = containerValueSymbol.type.getReturnType(); |
921 Type valueRetType = containerValueSymbol.type.getReturnType(); |
926 Type expectedType = types.makeArrayType(originalAnnoType); |
922 Type expectedType = types.makeArrayType(originalAnnoType); |
927 if (!(types.isArray(valueRetType) && |
923 if (!(types.isArray(valueRetType) && |
928 types.isSameType(expectedType, valueRetType))) { |
924 types.isSameType(expectedType, valueRetType))) { |
929 log.error(pos, |
925 log.error(pos, |
930 "invalid.repeatable.annotation.value.return", |
926 Errors.InvalidRepeatableAnnotationValueReturn(targetContainerType, |
931 targetContainerType, |
927 valueRetType, |
932 valueRetType, |
928 expectedType)); |
933 expectedType); |
|
934 fatalError = true; |
929 fatalError = true; |
935 } |
930 } |
936 |
931 |
937 return fatalError ? null : containerValueSymbol; |
932 return fatalError ? null : containerValueSymbol; |
938 } |
933 } |
949 // present along with repeated instances of |
944 // present along with repeated instances of |
950 // its contained annotation. |
945 // its contained annotation. |
951 ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); |
946 ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); |
952 if (manualContainer != null) { |
947 if (manualContainer != null) { |
953 log.error(ctx.pos.get(manualContainer.first()), |
948 log.error(ctx.pos.get(manualContainer.first()), |
954 "invalid.repeatable.annotation.repeated.and.container.present", |
949 Errors.InvalidRepeatableAnnotationRepeatedAndContainerPresent(manualContainer.first().type.tsym)); |
955 manualContainer.first().type.tsym); |
|
956 } |
950 } |
957 } |
951 } |
958 |
952 |
959 // A null return will delete the Placeholder |
953 // A null return will delete the Placeholder |
960 return validRepeated; |
954 return validRepeated; |