A workaround was added in 4accca37 for issue #307392 (closed). The root cause of the bug was that, via a ClassReader->ClassWriter transform, the length of the parameter_annotations array in the Runtime[In]VisibleParameterAnnotations attribute was not preserved (the number read in ClassReader was ignored, and it was recomputed from the descriptor in MethodWriter).
The workaround added at this time was fixing that, and it was also attempting to report parameter indices corresponding to the source parameters, assuming that the implicit parameters were at added at the begining. However, synthetic parameters can also be added at the end (see issue #317788 (closed)), so the second part of the above workaround does not work.
This change removes this workaround, and replaces it with a new visitAnnotableParameterCount method to preserve the size of the above array in a ClassReader->ClassWriter chain. In other words, this change still fixes the root cause of #307392 (closed) (closed), but no longer attempts to map bytecode parameter indices to source level parameter indices. We believe there is no universal method for doing that, but users can implement their own method, if desired, on top of the ASM API. Indeed, the JVMS spec states that (https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18):
The i'th entry in the parameter_annotations table may, but is not required to, correspond to the i'th parameter descriptor in the method descriptor (§4.3.3).
For example, a compiler may choose to create entries in the table corresponding only to those parameter descriptors which represent explicitly declared parameters in source code. In the Java programming language, a constructor of an inner class is specified to have an implicitly declared parameter before its explicitly declared parameters (JLS §8.8.1), so the corresponding method in a class file has a parameter descriptor representing the implicitly declared parameter before any parameter descriptors representing explicitly declared parameters. If the first explicitly declared parameter is annotated in source code, then a compiler may create parameter_annotations to store annotations corresponding to the second parameter descriptor.
Note that the new visit method need not be called. By default (for instance for classes generated from scratch, without a ClassReader), the number of annotable parameters is the number of parameters in the method descriptor. This was also the case with the current code (i.e. when no ASM specific Ljava/lang/Synthetic; annotation was used to mark synthetic parameters). In theory, we should define a new API version, e.g. ASM_6_1, and implement the full backward compatibility mechanism for this new visit method, but I'm not sure it is worth doing so. What do you think?
Closes #317788 (closed)