<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Mark,</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
No, accept and atEnd are both the first transform. No-op accept just drops elements of the transformed objects; atEnd is called when all accept calls are done, so here you are actually operating on a new class.</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I am thinking of adding <code>transforming</code> like that in CodeBuilder to other builders - CodeBuilder has this because CodeBuilder creation required no extra arguments. For other builders, I think we can just inherit arguments from the called builder.</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div class="elementToProof" style="font-family: "Calibri Light", "Helvetica Light", sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Chen</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Mark Roberts <markro@cs.washington.edu><br>
<b>Sent:</b> Thursday, April 24, 2025 5:07 PM<br>
<b>To:</b> Chen Liang <chen.l.liang@oracle.com>; classfile-api-dev@openjdk.org <classfile-api-dev@openjdk.org><br>
<b>Subject:</b> [External] : RE: modifying a newly added method</font>
<div> </div>
</div>
<style>
<!--
@font-face
        {font-family:"Cambria Math"}
@font-face
        {font-family:Calibri}
@font-face
        {font-family:"Calibri Light"}
p.x_MsoNormal, li.x_MsoNormal, div.x_MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif}
a:link, span.x_MsoHyperlink
        {color:#0563C1;
        text-decoration:underline}
code
        {font-family:"Courier New"}
span.x_EmailStyle21
        {font-family:"Calibri",sans-serif;
        color:windowtext}
.x_MsoChpDefault
        {font-size:10.0pt}
@page WordSection1
        {margin:1.0in 1.0in 1.0in 1.0in}
div.x_WordSection1
        {}
-->
</style>
<div lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="x_WordSection1">
<p class="x_MsoNormal">This approach looks interesting.  Just want to make sure I understand the control flow. 
</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">The empty ‘accept’ is the first transform that does nothing.</p>
<p class="x_MsoNormal">‘atEnd’ is the second transform</p>
<p class="x_MsoNormal">‘andThen is the third transform which will see any changes made by the second transform</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Correct?</p>
<p class="x_MsoNormal"> </p>
<p class="x_MsoNormal">Thank you,</p>
<p class="x_MsoNormal">Mark</p>
<p class="x_MsoNormal"> </p>
<div>
<div style="border:none; border-top:solid #e1e1e1 1.0pt; padding:3.0pt 0in 0in 0in">
<p class="x_MsoNormal"><b>From:</b> Chen Liang <<a href="mailto:chen.l.liang@oracle.com">chen.l.liang@oracle.com</a>>
<br>
<b>Sent:</b> Tuesday, April 15, 2025 10:33 AM<br>
<b>To:</b> Mark Roberts <<a href="mailto:markro@cs.washington.edu">markro@cs.washington.edu</a>>;
<a href="mailto:classfile-api-dev@openjdk.org">classfile-api-dev@openjdk.org</a><br>
<b>Subject:</b> Re: modifying a newly added method</p>
</div>
</div>
<p class="x_MsoNormal"> </p>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Hi Mark,</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Unfortunately there is no easy way to do this, but it is doable.</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">One way can be that you start with a class transform with a dummy class model, and move your original class builder code into the
</span><code><span style="font-size:10.0pt; color:black">atEnd</span></code><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">  of your first transform. Then, you can call
</span><code><span style="font-size:10.0pt; color:black">andThen</span></code><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> with the 2nd transform, which can get MethodModel views of methods built by your first transform.</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Pseudocode:</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Original:</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">cf.build(name, clb -> /* oldLambdaCode */)</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Updated:</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">cf.build(clb -> clb.transform(dummyClassModel, new ClassTransform() {</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">  @Override public void accept(ClassBuilder b, ClassEement e) {} // throw away</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">  @Override public void atEnd(ClassBuilder clb) { /* oldLambdaCode */ }</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">}.andThen(/* your actual transform that can see your old lambda's methods as MethodModel*/))</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">That said, I had previously proposed to introduce something like
</span><code><span style="font-size:10.0pt; color:black">CodeBuilder::transforming</span></code><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> to other models, which could have probably covered your use case; however, other
 builders require extra arguments to be constructed (class name, field/method name and types) so we did not add these APIs back.</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">If you have an idea how such additions can be done, feel free to share your ideas.</span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black"> </span></p>
</div>
<div>
<p class="x_MsoNormal"><span style="font-size:12.0pt; font-family:"Calibri Light",sans-serif; color:black">Regards, Chen</span></p>
</div>
<div class="x_MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="x_divRplyFwdMsg">
<p class="x_MsoNormal"><b><span style="color:black">From:</span></b><span style="color:black"> classfile-api-dev <<a href="mailto:classfile-api-dev-retn@openjdk.org">classfile-api-dev-retn@openjdk.org</a>> on behalf of Mark Roberts <<a href="mailto:markro@cs.washington.edu">markro@cs.washington.edu</a>><br>
<b>Sent:</b> Tuesday, April 15, 2025 12:15 PM<br>
<b>To:</b> <a href="mailto:classfile-api-dev@openjdk.org">classfile-api-dev@openjdk.org</a> <<a href="mailto:classfile-api-dev@openjdk.org">classfile-api-dev@openjdk.org</a>><br>
<b>Subject:</b> modifying a newly added method</span> </p>
<div>
<p class="x_MsoNormal"> </p>
</div>
</div>
<div>
<div>
<p class="x_MsoNormal">If I have added a new method to my classfile with<br>
ClassBuilder.withMethod(...) I know it is not added to ClassModel.methods()<br>
as that is an immutable list from the original, unmodified classfile.  Is<br>
there any way to get a MethodModel for this new method in order to modify it<br>
further?<br>
<br>
Thank you,<br>
Mark</p>
</div>
</div>
</div>
</div>
</body>
</html>