<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">I agree that much of what such
        a context would manage is options.  But I think we can also
        agree that the current treatment, where we stash Options in the
        CPBuilder, isn't right either.  <br>
        <br>
        I can buy that sometimes we want to parse with different options
        than we generate with.  We can add this in as as goal for
        rationalizing the classfile context.  I suspect also that part
        of the problem is that our options are too granular: "process
        debug" is just a boolean, which could be broken down further. 
        As a not-entirely-serious suggestion: <br>
        <br>
            enum ProcessDebugOptions implements Option { <br>
                DROP_DEBUG, DROP_DEBUG_ON_READ, DROP_DEBUG_ON_WRITE;<br>
            }<br>
        <br>
        Originally all our options were booleans, and we've moved past
        that structurally, but haven't really reexamined all the options
        we defined.<br>
        <br>
        I think the problem with "can't transform with different
        options" stems from the fact that transform lives only on the
        model, not on the context.  This would let you do what you want
        as:<br>
        <br>
            ClassModel cm = CC.of(opts1).parse(bytes);<br>
            CC.of(opts2).transform(cm, transform);<br>
      </font></font><font size="4"><font face="monospace"><font size="4"><font face="monospace">    CC.of(opts3).transform(cm, transform);<br>
          </font></font><br>
        This derives from the principle that all classfile entities are
        immutable and can be used in any context; no need to re-parse. 
        <br>
        <br>
        <br>
        <br>
      </font></font><br>
    <div class="moz-cite-prefix">On 5/19/2023 3:52 AM, Adam Sotona
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CY4PR1001MB21508C93F6B00FE5FEB5BFF78C7C9@CY4PR1001MB2150.namprd10.prod.outlook.com">
      
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style>@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;}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;}div.WordSection1
        {page:WordSection1;}</style>
      <div class="WordSection1">
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var options =
            List.of(Option.classHierarchyResolver(resolver),
            <o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">                      Option.attributeMapper(mapper));<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.build(clsDesc, options, handler);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes, options); //here we have
            only vararg now<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes,
            options1).transform(classTransform1);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">Classfile.parse(bytes,
            options2).transform(classTransform2);</span><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Instead of simple:<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var clm = Classfile.parse(bytes);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform1, options1);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform2, options2);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Or maybe:<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">var clm = Classfile.parse(bytes, options1);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform1);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.setOptions(options2);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;font-family:Consolas;mso-fareast-language:EN-US" lang="EN-US">clm.transform(classTransform2);<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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 style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US"><o:p> </o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Thanks,<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="EN-US">Adam<o:p></o:p></span></p>
        <p class="MsoNormal"><span style="font-size:11.0pt;mso-fareast-language:EN-US" lang="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
              <a class="moz-txt-link-rfc2396E" href="mailto:classfile-api-dev-retn@openjdk.org"><classfile-api-dev-retn@openjdk.org></a> on behalf of
              Brian Goetz <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com"><brian.goetz@oracle.com></a><br>
              <b>Date: </b>Thursday, 18 May 2023 16:16<br>
              <b>To: </b><a class="moz-txt-link-abbreviated" href="mailto:liangchenblue@gmail.com">liangchenblue@gmail.com</a>
              <a class="moz-txt-link-rfc2396E" href="mailto:liangchenblue@gmail.com"><liangchenblue@gmail.com></a>, classfile-api-dev
              <a class="moz-txt-link-rfc2396E" href="mailto:classfile-api-dev@openjdk.org"><classfile-api-dev@openjdk.org></a><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>
    </blockquote>
    <br>
  </body>
</html>