The attached Java file shows a rough sketch of what the
CompilationAnalysis API might look like.  The basic idea is to map
J(s)Nodes, SourceInfos, and Correlations onto a simplified API
suitable for building reports from.  The inner interfaces would likely
be top-level types in a separate package, but are in the one Java file
for ease of transmission.

The "byte-accounting" use cases would generally start with
getStories(), which returns a Map of non-overlapping Ranges onto the
applicable Story.  Each Story can then provide a collection of Members
that should be charged for those bytes.

The "reachability" use case would use getClasses() and proceed to
extract the fields and methods that have been retained (if somewhat
mangled) in the JS output.  The "dependency" use case is an extension
and would crawl the Members that implement HasDependency.

The "inspection" use case (similar to the JS-normal view) would be an
extension of the byte-accounting interface, but would add in the
additional mutation metadata from the Story.  I'd expect that this is
only really useful for compiler developers to look at the output with
this much detail.

Points for discussion:
  - Are simple HTML reports generated from the API (by a
SoycReportLinker) or by processing an all-inclusive XML file after the
fact?
  - There's going to be a _lot_ of data in the XML file [1].  It will
likely be necessary to break the data up over several files, but I
think that if we start with a single XML file and try to build some
XSLT reports from it, we'll have a better idea of where the hotspots
are.
  - If the data is broken up across several XML files, do we just
start with a manifest XML file that says "for dependency data for this
permutation, see this file"?
  - I don't really expect that anyone would use the Linker API
directly, so I'm not really concerned with having that API perform any
kind of aggregation or computations on behalf of the consumer.  It's
there in case anyone wants to use a different export format or to do
something crazy like submit the data to a database as part of the
build process.

[1] A graphviz / .dot file showing dependencies for Dynatable weighs
in at about 600k.  It's mainly full of text label and lines that look
like (56 -> 182);  Showcase dependency files are just under a meg.

-- 
Bob Vawter
Google Web Toolkit Team

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Attachment: CompilationAnalysis.java
Description: Binary data

<?xml version="1.0" encoding="UTF-8"?>
<soyc>
  <!--
    Assume that the children of the soyc node could be split up among several
    files to allow report-writers to reduce to total amount of XML used when
    generating simple reports.
  -->

  <!-- Members are functional units that humans like to use -->
  <members>
    <class id="com.google.Class" name="Class" package="com.google">
      <!--
        Preserve some amount of the type hierarchy, even if the superclass or
        superinterface doesn't contribute anything directly.
      -->
      <overrides idref="com.google.AbstractClass" />

      <!-- We could move depends to a top-level construct -->
      <depends>
        <on idref="com.google.Foo.methodUsedInPrototypeSetup" />
      </depends>

      <!--
        After inlining, many things are related only through direct field
        accesses.
      -->
      <field id="com.google.Class.field" name="field" />

      <!--
        Methods may or may not be directly preserved in the JS ouput, but we
        still want to be able to talk about the chunk of code the JS originated
        from.
      -->
      <method id="com.google.Class.method" name="method">
        <depends>
          <on idref="com.google.Other.method" />
          <on idref="com.google.Other.field" />
          <on idref="com.google.ThirdClass" />
        </depends>
        <overrides idref="com.google.AbstractClass.method" />
      </method>
    </class>

    <!-- Prototype setup function -->
    <function id="com_google_Class" name="com_google_Class">
      <depends>
        <on idref="com.google.Class" />
      </depends>
    </function>
  </members>

  <stories>
    <!-- Stories have a counter-based ID -->
    <story id="story1">
      <!-- The primary list of mutations, following the parent chain -->
      <mutations>
        <mutation>Class seed and function prototype setup</mutation>
        <mutation>Frobnicator frobbed this function</mutation>

        <!-- Shows ancestor SourceInfos -->
        <ancestor>
          <mutation>Additional ancestor's mutation</mutation>
          <mutation>Additional ancestar's mutation</mutation>
        </ancestor>
        <ancestor>
          <mutation>Some other ancester's mutation</mutation>
        </ancestor>
      </mutations>

      <!--
        Shows references to member tags / functional units;
        getPrimaryCorrelations()
      -->
      <correlations>
        <by idref="com.google.Class" />
        <by idref="com.google.Class.method" />
        <by idref="com_google_Class" />
      </correlations>
    </story>
  </stories>

  <!--
    Big block of annotated JS, with nested story references OR we could just
    store the start-end ranges in the story nodes or some other map-like
    structure. Keeping the JS in the XML allows the XML reports to be
    self-contained and archived.
  -->
  <js>
    <story idref="story1">function com_google_Class() {}</story>
    <story idref="story2">
      1 + 1 +
      <story idref="story3">'randomness'</story>
    </story>
  </js>
</soyc>

Reply via email to