<div dir="ltr"><div>Hello,</div><div><br></div><div>I recently implemented a bridge between attributes in the Class File API and ASM, which mostly succeeded, but I wanted to point out that this area is one with the least compatibility. Making this production ready would also require minor adjustments in the ASM API, but it seems like the team there is open to those. I also understand that it's not a project goal to replicate the ASM, but I assume that the ASM API is built upon actual use cases and that a good compatibility will make migration easier for those who aim for it.<br></div><div><br></div><div>To begin with, there are two minor incompatibilities that I do not think will have a big impact, but which would be nice to fix:</div><div>- ASM exposes className, superClassName and interfaceNames from its ClassReader. The Class File API only exposes className and superClassName. One can still navigate through the attributed element to get hold of the interface names unless attributing a record component info where the parent is not exposed. This is mainly an inconvenience.<br></div><div>- ASM allows for translating constant pool indices to class file offsets. In theory, one can read the entire class file using the Class File API's ClassReader and offer the same translation, but I would want to avoid manual parsing. The ASM API is offset based and only allows access to most constants using an offset. The Class File API offers access for either offset or index, but includes no possibility to translate. Maybe ASM could however offer a way to access by either offset or index, too, and deprecate the translation method. The Class File API is more convenient here and there is no reason to ask a user to make conversions.<br></div><div><br></div><div>The more complex operation where I cannot currently succeed are attributes on the code attribute. Unfortunately, those are the most common custom attributes, and they often carry references to the code. Here I struggle to use the Class File API altogether.</div><div><br></div><div>Normally, a custom attribute on code stores offsets to the byte code. In some way, I want to add some information about a section of code. When reading such an attribute I would read those offsets, which are typically presented as labels. I think that from AttributeMapper::read, it should be possible to tell the Class File API that labels should be inserted at given positions. Those labels could then be discovered when walking through the instructions. For example one could add a method "bciToLabel" method somewhere. The resolved custom attribute could then only contain these labels such that a user of the Class File API can match the labeled offset to a segment in the code.</div><div><br></div><div>At the same time, AttributeMapper::write should contain a form of "labelToBci" method such that (possibly altered) byte code offsets can be stored back in the class file. Possibly getBci could be exposed on the Label, too, maybe returning an OptionalInt to accommodate labels where the offset is not yet bound.<br></div><div><br></div><div>The issue with this is that form of logic is only relevant to attributes on the code attribute. ASM has itself a special handling of such attributes where one overrides the isCodeAttribute method of org.ow2.asm.Attribute class. When reading such an attribute, it is also passed additional information. On reading, it is passed the beginning offset of the code attribute itself and an array of labels that are included in the code. There is however no way of inserting new labels as of today, something I consider a lacking feature of ASM.</div><div><br></div><div>When writing such an attribute, ASM is including most data from the CodeAttribute to which the attribute is written to. Personlly, I also think that the Class File API should add the context to which an attribute is written to as an argument, similar to when reading an attribute. It is fully possible to write different data for example when adding an attribute to a field, or to a method. Ideally, it should be possible to (lazily) resolve previously written, different attributes from the target when writing, to add contextual information.</div><div><br></div><div>Thanks! If you are curious how the back and forth mapping of ASM and JDK attributes currently looks like, you can check this class: <a href="https://github.com/raphw/asm-jdk-bridge/blob/main/src/main/java/codes/rafael/asmjdkbridge/AsmAttribute.java#L59">https://github.com/raphw/asm-jdk-bridge/blob/main/src/main/java/codes/rafael/asmjdkbridge/AsmAttribute.java#L59</a></div><div><br></div><div>Best regards, Rafael<br></div></div>