751 attrCount++; 752 } 753 if (invisibles.length() != 0) { 754 int attrIndex = writeAttr(names.RuntimeInvisibleAnnotations); 755 databuf.appendChar(invisibles.length()); 756 for (Attribute.Compound a : invisibles) 757 writeCompoundAttribute(a); 758 endAttr(attrIndex); 759 attrCount++; 760 } 761 return attrCount; 762 } 763 764 int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos, boolean inCode) { 765 if (typeAnnos.isEmpty()) return 0; 766 767 ListBuffer<Attribute.TypeCompound> visibles = new ListBuffer<>(); 768 ListBuffer<Attribute.TypeCompound> invisibles = new ListBuffer<>(); 769 770 for (Attribute.TypeCompound tc : typeAnnos) { 771 if (tc.hasUnknownPosition()) { 772 boolean fixed = tc.tryFixPosition(); 773 774 // Could we fix it? 775 if (!fixed) { 776 // This happens for nested types like @A Outer. @B Inner. 777 // For method parameters we get the annotation twice! Once with 778 // a valid position, once unknown. 779 // TODO: find a cleaner solution. 780 PrintWriter pw = log.getWriter(Log.WriterKind.ERROR); 781 pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc); 782 continue; 783 } 784 } 785 786 if (tc.position.type.isLocal() != inCode) 787 continue; 788 if (!tc.position.emitToClassfile()) 789 continue; 790 switch (types.getRetention(tc)) { 791 case SOURCE: break; 792 case CLASS: invisibles.append(tc); break; 793 case RUNTIME: visibles.append(tc); break; 794 default: // /* fail soft */ throw new AssertionError(vis); 795 } 796 } 797 798 int attrCount = 0; 799 if (visibles.length() != 0) { 800 int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations); 801 databuf.appendChar(visibles.length()); 802 for (Attribute.TypeCompound p : visibles) 803 writeTypeAnnotation(p); 804 endAttr(attrIndex); 805 attrCount++; 806 } 807 808 if (invisibles.length() != 0) { 809 int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations); 950 databuf.appendChar(p.type_index); 951 break; 952 // method parameter 953 case METHOD_FORMAL_PARAMETER: 954 databuf.appendByte(p.parameter_index); 955 break; 956 // type cast 957 case CAST: 958 // method/constructor/reference type argument 959 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 960 case METHOD_INVOCATION_TYPE_ARGUMENT: 961 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 962 case METHOD_REFERENCE_TYPE_ARGUMENT: 963 databuf.appendChar(p.offset); 964 databuf.appendByte(p.type_index); 965 break; 966 // We don't need to worry about these 967 case METHOD_RETURN: 968 case FIELD: 969 break; 970 case UNKNOWN: 971 throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!"); 972 default: 973 throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p); 974 } 975 976 { // Append location data for generics/arrays. 977 databuf.appendByte(p.location.size()); 978 java.util.List<Integer> loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location); 979 for (int i : loc) 980 databuf.appendByte((byte)i); 981 } 982 } 983 984 /********************************************************************** 985 * Writing Objects 986 **********************************************************************/ 987 988 /** Enter an inner class into the `innerClasses' set/queue. 989 */ 990 void enterInner(ClassSymbol c) { 991 if (c.type.isCompound()) { | 751 attrCount++; 752 } 753 if (invisibles.length() != 0) { 754 int attrIndex = writeAttr(names.RuntimeInvisibleAnnotations); 755 databuf.appendChar(invisibles.length()); 756 for (Attribute.Compound a : invisibles) 757 writeCompoundAttribute(a); 758 endAttr(attrIndex); 759 attrCount++; 760 } 761 return attrCount; 762 } 763 764 int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos, boolean inCode) { 765 if (typeAnnos.isEmpty()) return 0; 766 767 ListBuffer<Attribute.TypeCompound> visibles = new ListBuffer<>(); 768 ListBuffer<Attribute.TypeCompound> invisibles = new ListBuffer<>(); 769 770 for (Attribute.TypeCompound tc : typeAnnos) { 771 Assert.checkNonNull(tc.position); 772 if (tc.position.type.isLocal() != inCode) { 773 continue; 774 } 775 if (!tc.position.emitToClassfile()) { 776 continue; 777 } 778 switch (types.getRetention(tc)) { 779 case SOURCE: break; 780 case CLASS: invisibles.append(tc); break; 781 case RUNTIME: visibles.append(tc); break; 782 default: // /* fail soft */ throw new AssertionError(vis); 783 } 784 } 785 786 int attrCount = 0; 787 if (visibles.length() != 0) { 788 int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations); 789 databuf.appendChar(visibles.length()); 790 for (Attribute.TypeCompound p : visibles) 791 writeTypeAnnotation(p); 792 endAttr(attrIndex); 793 attrCount++; 794 } 795 796 if (invisibles.length() != 0) { 797 int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations); 938 databuf.appendChar(p.type_index); 939 break; 940 // method parameter 941 case METHOD_FORMAL_PARAMETER: 942 databuf.appendByte(p.parameter_index); 943 break; 944 // type cast 945 case CAST: 946 // method/constructor/reference type argument 947 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 948 case METHOD_INVOCATION_TYPE_ARGUMENT: 949 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 950 case METHOD_REFERENCE_TYPE_ARGUMENT: 951 databuf.appendChar(p.offset); 952 databuf.appendByte(p.type_index); 953 break; 954 // We don't need to worry about these 955 case METHOD_RETURN: 956 case FIELD: 957 break; 958 default: 959 throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p); 960 } 961 962 { // Append location data for generics/arrays. 963 databuf.appendByte(p.location.size()); 964 java.util.List<Integer> loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location); 965 for (int i : loc) 966 databuf.appendByte((byte)i); 967 } 968 } 969 970 /********************************************************************** 971 * Writing Objects 972 **********************************************************************/ 973 974 /** Enter an inner class into the `innerClasses' set/queue. 975 */ 976 void enterInner(ClassSymbol c) { 977 if (c.type.isCompound()) { |