nbauma109 opened a new pull request, #539:
URL: https://github.com/apache/commons-bcel/pull/539

   Parses and writes the `RuntimeVisibleTypeAnnotations` and 
`RuntimeInvisibleTypeAnnotations` attributes ([JVMS 
4.7.20](https://docs.oracle.com/javase/specs/jvms/se21/html/jvms-4.html#jvms-4.7.20)),
 which `Attribute.readAttribute` returns as `Unknown` today.
   
   ## Why
   
   Annotations written on types (JSR 308) are stored apart from the declaration 
annotations: JSpecify's `@Nullable` in `void put(@Nullable Object key)`, 
`List<@Nullable String>`, `<K extends @Nullable Object>`. A user of BCEL can 
only get them by parsing the bytes of an `Unknown` attribute 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 `@Nullable` 
of 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>`, like 
`Annotations`), `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; the `localvar_target` table has a variable size), the type path 
(`getTypePathLength`, `getTypePathKind`, `getTypePathArgumentIndex`), and the 
`AnnotationEntry` read by the existing code. An undefined target type throws 
`ClassFormatException`. `dump` writes what `read` read.
   - `Attribute.readAttribute`, `Visitor.visitTypeAnnotations` (a default 
method: existing `Visitor` implementations are unaffected), 
`DescendingVisitor`, `EmptyVisitor`, `StringRepresentation`, and an entry in 
`changes.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
   
   `TypeAnnotationsTest` reads 
`src/test/resources/typeannotations/TypeAnnotated.class`, compiled with `javac 
--release 8` from the `.java` file 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`, the visitor and 
`StringRepresentation`. Two more tests cover the `localvar_target` table (read 
then dump gives the same bytes) and an undefined target type.
   
   The default `mvn` goal (tests, rat, japicmp, checkstyle, pmd, spotbugs, 
javadoc) passes.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to