<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
        {font-family:"Times New Roman \(Body CS\)";
        panose-1:2 11 6 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;}
span.EmailStyle20
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="en-CZ" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I think our current Classfile.Option is already not so far from the proposed global context holder approach.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">The most significant use cases to persist (class hierarchy resolution and custom attributes) can be very well cached by keeping the Classfile.Option instances and re-using
 them as many times as user needs.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var options = List.of(Option.classHierarchyResolver(resolver),
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">                      Option.attributeMapper(mapper));<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.build(clsDesc, options, handler);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options); //here we have only vararg now<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">What I’m missing much much more than “global options holder” is per-transformation options (or even option change for transformed method).
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">For example I would like to use one class model to transform into multiple classes with different options, and I have to write:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options1).transform(classTransform1);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">Classfile.parse(bytes, options2).transform(classTransform2);</span><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Instead of simple:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var clm = Classfile.parse(bytes);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform1, options1);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform2, options2);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Or maybe:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">var clm = Classfile.parse(bytes, options1);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform1);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.setOptions(options2);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US">clm.transform(classTransform2);<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">However it raises the main question about what options are really tied to model parsing (I think it is only attributeMapper).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">And what options can be safely changed later. For example can I change processDebug, processLineNumbers or processUnknownAttributes on already parsed class model to
 get different results of the following model traversal?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">And there are majority of options unrelated to the parsed class model but affecting only building and transformations (generateStackmap, constantPoolSharing, fixShortJumps,
 patchDeadCode, classHierarchyResolver, filterDeadLabels).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I think we should make more clear which options affect what actions (parsing, building, transformation) and give more flexibility to change them on the fly.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Adam<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">classfile-api-dev <classfile-api-dev-retn@openjdk.org> on behalf of Brian Goetz <brian.goetz@oracle.com><br>
<b>Date: </b>Thursday, 18 May 2023 16:16<br>
<b>To: </b>liangchenblue@gmail.com <liangchenblue@gmail.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
<b>Subject: </b>Re: Planned features of a classfile context object<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New"">Currently the ConstantPoolBuilder is another place we we attach options.  This was more of a sin of convenience than anything else; the theory was that
 if we are transforming a class, we'll parse it with a set of options, and then generate a new class which shares its CP, and the options came along for the ride. 
<br>
<br>
Searching for a better name that ClassfileContext.  The name Classfile is too good to waste, but it doesn't represent a classfile (that's ClassModel), so calling the new thing Classfile would likely be weird.  Also ClassfileContext would make it harder to discover
 the key entry points (build/parse).  Classfile.Context is better in that it is more discoverable at least. 
<br>
<br>
Classfile{Parser,Generator} are more discoverable but only tell half the story, and there's no obvious "first half" of the story.  ClassfileReaderWriter is discoverable and honest but long.  Classfile{Broker,Manager,Mediator} sound like parodies of the Design
 Patterns era.  <br>
<br>
A slightly cheeky but possibly viable option is "Classfiles"; while not a collection of classfiles, it is a collection of behaviors _about_ classfiles. 
<br>
<br>
    Classfiles.of(options).parse(bytes)<br>
    Classfiles.of(options).generate(handler)<br>
<br>
<br>
<br>
<br>
</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 5/17/2023 11:21 AM, Brian Goetz wrote:<o:p></o:p></span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal" style="margin-bottom:12.0pt"><span style="font-size:13.5pt;font-family:"Courier New"">These are basically what is on my list, though I had in mind to move _all_ option information to the context, and leave it out of individual processing
 decisions.  </span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">On 5/17/2023 9:59 AM, - wrote:<o:p></o:p></span></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<pre>Hi,<o:p></o:p></pre>
<pre>In the discussions a few weeks ago, we envisioned a Classfile context<o:p></o:p></pre>
<pre>object shared across multiple Classfile processing scenarios, mainly<o:p></o:p></pre>
<pre>for Class hierarchy information caching.<o:p></o:p></pre>
<pre><o:p> </o:p></pre>
<pre>I want to confirm that these are contents of the object, mainly<o:p></o:p></pre>
<pre>promoted from individual options:<o:p></o:p></pre>
<pre> - Class Hierarchy information caching<o:p></o:p></pre>
<pre> - Custom attribute processing<o:p></o:p></pre>
<pre> - A set of default options, propagated to individual processing (may<o:p></o:p></pre>
<pre>be overridden classfile-wise)<o:p></o:p></pre>
<pre><o:p> </o:p></pre>
<pre>What else is planned for the context object currently? Please don't<o:p></o:p></pre>
<pre>hesitate to propose. Thanks!<o:p></o:p></pre>
<pre><o:p> </o:p></pre>
<pre>Chen Liang<o:p></o:p></pre>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</blockquote>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</body>
</html>