I turned on -remove-circulars by default for now so I could push other
changes.  ASDoc now appears to be working in js-release.  I am going to
push the js-release version to the website.

-Alex

On 2/17/18, 8:21 PM, "Alex Harui" <aha...@adobe.com.INVALID> wrote:

>
>
>On 2/17/18, 9:00 AM, "Gabe Harbs" <harbs.li...@gmail.com> wrote:
>
>>FWIW, none of the apps I built to date compiled correctly without
>>-remove-circulars.
>>
>>I’m not sure I completely understand the issue. Will your proposed
>>solution make minified apps fatter, or just the debug apps?
>
>Good question.  I think you might be right that the optimizer will kick
>out those classes anyway.  Those data classes will likely just be used to
>make the closure compiler happy and prevent renaming.
>>
>>Can you point me to where in the ASDoc code the problem is so In can
>>understand the problem better?
>
>ASDocModel manages the JSON results.  What is in the repo doesn't contain
>the ValueObjects I'm now working with, but I have a JSONReviver class that
>converts JSON to VOs on the fly.  The JSON works from registered
>[RemoteClasses] similar to how AMF works.  That means, if I have a class
>called ASDocClass that represents the ASDoc for a Class, there is no code
>my local version of ASDocModel that calls "new ASDocClass".  Instead, it
>just does:
>
>   var data:ASDocClass = app.reviver.parse(app.service.data) as
>ASDocClass;
>
>
>Then, when optimizing "data.members", if the compiler has already removed
>the goog.require('ASDocClass') then the Closure Compiler might rename
>members to "xy".
>
>The compiler currently tries to detect how you used a class in a file to
>decide whether it needs to be goog.require'd or not.  The current
>ASDocModel code also has an "@flexjsignorecoercion ASDocClass" so the JS
>output of the line above is:
>
>   var /** @type {ASDocClass} */ data =
>this.app.reviver.parse(this.app.service.data);
>
>Since this code can run without needing an ASDocClass definition, the
>current compiler removes the goog.require.  This helps reduce the number
>of circularities in Flex since simple parent/child or bead/strand always
>always has at least one class in the pair reference the other class as
>only a type.  For example:
>
>interface IParent {
>  var child:IChild;
>}
>
>interface IChild {
>  var parent:IParent;
>}
>
>The JS output is, more or less:
>
>goog.provide('IParent');
>goog.require('IChild');
>IParent = function();
>/** @type {IChild} */
>IParent.prototype.IChild;
>
>goog.provide('IChild');
>goog.require('IParent');
>IChild = function();
>/** @type {IParent} */
>IChild.prototype.IParent;
>
>
>Again, you can see that IParent doesn't have to exist at runtime to make
>IChild happy and vice versa.  But the Closure Compiler will see the
>goog.requires as a circularity, so that's why the current Royale Compiler
>found a way to remove them.  I don't know a way to detect that a
>goog.require is only used for type-checking and not later used to prevent
>renaming.  So the change I made was to turn off the pruning of
>goog.requires.  I think this will help prevent renaming in more places and
>make the js-release version work more often.  But now, every app will use
>IParent and IBead and result in circularities from Closure Compiler.
>
>The reason -remove-circulars is not on by default is that some folks
>wanted to be able to write apps that don't have circularities so they want
>Closure Compiler to complain so they can fix their code by breaking the
>circularities.  Also note that -remove-circulars also removes
>goog.requires and thus still presents a risk that closure compiler will
>rename something it shouldn't.  -remove-circulars chooses to remove
>goog.requires that have already been seen by a dependency walk starting
>with the main class.  The circularity removal code uses a different
>criteria for deciding whether to remove a goog.require.  It will remove a
>goog.require unless it sees it is used in a static variable initializer.
>
>So, there is a chance that as we continue to debug js-release versions we
>will see that we must break circularities the theoretical way instead of
>by using -remove-circulars.  We might just be getting lucky so far.
>
>I am devoting time to this now not only to get ASDoc running but to get a
>better understanding of why js-release versions don't work so we know what
>to look for when we debug really big apps some day.
>
>What I'm working on now is changing over some "public var foo" to
>getter/setters in order to address renaming issues for properties
>referenced by MXML code.  I'm probably going to add a warning to the
>compiler on every use of "public var" to help us sweep the code and
>convert to getter/setter to ward off renaming issues later.
>
>HTH,
>-Alex
>
>>
>>Harbs
>>
>>> On Feb 17, 2018, at 7:40 AM, Alex Harui <aha...@adobe.com.INVALID>
>>>wrote:
>>> 
>>> Hi Folks,
>>> 
>>> I've spent the last day or so trying to get ASDoc to run when minified.
>>> I
>>> created a JSON to ValueObjects utility which helped a lot.  It still
>>>isn't
>>> completely running, but it appears that we need to stop pruning classes
>>> that are only used in type annotations.  This will make most apps a
>>>little
>>> fatter, but also require all apps to use remove-circulars.
>>> 
>>> What do folks think about that?  The compiler used to prune classes
>>>from a
>>> file's goog.requires list that were never instantiated or type-checked
>>>in
>>> that file.  So, for ASDoc, the ASDocClass ValueObject that represents
>>>the
>>> JSON data for the ASDoc is never instantiated by the class that
>>>consumes
>>> it.  The instances are created by JSON.  The ASDocClass is only
>>>mentioned
>>> in JSDoc to declare some variable as being of type ASDoc.  That enabled
>>>us
>>> to remove that class from the requires list since that ASDocClass is
>>>never
>>> referenced by operational code.  Removing that goog.require helped
>>> eliminate circular goog.require references that the closure compiler
>>> disallows.  That kicked HTMLElementWrapper out of the app for example.
>>> But it appears that by removing that goog.require, the compiler didn't
>>> know that the ASDocClass properties were exported and it renamed some
>>>of
>>> them resulting in problems in js-release.  So by leaving more
>>> goog.requires in the code we get better support against renaming, but
>>>we
>>> also bring back more circularities and now even HelloWorld would need
>>> -remove-circulars.
>>> 
>>> An alternative that would allow a few more apps to not need
>>> remove-circulars is to modify a few of our examples and classes to
>>> eliminate circularities.  HelloWorld only has 3.  But 2 of them are
>>> IParent/IChild and IStrand/IBead.  It seems "right" to have IParent
>>> reference IChild and vice versa.  Same for IStrand and IBead.  I'm not
>>> quite sure what the answer is.  Maybe IParent can reference IChild, but
>>> IChild does not reference its IParent.  I guess you could make an
>>> IParentedChild interface with the parent property and concrete children
>>> implement both IChild and IParentedChild.  That seems wrong and overly
>>> complicated.
>>> 
>>> Yet another option, which is recommended by some folks in the Closure
>>> Compiler community but doesn't fit well with the ActionScript language
>>>is
>>> to define both IChild and IParent in the same file.  I do not want to
>>> spend the time modifying the compiler for that.  It might be practical
>>>to
>>> merge the files as part of the Ant and Maven builds.  But again, that
>>>will
>>> take time as well.
>>> 
>>> That said, requiring remove-circulars always doesn't seem quite right
>>> either.
>>> 
>>> Thoughts?
>>> -Alex
>>> 
>>> 
>>> 
>>
>

Reply via email to