Experience report

Brian Goetz brian.goetz at oracle.com
Tue Aug 16 14:28:10 UTC 2022



On 8/15/2022 4:26 PM, Dan Heidinga wrote:
> Thanks for the feedback, Brian.
>
> I've worked through the suggestions on the various ways to update an 
> Attribute {use a stateful ClassTransform, use 
> builder.original().get()} and found the "original().get()" approach 
> felt the cleanest and clearest for what I was doing.

By that, do you mean "cleanest of the terrible options", or "seemed a 
good enough option"?

> While working on that, I also added the ::with & ::withSymbols methods 
> I had proposed and opened a PR [0] to see if the fleshed out API fit 
> with the general way you wanted to evolve this.

I had a look at the API suggestions and I have a counter-suggestion.

The operation that you are trying to enable is adding to (and I predict 
eventually, removing from) list-holding attributes.  You propose four 
new methods for each attribute:

     NMA with(NMA base, List<CE> additions)
     NMA with(NMA base, CE... additions)
     NMA withSymbols(NMA base, List<CD> additions)
     NMA withSymbols(NMA base, CD... additions)

So that's 2 representations (CE/CD) x 2 API styles (list, varargs) x N 
attributes (4N), which will get worse if the attribute is not merely a 
holder for a list, but might have other stuff to be modified too.  If 
you want to support removals, that's 2x more.

Really what you need is four methods, somewhere:

     List<CE> adding(List<CE>, List<CE>)
     List<CE> adding(List<CE>, CE...)
     List<CE> addingSymbols(List<CE>, List<CD>)
     List<CE> addingSymbols(List<CE>, CD...)

and invoke it like:

     case NMA a -> NMA.of(adding(a.nestMembers(), NEW_STUFF));

And this would cover all attributes, plus would support dealing with 
attributes that have more than just a List<CE> in them.  The question is 
where to put these to make them discoverable.




More information about the classfile-api-dev mailing list