Repository navigation
Add support for the RuntimeVisibleTypeAnnotations and RuntimeInvisibleTypeAnnotations attributes - #539
Conversation
…eTypeAnnotations attributes Both attributes (JVMS 4.7.20) were returned as Unknown, so a caller had to parse the raw bytes (target_type/target_info, type_path, annotation) to know about annotations such as JSpecify's @nullable, which are type annotations. - Const: ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS. - TypeAnnotations (base class), RuntimeVisibleTypeAnnotations and RuntimeInvisibleTypeAnnotations, TypeAnnotationEntry (target type and info, type path, AnnotationEntry); read and dump round trip. - Visitor.visitTypeAnnotations (default method), DescendingVisitor, EmptyVisitor, StringRepresentation. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@garydgregory The On my fork every other job passes (21 of 22, all operating systems and Java 8 to 27): nbauma109#103 |
|
@nbauma109 Copying
Visting
TypeAnnotationEntryThe new JavadocThe new Javadoc also needs corrections: Could you address each point, or explain the intended BCEL contract if any of these behaviors is intentional? |
…ations, validation of TypeAnnotationEntry, Javadoc - copy(ConstantPool) of RuntimeVisibleTypeAnnotations and RuntimeInvisibleTypeAnnotations copies the entries and binds them and the attribute to the given constant pool. - DescendingVisitor.visitTypeAnnotations visits the AnnotationEntry of each entry. - The TypeAnnotationEntry constructor rejects a type path which is not a sequence of pairs of bytes of at most 255 steps, and a target info whose size does not match its target type. - Javadoc: empty type path, TARGET_CLASS_EXTENDS, scope of the attributes. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
@garydgregory All four points are addressed in 601010f. Copying. Visiting. TypeAnnotationEntry. The constructor throws Javadoc. The default |
Parses and writes the
RuntimeVisibleTypeAnnotationsandRuntimeInvisibleTypeAnnotationsattributes (JVMS 4.7.20), whichAttribute.readAttributereturns asUnknowntoday.Why
Annotations written on types (JSR 308) are stored apart from the declaration annotations: JSpecify's
@Nullableinvoid put(@Nullable Object key),List<@Nullable String>,<K extends @Nullable Object>. A user of BCEL can only get them by parsing the bytes of anUnknownattribute itself: target type, variable-size target info, type path, then the annotation with its element values. For example, a decompiler built on BCEL loses every@Nullableof a library such as Guava, whose packages are@NullMarked, and the recompiled sources are rejected by Error Prone.Changes
Const:ATTR_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = 29,ATTR_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = 30,KNOWN_ATTRIBUTES = 31, and the two attribute names.TypeAnnotations(abstract,Iterable<TypeAnnotationEntry>, likeAnnotations),RuntimeVisibleTypeAnnotations,RuntimeInvisibleTypeAnnotations.TypeAnnotationEntry: the target type (TARGET_*constants for the table 4.7.20-A), the target info as stored in the class file (its size depends on the target type; thelocalvar_targettable has a variable size), the type path (getTypePathLength,getTypePathKind,getTypePathArgumentIndex), and theAnnotationEntryread by the existing code. An undefined target type throwsClassFormatException; the constructor rejects a type path that is not a sequence of pairs of bytes (at most 255 steps) and a target info whose size does not match the target type.dumpwrites whatreadread, andcopy(ConstantPool)makes a deep copy bound to the given constant pool.Attribute.readAttribute,Visitor.visitTypeAnnotations(a default method: existingVisitorimplementations are unaffected),DescendingVisitor(which also visits theAnnotationEntryof each entry),EmptyVisitor,StringRepresentation, and an entry inchanges.xml.The target info is exposed as bytes, not as one class per kind of target, to keep the API small. The meaning of its bytes is documented on
getTargetInfo(): index of the type parameter, of the bound, or of the formal parameter.Tests
TypeAnnotationsTestreadssrc/test/resources/typeannotations/TypeAnnotated.class, compiled withjavac --release 8from the.javafile next to it. It covers a field, the type path of a type argument, an invisible annotation, a method return and a parameter, the bound of a class type parameter, dump then re-read,copy(independent mutation, other constant pool), the visitor callbacks and their stack context, andStringRepresentation. More tests cover thelocalvar_targettable (read then dump gives the same bytes), an undefined target type, a malformed type path and a target info of the wrong size.The default
mvngoal (tests, rat, japicmp, checkstyle, pmd, spotbugs, javadoc) passes.🤖 Generated with Claude Code