You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Harbs <ha...@gmail.com> on 2016/12/06 07:12:06 UTC

Avoiding goog renaming

I created a swc library[1] which relies on some typedefs which I created using ActionScript[2].

This all works well when I debug. However, when I compile a release build, the “cep global” methods are being renamed and when executed, I get “function undefined” errors.

I’m not sure what I’m doing wrong. I could change the function calls to use bracket notation, which I expect would prevent goog from renaming them, but that seems like a work-around which should be unnecessary. Is the problem that I’m using ActionnScript rather than “extern” js files to compile the typedef swc?

Harbs

[1]https://github.com/unhurdle/cep-flexjs/tree/master/CEPTools
[2]https://github.com/unhurdle/cep-flexjs/tree/master/CEP6.1

Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/12/16, 12:28 AM, "Harbs" <ha...@gmail.com> wrote:

>Yup. It’s not working as I thought.
>
>I just did this:

What did NodeStreamParams.js and JSZip.js look like, and did you include
them as externs in a typedefs SWC and/or via compiler options?  The steps
required to do so are the steps I think the compiler could help you do
that I mentioned upthread.

-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
Yup. It’s not working as I thought.

I just did this:

NodeStreamParams.as:
package com.printui.utils
{
	public class NodeStreamParam
	{
        public function NodeStreamParam(type:String,streamFiles:Boolean)
        {
            this.type = type;
            this.streamFiles = streamFiles;
        }
		public static const NODE_BUFFER:String = "nodeBuffer";
		public var type:String;
		public var streamFiles:Boolean;
	}
}

JSZip.as:
package com.printui.utils
{
	import stream.Stream;

	public class JSZip
	{
		public function generateNodeStream(nsp:NodeStreamParam):Stream{
			return null;
		}
	}
    
}
Usage:
			var jszip:* = require("jszip");

			var zip:JSZip = new jszip();
			var name:String = folderToZip.name;
			recursiveAdd(folderToZip,zip,"");
			var promise:Promise = new Promise(function(resolve:*,reject:*):void{
				var zipFile:File = destinationFolder.resolvePath(folderToZip.name + ".zip");
				var zipStream:Stream  = zip.generateNodeStream(new NodeStreamParam(NodeStreamParam.NODE_BUFFER,true)).pipe(
				fs.createWriteStream(zipFile.nativePath));

Output:

;u(Kt,uT);fs=require('fs');require('stream');function vT(){}function wT(a,b){var c=new (require(Az));xT(a,c,e);return new Promise(function(d,f){var h=b.ba(a.name+Zc),k=c.Dr(new uT(zA,!0)).pipe(fs.createWriteStream(h.nativePath))

I have not tested this, but it’s pretty clear to me that this will not work.

new uT(zA,!0) should be fine because the constructor is defined like this:
function uT(a,b){this.type=a;this.streamFiles=b}

However, c looks totally borked:
var c=new (require(Az)). That’s ok because Az is defined as ‘aszip’.
However c.Dr(new uT(zA,!0)) is not gonna work because jszip does not have a Dr method.

Here’s the full contents of the non-minified function for reference:
  var /** @type {Function} */ __localFn0__ = function(resolve, reject) {
    var /** @type {Function} */ __localFn0__ = function() {
      console.log(zipFile.name + " written.");
      resolve(zipFile);
    }
    var /** @type {Function} */ __localFn1__ = function() {
      console.log("zip error");
      reject("error");
    }
    var /** @type {com.printui.utils.File} */ zipFile = destinationFolder.resolvePath(folderToZip.name + ".zip");
    var /** @type {stream.Stream} */ zipStream = zip.generateNodeStream(new com.printui.utils.NodeStreamParam(com.printui.utils.NodeStreamParam.NODE_BUFFER, true)).pipe(fs.createWriteStream(zipFile.nativePath));
    zipStream.on('finish', __localFn0__);
    zipStream.on('error', __localFn1__);
  }
  var /** @type {*} */ jszip = require("jszip");
  var /** @type {com.printui.utils.JSZip} */ zip = new jszip();
  var /** @type {string} */ name = folderToZip.name;
  com.printui.utils.FolderZipper.recursiveAdd(folderToZip, zip, "");
  var /** @type {Promise} */ promise = new Promise(__localFn0__);
  return promise;


On Dec 12, 2016, at 9:56 AM, Harbs <ha...@gmail.com> wrote:

> I thought I tried something similar and declaring the types did not help (i.e. the externs were not generated), but maybe I did something wrong.


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
I personally don’t like the convention to use comments. It feels more like a hack than a language feature. But it’s not a show-stopper.

I would vote for [Externs] or @externs rather than /*@externs*/

On Dec 14, 2016, at 1:19 AM, Alex Harui <ah...@adobe.com> wrote:

> As an ASDoc tag, so /** @externs */
> 
> On 12/13/16, 1:23 PM, "Harbs" <ha...@gmail.com> wrote:
> 
>> Do you mean /*@externs*/ or @externs (which is currently not valid code)?
>> 
>> On Dec 13, 2016, at 6:19 PM, Alex Harui <ah...@adobe.com> wrote:
>> 
>>> 
>>> 
>>> On 12/13/16, 12:48 AM, "Harbs" <ha...@gmail.com> wrote:
>>> 
>>>> What I’d really like to do would be to define a class like this:
>>>> 
>>>> package
>>>> {
>>>> 	import stream.Stream;
>>>> 
>>>>  [Extern]
>>>>  public class JSZip
>>>> 	{
>>>> 		public function generateNodeStream(nsp:NodeStreamParam):Stream{
>>>> 			return null;
>>>> 		}
>>>> 	}
>>>> 
>>>> }
>>>> And the compiler would know to generate externs from this class and it
>>>> should “just work”.
>>>> 
>>>> This would make it MUCH easier to create swc libraries of externs as
>>>> well.
>>> 
>>> File a JIRA.  Although I would much rather use @externs instead
>>> [Externs]
>>> 
>>> -Alex
>>> 
>> 
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.
As an ASDoc tag, so /** @externs */

On 12/13/16, 1:23 PM, "Harbs" <ha...@gmail.com> wrote:

>Do you mean /*@externs*/ or @externs (which is currently not valid code)?
>
>On Dec 13, 2016, at 6:19 PM, Alex Harui <ah...@adobe.com> wrote:
>
>> 
>> 
>> On 12/13/16, 12:48 AM, "Harbs" <ha...@gmail.com> wrote:
>> 
>>> What I’d really like to do would be to define a class like this:
>>> 
>>> package
>>> {
>>> 	import stream.Stream;
>>> 
>>>   [Extern]
>>>   public class JSZip
>>> 	{
>>> 		public function generateNodeStream(nsp:NodeStreamParam):Stream{
>>> 			return null;
>>> 		}
>>> 	}
>>> 
>>> }
>>> And the compiler would know to generate externs from this class and it
>>> should “just work”.
>>> 
>>> This would make it MUCH easier to create swc libraries of externs as
>>>well.
>> 
>> File a JIRA.  Although I would much rather use @externs instead
>>[Externs]
>> 
>> -Alex
>> 
>


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
Do you mean /*@externs*/ or @externs (which is currently not valid code)?

On Dec 13, 2016, at 6:19 PM, Alex Harui <ah...@adobe.com> wrote:

> 
> 
> On 12/13/16, 12:48 AM, "Harbs" <ha...@gmail.com> wrote:
> 
>> What I’d really like to do would be to define a class like this:
>> 
>> package
>> {
>> 	import stream.Stream;
>> 
>>   [Extern]
>>   public class JSZip
>> 	{
>> 		public function generateNodeStream(nsp:NodeStreamParam):Stream{
>> 			return null;
>> 		}
>> 	}
>> 
>> }
>> And the compiler would know to generate externs from this class and it
>> should “just work”.
>> 
>> This would make it MUCH easier to create swc libraries of externs as well.
> 
> File a JIRA.  Although I would much rather use @externs instead [Externs]
> 
> -Alex
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/13/16, 10:41 AM, "omuppi1@gmail.com on behalf of OmPrakash
Muppirala" <omuppi1@gmail.com on behalf of bigosmallm@gmail.com> wrote:

>(Possible unrelated to the current discussion)
>
>For what it's worth, Typescript is pushing the metadata (decorators)
>concept forward [1]
>Angular2 is fully utilizing this concept in the form of annotations [2]
>
>There is also a proposal to add metadata/decorators in Javascript directly
>[3]
>
>Looks like the industry is slowly starting to full on embracing the
>concepts introduced by Flex 3/4.  For example Angular 1 and 2 support
>dependency injection.  In the Flex world, Parsley, Robotlegs etc. easily
>added support for DI by utilizing the custom metadata support and runtime
>describeType (or its FlexJS equivalent)
>
>If we don't support custom metadata, it will make it very hard for 3rd
>party developers to add these kind of cool features.

That good to know.  FlexJS already supports what Flex users think of as
Metadata.

I think annotations are something different, and this thread about
@externs or [Externs] is about something more like annotations at act as
preprocessors that generate first-class data structure on the class.
Metadata is just additional data that requires a special API to access at
runtime.

I don't want to take on annotations in the compiler right now.  We have
plenty to do, and having a few optional ASDoc/JSDoc tags is the path of
least resistance for me.

-Alex

>
>[1] https://www.typescriptlang.org/docs/handbook/decorators.html
>[2] http://www.angulartypescript.com/angular-2-annotations/
>[3] https://github.com/wycats/javascript-decorators



Re: Avoiding goog renaming

Posted by OmPrakash Muppirala <bi...@gmail.com>.
(Possible unrelated to the current discussion)

For what it's worth, Typescript is pushing the metadata (decorators)
concept forward [1]
Angular2 is fully utilizing this concept in the form of annotations [2]

There is also a proposal to add metadata/decorators in Javascript directly
[3]

Looks like the industry is slowly starting to full on embracing the
concepts introduced by Flex 3/4.  For example Angular 1 and 2 support
dependency injection.  In the Flex world, Parsley, Robotlegs etc. easily
added support for DI by utilizing the custom metadata support and runtime
describeType (or its FlexJS equivalent)

If we don't support custom metadata, it will make it very hard for 3rd
party developers to add these kind of cool features.

[1] https://www.typescriptlang.org/docs/handbook/decorators.html
[2] http://www.angulartypescript.com/angular-2-annotations/
[3] https://github.com/wycats/javascript-decorators

On Tue, Dec 13, 2016 at 8:19 AM, Alex Harui <ah...@adobe.com> wrote:

>
>
> On 12/13/16, 12:48 AM, "Harbs" <ha...@gmail.com> wrote:
>
> >What I’d really like to do would be to define a class like this:
> >
> >package
> >{
> >       import stream.Stream;
> >
> >    [Extern]
> >    public class JSZip
> >       {
> >               public function generateNodeStream(nsp:
> NodeStreamParam):Stream{
> >                       return null;
> >               }
> >       }
> >
> >}
> >And the compiler would know to generate externs from this class and it
> >should “just work”.
> >
> >This would make it MUCH easier to create swc libraries of externs as well.
>
> File a JIRA.  Although I would much rather use @externs instead [Externs]
>
> -Alex
>
>

Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/13/16, 12:48 AM, "Harbs" <ha...@gmail.com> wrote:

>What I’d really like to do would be to define a class like this:
>
>package
>{
>	import stream.Stream;
>
>    [Extern]
>    public class JSZip
>	{
>		public function generateNodeStream(nsp:NodeStreamParam):Stream{
>			return null;
>		}
>	}
>    
>}
>And the compiler would know to generate externs from this class and it
>should “just work”.
>
>This would make it MUCH easier to create swc libraries of externs as well.

File a JIRA.  Although I would much rather use @externs instead [Externs]

-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
What I’d really like to do would be to define a class like this:

package
{
	import stream.Stream;

    [Extern]
    public class JSZip
	{
		public function generateNodeStream(nsp:NodeStreamParam):Stream{
			return null;
		}
	}
    
}
And the compiler would know to generate externs from this class and it should “just work”.

This would make it MUCH easier to create swc libraries of externs as well.

On Dec 12, 2016, at 6:37 PM, Josh Tynjala <jo...@gmail.com> wrote:

> Yes, it should be that simple. If we could make the compc compiler able to
> (optionally) generate externs from ActionScript files somehow, that would
> make using third-party libraries easier. I think most developers would be
> more comfortable writing a few classes in ActionScript for a third-party
> library, and then running compc with some kind of --externs=true (or maybe
> --typedef=true) option that generates externs in the SWC.
> 
> - Josh
> 
> On Mon, Dec 12, 2016 at 8:01 AM, Alex Harui <ah...@adobe.com> wrote:
> 
>> 
>> 
>> On 12/11/16, 11:56 PM, "Harbs" <ha...@gmail.com> wrote:
>> 
>>> I thought I tried something similar and declaring the types did not help
>>> (i.e. the externs were not generated), but maybe I did something wrong.
>>> 
>>> I’ll try again.
>>> 
>>>> The reason to create an AS API for a 3rd party library is more than just
>>>> preventing renaming.  It is to allow the compiler to check your code so
>>>> you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
>>>> "{typ: "nodbufr"}.  If you don't want to use strong typing, why use
>>>> FlexJS
>>>> in the first place?
>>> 
>>> In general I agree, but if you’re just doing simple with some third party
>>> library, it should be possible to just copy some JS code which works,
>>> make minor changes and be good to go.
>>> 
>>> I’m bringing this up, because it’s been a pain point for me in my current
>>> project.
>> 
>> I'm not sure whether it is truly possible to grab any JS, insert it in AS
>> and compile it so that it will survive renaming without outputting every
>> property as quoted values, which effectively turns off all renaming.  And
>> then we'd get complaints about total size.  And the compiler wouldn't
>> catch nearly enough stuff.  IMO, the productivity advantage of FlexJS is
>> better served by an eco-system of typedefs for third party libraries.  The
>> creation of the typedefs should be as "simple" as creating the two AS
>> files.
>> 
>> My 2 cents,
>> -Alex
>> 
>> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/12/16, 9:50 AM, "Josh Tynjala" <jo...@gmail.com> wrote:

>Off the top of my head, [Frame] and [SWF] are also used to change compiler
>output. I can see how it's a little weird that some metadata is used at
>compile-time and some at runtime, but as a developer, I think it's really
>useful.

I forgot about those two, but IMO, they also do not change the AST -> ABC
generation of the compiler; they are linker directives!  There was no AS
syntax to provide that information.

Anyway, we'll see if someone comes up with a better idea, then we'll
explore this further.
-Alex


Re: Avoiding goog renaming

Posted by Josh Tynjala <jo...@gmail.com>.
Off the top of my head, [Frame] and [SWF] are also used to change compiler
output. I can see how it's a little weird that some metadata is used at
compile-time and some at runtime, but as a developer, I think it's really
useful.

Anyway, if it's an asdoc tag that FalconJX will preserve to configure the
Closure compiler, it seems like a reasonable approach to me.

- Josh

On Mon, Dec 12, 2016 at 9:39 AM, Alex Harui <ah...@adobe.com> wrote:

>
>
> On 12/12/16, 9:13 AM, "Josh Tynjala" <jo...@gmail.com> wrote:
>
> >Yeah, if we could make it work without creating a SWC, I think that would
> >be ideal. The fewer steps it takes to add third-party libraries to a
> >project, the better.
> >
> >I notice that you seem to have a preference for custom ASDoc tags, like
> >@externs or @flexjsignorecoercion for changing the compiler's behavior.
> >Why
> >not metadata, like [Extern] or [IgnoreCoercion], instead? Personally,
> >using
> >ASDoc tags for something other than documentation doesn't feel quite right
> >to me. Metadata has long been used to pass extra information to the
> >compiler, though. Plus, if something needs more complex configuration,
> >metadata is more like setting properties on an object:
> >[Metadata(option1="true",option2="hello world")]. I've been meaning to
> ask
> >you about this for a while, but I kept forgetting.
>
> I tend to offer up custom ASDoc tags as compiler directives because Google
> Closure Compiler uses a similar JSDoc tag set in a similar way.  It
> controls the output and doesn't always need to be kept around after the
> compile.
>
> IIRC, the compiler and runtime teams thought Metadata was an overused
> mess.  It has several inconsistent uses.  I think only [Bindable] actually
> is a compiler directive that alters the compiler output.  Other metadata
> is used by MXML and IDEs to declare events and styles but doesn't alter
> the byte code of the class it annotates other than being stored in the SWC
> and deleted from the final SWF.  All other metadata, including Bindable,
> are annotations stored in the code for use by the code, where it is
> hard.slow to access in Flash.
>
> @externs could be [Externs] since it is needed after compile time, but I
> can't think of a good reason to store it in the byte code.  It isn't
> needed by MXML, IDEs, or at runtime, and has to appear in the JSDoc output
> so the Google Closure Compiler can use it.
>
> Of course, I could be convinced otherwise...
> -Alex
>
>

Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/12/16, 9:13 AM, "Josh Tynjala" <jo...@gmail.com> wrote:

>Yeah, if we could make it work without creating a SWC, I think that would
>be ideal. The fewer steps it takes to add third-party libraries to a
>project, the better.
>
>I notice that you seem to have a preference for custom ASDoc tags, like
>@externs or @flexjsignorecoercion for changing the compiler's behavior.
>Why
>not metadata, like [Extern] or [IgnoreCoercion], instead? Personally,
>using
>ASDoc tags for something other than documentation doesn't feel quite right
>to me. Metadata has long been used to pass extra information to the
>compiler, though. Plus, if something needs more complex configuration,
>metadata is more like setting properties on an object:
>[Metadata(option1="true",option2="hello world")]. I've been meaning to ask
>you about this for a while, but I kept forgetting.

I tend to offer up custom ASDoc tags as compiler directives because Google
Closure Compiler uses a similar JSDoc tag set in a similar way.  It
controls the output and doesn't always need to be kept around after the
compile.

IIRC, the compiler and runtime teams thought Metadata was an overused
mess.  It has several inconsistent uses.  I think only [Bindable] actually
is a compiler directive that alters the compiler output.  Other metadata
is used by MXML and IDEs to declare events and styles but doesn't alter
the byte code of the class it annotates other than being stored in the SWC
and deleted from the final SWF.  All other metadata, including Bindable,
are annotations stored in the code for use by the code, where it is
hard.slow to access in Flash.

@externs could be [Externs] since it is needed after compile time, but I
can't think of a good reason to store it in the byte code.  It isn't
needed by MXML, IDEs, or at runtime, and has to appear in the JSDoc output
so the Google Closure Compiler can use it.

Of course, I could be convinced otherwise...
-Alex


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/13/16, 12:44 AM, "Harbs" <ha...@gmail.com> wrote:

>I’m in the same boat.
>
>I think metadata tags feel much better as well.

Well, IMO, metadata is additional byte code or JS output.  There is no
reason for @externs or @flexjsignorecoercion to be in the output.  In
fact, if we used metadata for these directives, I think we'd be
introducing a new class of metadata, tags that are stripped out by COMPC.
AFAICT, COMPC puts all metadata in the byte code, the only filtering is
done by the SWF linker.

Further, for @externs, it needs to end up in the JSDoc for the JS output
for Google Closure Compiler so if we use [Extern] instead, it would
introduce the first time metadata ends up as a JSDoc tag and not as
output.  IMO, using something other than metadata as a compiler output
directive would be better than overloading metadata yet again.

>
>If tools can help with validating metadata tags it would be even better.

I think this was one of the reasons the compiler team didn't like
metadata.  There is no official grammar for it.  How would you specify
correctness?  With Metadata on the Metadata?  The other thing I don't like
about metadata is that ASDoc annotates certain kinds of metadata like
[Event], but not [Bindable].

My 2 cents,
-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
I’m in the same boat.

I think metadata tags feel much better as well.

If tools can help with validating metadata tags it would be even better.

On Dec 12, 2016, at 7:13 PM, Josh Tynjala <jo...@gmail.com> wrote:

> I notice that you seem to have a preference for custom ASDoc tags, like
> @externs or @flexjsignorecoercion for changing the compiler's behavior. Why
> not metadata, like [Extern] or [IgnoreCoercion], instead? Personally, using
> ASDoc tags for something other than documentation doesn't feel quite right
> to me. Metadata has long been used to pass extra information to the
> compiler, though. Plus, if something needs more complex configuration,
> metadata is more like setting properties on an object:
> [Metadata(option1="true",option2="hello world")]. I've been meaning to ask
> you about this for a while, but I kept forgetting.


Re: Avoiding goog renaming

Posted by Josh Tynjala <jo...@gmail.com>.
Yeah, if we could make it work without creating a SWC, I think that would
be ideal. The fewer steps it takes to add third-party libraries to a
project, the better.

I notice that you seem to have a preference for custom ASDoc tags, like
@externs or @flexjsignorecoercion for changing the compiler's behavior. Why
not metadata, like [Extern] or [IgnoreCoercion], instead? Personally, using
ASDoc tags for something other than documentation doesn't feel quite right
to me. Metadata has long been used to pass extra information to the
compiler, though. Plus, if something needs more complex configuration,
metadata is more like setting properties on an object:
[Metadata(option1="true",option2="hello world")]. I've been meaning to ask
you about this for a while, but I kept forgetting.

- Josh

On Mon, Dec 12, 2016 at 8:46 AM, Alex Harui <ah...@adobe.com> wrote:

>
>
> On 12/12/16, 8:37 AM, "Josh Tynjala" <jo...@gmail.com> wrote:
>
> >I think most developers would be
> >more comfortable writing a few classes in ActionScript for a third-party
> >library,
>
> Agreed, because not only do you get type-checking, but you also get to
> "bullet-proof" the API.  For these JS libraries that you pass a plain
> object to that has to have certain properties with certain values, you can
> define a type for it with appropriate defaults and constants so you don't
> make typos, don't pass the wrong thing into the wrong method, etc.
>
> So there are two ideas, not mutually exclusive, on the table right now:
> 1) Add an externs output type that only COMPJS would recognize.  It would
> skip the goog.provide and goog.requires output and maybe automatically
> package any .JS files into a SWC.
> 2) Allow an @externs ASDoc annotation that would cause the compiler to use
> the output JS file as an extern.  Then you don't need to actually build a
> SWC.  You would be designating certain files in your project's source code
> as an extern.  IMO, we want to encourage folks to build out re-usable SWCs
> to be shared with the community, but this option might be the lowest
> barrier for some, especially if you have to hook into some in-house JS
> library.
>
> Other ideas are welcome.
>
> -Alex
>
>

Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/12/16, 8:37 AM, "Josh Tynjala" <jo...@gmail.com> wrote:

>I think most developers would be
>more comfortable writing a few classes in ActionScript for a third-party
>library,

Agreed, because not only do you get type-checking, but you also get to
"bullet-proof" the API.  For these JS libraries that you pass a plain
object to that has to have certain properties with certain values, you can
define a type for it with appropriate defaults and constants so you don't
make typos, don't pass the wrong thing into the wrong method, etc.

So there are two ideas, not mutually exclusive, on the table right now:
1) Add an externs output type that only COMPJS would recognize.  It would
skip the goog.provide and goog.requires output and maybe automatically
package any .JS files into a SWC.
2) Allow an @externs ASDoc annotation that would cause the compiler to use
the output JS file as an extern.  Then you don't need to actually build a
SWC.  You would be designating certain files in your project's source code
as an extern.  IMO, we want to encourage folks to build out re-usable SWCs
to be shared with the community, but this option might be the lowest
barrier for some, especially if you have to hook into some in-house JS
library.

Other ideas are welcome.

-Alex


Re: Avoiding goog renaming

Posted by Josh Tynjala <jo...@gmail.com>.
Yes, it should be that simple. If we could make the compc compiler able to
(optionally) generate externs from ActionScript files somehow, that would
make using third-party libraries easier. I think most developers would be
more comfortable writing a few classes in ActionScript for a third-party
library, and then running compc with some kind of --externs=true (or maybe
--typedef=true) option that generates externs in the SWC.

- Josh

On Mon, Dec 12, 2016 at 8:01 AM, Alex Harui <ah...@adobe.com> wrote:

>
>
> On 12/11/16, 11:56 PM, "Harbs" <ha...@gmail.com> wrote:
>
> >I thought I tried something similar and declaring the types did not help
> >(i.e. the externs were not generated), but maybe I did something wrong.
> >
> >I’ll try again.
> >
> >> The reason to create an AS API for a 3rd party library is more than just
> >> preventing renaming.  It is to allow the compiler to check your code so
> >> you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
> >> "{typ: "nodbufr"}.  If you don't want to use strong typing, why use
> >>FlexJS
> >> in the first place?
> >
> >In general I agree, but if you’re just doing simple with some third party
> >library, it should be possible to just copy some JS code which works,
> >make minor changes and be good to go.
> >
> >I’m bringing this up, because it’s been a pain point for me in my current
> >project.
>
> I'm not sure whether it is truly possible to grab any JS, insert it in AS
> and compile it so that it will survive renaming without outputting every
> property as quoted values, which effectively turns off all renaming.  And
> then we'd get complaints about total size.  And the compiler wouldn't
> catch nearly enough stuff.  IMO, the productivity advantage of FlexJS is
> better served by an eco-system of typedefs for third party libraries.  The
> creation of the typedefs should be as "simple" as creating the two AS
> files.
>
> My 2 cents,
> -Alex
>
>

Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/11/16, 11:56 PM, "Harbs" <ha...@gmail.com> wrote:

>I thought I tried something similar and declaring the types did not help
>(i.e. the externs were not generated), but maybe I did something wrong.
>
>I’ll try again.
>
>> The reason to create an AS API for a 3rd party library is more than just
>> preventing renaming.  It is to allow the compiler to check your code so
>> you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
>> "{typ: "nodbufr"}.  If you don't want to use strong typing, why use
>>FlexJS
>> in the first place?
>
>In general I agree, but if you’re just doing simple with some third party
>library, it should be possible to just copy some JS code which works,
>make minor changes and be good to go.
>
>I’m bringing this up, because it’s been a pain point for me in my current
>project.

I'm not sure whether it is truly possible to grab any JS, insert it in AS
and compile it so that it will survive renaming without outputting every
property as quoted values, which effectively turns off all renaming.  And
then we'd get complaints about total size.  And the compiler wouldn't
catch nearly enough stuff.  IMO, the productivity advantage of FlexJS is
better served by an eco-system of typedefs for third party libraries.  The
creation of the typedefs should be as "simple" as creating the two AS
files.

My 2 cents,
-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
I thought I tried something similar and declaring the types did not help (i.e. the externs were not generated), but maybe I did something wrong.

I’ll try again.

> The reason to create an AS API for a 3rd party library is more than just
> preventing renaming.  It is to allow the compiler to check your code so
> you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
> "{typ: "nodbufr"}.  If you don't want to use strong typing, why use FlexJS
> in the first place?

In general I agree, but if you’re just doing simple with some third party library, it should be possible to just copy some JS code which works, make minor changes and be good to go.

I’m bringing this up, because it’s been a pain point for me in my current project.

On Dec 12, 2016, at 9:48 AM, Alex Harui <ah...@adobe.com> wrote:

> 
> 
> On 12/11/16, 10:48 PM, "Harbs" <ha...@gmail.com> wrote:
> 
>> 
>> On Dec 12, 2016, at 7:52 AM, Alex Harui <ah...@adobe.com> wrote:
>> 
>>> 
>>> 
>>> On 12/11/16, 10:28 AM, "Harbs" <ha...@gmail.com> wrote:
>>> 
>>>> I DO want renaming.
>>>> 
>>>> My point is that we really need to have an option to disable renaming
>>>> in
>>>> specific places in the code.
>>>> 
>>>> My example is a very classic case when interop between outside code is
>>>> going to cause problems. I CAN’T use class definitions everywhere.
>>>> There
>>>> needs to be a method to properly deal with that.
>>>> 
>>>> I don’t have types for JSZip, and create extern files for every use of
>>>> third party libraries is not a practical option.
>>> 
>>> I don't understand why you can't use class definitions or don't have
>>> types.  The whole point of the externs for third-party libraries is to
>>> have an AS API for a external JS API.  Create a JSZip class with a
>>> generateNodeStream function.  Generate Value Objects for their objects
>>> that are passed in as objects.  In the final JS, everything is plain
>>> objects.
>>> 
>>> Public class NodeStreamParam
>>> {
>>> Public const NODE_BUFFER:String = "nodeBuffer";
>>> Public var type:String;
>>> Public var streamFiles:Boolean;
>>> }
>>> 
>>> Public class JSZip
>>> {
>>> Public function generateNodeStream(nsp:NodeStreamParam):NodeStream
>>> {
>>>   return null;
>>> }
>>> }
>>> 
>> 
>> AFAIU, this will not prevent renaming unless there is a extern js file
>> for the Google Compiler — which I don’t have.
> 
> If you use FalconJX to compile that AS you will have your externs file.
> 
>> 
>> Also, there’s lots of APIs that take object literals. Requiring to
>> declare classes for each of these raise the overhead for simple
>> implementations. A lot of folks will be copying code off Stack Overflow
>> or wherever. Rather than it just “working”, they would have a lot of
>> extra overhead. Making that a REQUIREMENT is something I think we should
>> avoid.
> 
> It is only a requirement if you want to use ADVANCED_OPTIMIZATIONS, which
> folks don't have to use.  And you'd have to use the same techniques
> (externs, quotes) to prevent renaming.
> 
> The reason to create an AS API for a 3rd party library is more than just
> preventing renaming.  It is to allow the compiler to check your code so
> you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
> "{typ: "nodbufr"}.  If you don't want to use strong typing, why use FlexJS
> in the first place?
> 
>> 
>>> 
>>>> 
>>>> If you read my email you will see I already stated that using quoted
>>>> strings is the work-around here, but IMO, it’s not a solution to
>>>> require
>>>> client code to always do that.
>>> 
>>> I'm not clear any sort of annotation would be any easier for the person
>>> writing the code.  You have to remember when to use the annotation or
>>> remember to use the quotes.  There might be a way to make it easier to
>>> generate the externs for a third party library. If you were to have .AS
>>> files for JSZip and NodeStreamParam like I do above, maybe we can teach
>>> the compiler to look for an @externs and treat the file as an extern.
>>> Similarly, the compiler might be able to package such a file in the SWC
>>> differently than it does now.
>> 
>> I like this idea for generating externs, but for my examples I was
>> thinking of something simpler:
>> 
>> 1. instead of:
>> var zip:* = new JSZip();
>> or
>> var zip:Object = new JSZip();
>> 
>> we could enable:
>> var zip:Extern = new JSZip();
>> 
>> and the compiler would know that “Extern” is of type Object, but all
>> methods and properties should have string bracket notation instead of dot
>> notation.
> 
> I think that would slow down the compiler.  It would have to test every
> output against the type of object.  We could do it if enough folks ask,
> but IMO, externs and strong-typing will save you lots of other mistakes.
> 
>> 
>> 2. We should have a compiler option (on by default) where all untyped
>> object literals be written with quoted string literals. So:
>> var obj:Object = {foo:true,baz:10};
>> could be rewritten, but
>> var obj:* = {foo:true,baz:10};
>> would compile as:
>> var obj = {“foo":true,”baz":10};
>> and the names would be preserved by the compiler
>> Similarly:
>> 
>> myThingy.doSomething({foo:true,baz:10})
>> 
>> would compile as:
>> myThingy.doSomething({“foo":true,”baz":10})
> 
> Also possible, but as soon as you turn the option off, you'll be wishing
> for those externs and class definitions.
> 
> -Alex


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/11/16, 10:48 PM, "Harbs" <ha...@gmail.com> wrote:

>
>On Dec 12, 2016, at 7:52 AM, Alex Harui <ah...@adobe.com> wrote:
>
>> 
>> 
>> On 12/11/16, 10:28 AM, "Harbs" <ha...@gmail.com> wrote:
>> 
>>> I DO want renaming.
>>> 
>>> My point is that we really need to have an option to disable renaming
>>>in
>>> specific places in the code.
>>> 
>>> My example is a very classic case when interop between outside code is
>>> going to cause problems. I CAN’T use class definitions everywhere.
>>>There
>>> needs to be a method to properly deal with that.
>>> 
>>> I don’t have types for JSZip, and create extern files for every use of
>>> third party libraries is not a practical option.
>> 
>> I don't understand why you can't use class definitions or don't have
>> types.  The whole point of the externs for third-party libraries is to
>> have an AS API for a external JS API.  Create a JSZip class with a
>> generateNodeStream function.  Generate Value Objects for their objects
>> that are passed in as objects.  In the final JS, everything is plain
>> objects.
>> 
>> Public class NodeStreamParam
>> {
>>  Public const NODE_BUFFER:String = "nodeBuffer";
>>  Public var type:String;
>>  Public var streamFiles:Boolean;
>> }
>> 
>> Public class JSZip
>> {
>>  Public function generateNodeStream(nsp:NodeStreamParam):NodeStream
>>  {
>>    return null;
>>  }
>> }
>> 
>
>AFAIU, this will not prevent renaming unless there is a extern js file
>for the Google Compiler — which I don’t have.

If you use FalconJX to compile that AS you will have your externs file.

>
>Also, there’s lots of APIs that take object literals. Requiring to
>declare classes for each of these raise the overhead for simple
>implementations. A lot of folks will be copying code off Stack Overflow
>or wherever. Rather than it just “working”, they would have a lot of
>extra overhead. Making that a REQUIREMENT is something I think we should
>avoid.

It is only a requirement if you want to use ADVANCED_OPTIMIZATIONS, which
folks don't have to use.  And you'd have to use the same techniques
(externs, quotes) to prevent renaming.

The reason to create an AS API for a 3rd party library is more than just
preventing renaming.  It is to allow the compiler to check your code so
you don't also get hosed by typing zip["fnerateNdeStrm"]  Or pass it
"{typ: "nodbufr"}.  If you don't want to use strong typing, why use FlexJS
in the first place?

>
>> 
>>> 
>>> If you read my email you will see I already stated that using quoted
>>> strings is the work-around here, but IMO, it’s not a solution to
>>>require
>>> client code to always do that.
>> 
>> I'm not clear any sort of annotation would be any easier for the person
>> writing the code.  You have to remember when to use the annotation or
>> remember to use the quotes.  There might be a way to make it easier to
>> generate the externs for a third party library. If you were to have .AS
>> files for JSZip and NodeStreamParam like I do above, maybe we can teach
>> the compiler to look for an @externs and treat the file as an extern.
>> Similarly, the compiler might be able to package such a file in the SWC
>> differently than it does now.
>
>I like this idea for generating externs, but for my examples I was
>thinking of something simpler:
>
>1. instead of:
>var zip:* = new JSZip();
>or
>var zip:Object = new JSZip();
>
>we could enable:
>var zip:Extern = new JSZip();
>
>and the compiler would know that “Extern” is of type Object, but all
>methods and properties should have string bracket notation instead of dot
>notation.

I think that would slow down the compiler.  It would have to test every
output against the type of object.  We could do it if enough folks ask,
but IMO, externs and strong-typing will save you lots of other mistakes.

>
>2. We should have a compiler option (on by default) where all untyped
>object literals be written with quoted string literals. So:
>var obj:Object = {foo:true,baz:10};
>could be rewritten, but
>var obj:* = {foo:true,baz:10};
>would compile as:
>var obj = {“foo":true,”baz":10};
>and the names would be preserved by the compiler
>Similarly:
>
>myThingy.doSomething({foo:true,baz:10})
>
>would compile as:
>myThingy.doSomething({“foo":true,”baz":10})

Also possible, but as soon as you turn the option off, you'll be wishing
for those externs and class definitions.

-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
On Dec 12, 2016, at 7:52 AM, Alex Harui <ah...@adobe.com> wrote:

> 
> 
> On 12/11/16, 10:28 AM, "Harbs" <ha...@gmail.com> wrote:
> 
>> I DO want renaming.
>> 
>> My point is that we really need to have an option to disable renaming in
>> specific places in the code.
>> 
>> My example is a very classic case when interop between outside code is
>> going to cause problems. I CAN’T use class definitions everywhere. There
>> needs to be a method to properly deal with that.
>> 
>> I don’t have types for JSZip, and create extern files for every use of
>> third party libraries is not a practical option.
> 
> I don't understand why you can't use class definitions or don't have
> types.  The whole point of the externs for third-party libraries is to
> have an AS API for a external JS API.  Create a JSZip class with a
> generateNodeStream function.  Generate Value Objects for their objects
> that are passed in as objects.  In the final JS, everything is plain
> objects.
> 
> Public class NodeStreamParam
> {
>  Public const NODE_BUFFER:String = "nodeBuffer";
>  Public var type:String;
>  Public var streamFiles:Boolean;
> }
> 
> Public class JSZip
> {
>  Public function generateNodeStream(nsp:NodeStreamParam):NodeStream
>  {
>    return null;
>  }
> }
> 

AFAIU, this will not prevent renaming unless there is a extern js file for the Google Compiler — which I don’t have.

Also, there’s lots of APIs that take object literals. Requiring to declare classes for each of these raise the overhead for simple implementations. A lot of folks will be copying code off Stack Overflow or wherever. Rather than it just “working”, they would have a lot of extra overhead. Making that a REQUIREMENT is something I think we should avoid.

> 
>> 
>> If you read my email you will see I already stated that using quoted
>> strings is the work-around here, but IMO, it’s not a solution to require
>> client code to always do that.
> 
> I'm not clear any sort of annotation would be any easier for the person
> writing the code.  You have to remember when to use the annotation or
> remember to use the quotes.  There might be a way to make it easier to
> generate the externs for a third party library. If you were to have .AS
> files for JSZip and NodeStreamParam like I do above, maybe we can teach
> the compiler to look for an @externs and treat the file as an extern.
> Similarly, the compiler might be able to package such a file in the SWC
> differently than it does now.

I like this idea for generating externs, but for my examples I was thinking of something simpler:

1. instead of:
var zip:* = new JSZip();
or
var zip:Object = new JSZip();

we could enable:
var zip:Extern = new JSZip();

and the compiler would know that “Extern” is of type Object, but all methods and properties should have string bracket notation instead of dot notation.

2. We should have a compiler option (on by default) where all untyped object literals be written with quoted string literals. So:
var obj:Object = {foo:true,baz:10};
could be rewritten, but
var obj:* = {foo:true,baz:10};
would compile as:
var obj = {“foo":true,”baz":10};
and the names would be preserved by the compiler
Similarly:

myThingy.doSomething({foo:true,baz:10})

would compile as:
myThingy.doSomething({“foo":true,”baz":10})

> Thoughts?
> -Alex
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/11/16, 10:28 AM, "Harbs" <ha...@gmail.com> wrote:

>I DO want renaming.
>
>My point is that we really need to have an option to disable renaming in
>specific places in the code.
>
>My example is a very classic case when interop between outside code is
>going to cause problems. I CAN’T use class definitions everywhere. There
>needs to be a method to properly deal with that.
>
>I don’t have types for JSZip, and create extern files for every use of
>third party libraries is not a practical option.

I don't understand why you can't use class definitions or don't have
types.  The whole point of the externs for third-party libraries is to
have an AS API for a external JS API.  Create a JSZip class with a
generateNodeStream function.  Generate Value Objects for their objects
that are passed in as objects.  In the final JS, everything is plain
objects.

Public class NodeStreamParam
{
  Public const NODE_BUFFER:String = "nodeBuffer";
  Public var type:String;
  Public var streamFiles:Boolean;
}

Public class JSZip
{
  Public function generateNodeStream(nsp:NodeStreamParam):NodeStream
  {
    return null;
  }
}


>
>If you read my email you will see I already stated that using quoted
>strings is the work-around here, but IMO, it’s not a solution to require
>client code to always do that.

I'm not clear any sort of annotation would be any easier for the person
writing the code.  You have to remember when to use the annotation or
remember to use the quotes.  There might be a way to make it easier to
generate the externs for a third party library. If you were to have .AS
files for JSZip and NodeStreamParam like I do above, maybe we can teach
the compiler to look for an @externs and treat the file as an extern.
Similarly, the compiler might be able to package such a file in the SWC
differently than it does now.

Thoughts?
-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
I DO want renaming.

My point is that we really need to have an option to disable renaming in specific places in the code.

My example is a very classic case when interop between outside code is going to cause problems. I CAN’T use class definitions everywhere. There needs to be a method to properly deal with that.

I don’t have types for JSZip, and create extern files for every use of third party libraries is not a practical option.

If you read my email you will see I already stated that using quoted strings is the work-around here, but IMO, it’s not a solution to require client code to always do that.

On Dec 11, 2016, at 5:04 PM, Alex Harui <ah...@adobe.com> wrote:

> There is a compiler option to turn off renaming in the release build if
> you don't care about size.
> 
> IMO, use of * and plain Object is going to result in renaming issues.  Use
> class definitions everywhere.  I've mentioned in the past about a compiler
> warning on use of * and Object to help.  For Object you might also be able
> to use JSON quoted keys.
> 
> HTH,
> -Ales
> 
> On 12/11/16, 2:14 AM, "Harbs" <ha...@gmail.com> wrote:
> 
>> I’ve been spending WAY too much time dealing with goog renaming.
>> 
>> I have a good example of the kind of issues I’ve been dealing with. I
>> think this is an area where Falcon needs to do a better job.
>> 
>> I have some code which looks like this:
>> 
>> 			var JSZip:* = require("jszip");
>> 
>> 			var zip:* = new JSZip();
>> 			var name:String = folderToZip.name;
>> 			recursiveAdd(folderToZip,zip,"");
>> 			var promise:Promise = new Promise(function(resolve:*,reject:*):void{
>> 				var zipFile:File = destinationFolder.resolvePath(folderToZip.name +
>> ".zip");
>> 				var zipStream:Stream  = zip.generateNodeStream(
>> 				{type:'nodebuffer',streamFiles:true}).pipe(
>> 				fs.createWriteStream(zipFile.nativePath));
>> 
>> 				zipStream.on('finish', function ():* {
>>   				// JSZip generates a readable stream with a "end" event,
>>   				// but is piped here in a writable stream which emits a "finish"
>> event.
>>  		 			console.log(zipFile.name + " written.");
>> 						resolve(zipFile);
>> 				});
>> 				zipStream.on('error',function():void{
>> 					console.log("zip error");
>> 					reject("error");
>> 				})
>> 			});
>> 			return promise;
>> 
>> jszip is a Node module I’m using with require().
>> 
>> This code works perfectly in a debug build of my app.
>> 
>> When I run a release build I get an “undefined function” error.
>> 
>> The problematic code is here:
>> 				var zipStream:Stream  = zip.generateNodeStream(
>> 				{type:'nodebuffer',streamFiles:true}).pipe(
>> 				fs.createWriteStream(zipFile.nativePath));
>> 
>> The code gets minified to this:
>> 
>> return new Promise(function(d,f){var
>> h=b.ba(a.name+Zc),k=c.Br({type:yA,Vr:!0}).pipe(fs.createWriteStream(h.nati
>> vePath));k.on(Nw,function(){console.log(h.name+ib);d(h)});k.on(vw,function
>> (){console.log(hI);f(vw)
>> 
>> This is broken on multiple fronts:
>> 1. zip. zip.generateNodeStream is renamed to c.Br. Br is quite obviously
>> not defined.
>> 2. streamFiles is renamed to Vr, so the wrong options are being passed
>> into jszip. I have no idea why streamFiles is being renamed, but type is
>> not.
>> 
>> To fix this you need to do something like this:
>> 
>> 				var zipStream:Stream  = zip["generateNodeStream"](
>> 				{"type":'nodebuffer',"streamFiles":true})["pipe"](
>> 				fs.createWriteStream(zipFile.nativePath));
>> 
>> Which generates:
>> return new Promise(function(d,f){var
>> h=b.ba(a.name+Zc),k=c.generateNodeStream({type:yA,streamFiles:!0}).pipe(fs
>> .createWriteStream(h.nativePath));k.on(Nw,function(){console.log(h.name+ib
>> );d(h)});k.on(vw,function(){console.log(hI);f(vw)})}
>> 
>> I also have no idea why nativePath is not renamed. It’s a property of a
>> class which I defined. It seems like it would be a good candidate for
>> renaming.
>> 
>> We need some kind of annotation in ActionScript code to enable output of
>> annotations for the Google Compiler to know that it’s not okay to rename
>> properties of the objects. I’ve had this problem with object literals
>> that are being sent as well as accessing properties and methods of
>> external objects.
>> 
>> Having manually use bracket notation instead of dot notation is error
>> prone. It would be much better to have Falcon automatically change the
>> notations or annotate the code in such a way that goog does not rename
>> them.
>> 
>> On Dec 6, 2016, at 6:02 PM, Alex Harui <ah...@adobe.com> wrote:
>> 
>>> 
>>> 
>>> On 12/5/16, 11:47 PM, "Harbs" <ha...@gmail.com> wrote:
>>> 
>>>> OK. I guess I’ll rework the definitions into extern js files when I
>>>> have
>>>> time.
>>> 
>>> In theory, if you use FalconJX to cross-compile those AS files, you
>>> should
>>> get the right set of JS files to stick a folder called externs (instead
>>> of
>>> js/out).  The build scripts and settings should be almost the same as
>>> how
>>> we build the framework SWCs.
>>> 
>>> HTH,
>>> -Alex
>>> 
>> 
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.
There is a compiler option to turn off renaming in the release build if
you don't care about size.

IMO, use of * and plain Object is going to result in renaming issues.  Use
class definitions everywhere.  I've mentioned in the past about a compiler
warning on use of * and Object to help.  For Object you might also be able
to use JSON quoted keys.

HTH,
-Ales

On 12/11/16, 2:14 AM, "Harbs" <ha...@gmail.com> wrote:

>I’ve been spending WAY too much time dealing with goog renaming.
>
>I have a good example of the kind of issues I’ve been dealing with. I
>think this is an area where Falcon needs to do a better job.
>
>I have some code which looks like this:
>
>			var JSZip:* = require("jszip");
>
>			var zip:* = new JSZip();
>			var name:String = folderToZip.name;
>			recursiveAdd(folderToZip,zip,"");
>			var promise:Promise = new Promise(function(resolve:*,reject:*):void{
>				var zipFile:File = destinationFolder.resolvePath(folderToZip.name +
>".zip");
>				var zipStream:Stream  = zip.generateNodeStream(
>				{type:'nodebuffer',streamFiles:true}).pipe(
>				fs.createWriteStream(zipFile.nativePath));
>
>				zipStream.on('finish', function ():* {
>    				// JSZip generates a readable stream with a "end" event,
>    				// but is piped here in a writable stream which emits a "finish"
>event.
>   		 			console.log(zipFile.name + " written.");
>						resolve(zipFile);
>				});
>				zipStream.on('error',function():void{
>					console.log("zip error");
>					reject("error");
>				})
>			});
>			return promise;
>
>jszip is a Node module I’m using with require().
>
>This code works perfectly in a debug build of my app.
>
>When I run a release build I get an “undefined function” error.
>
>The problematic code is here:
>				var zipStream:Stream  = zip.generateNodeStream(
>				{type:'nodebuffer',streamFiles:true}).pipe(
>				fs.createWriteStream(zipFile.nativePath));
>
>The code gets minified to this:
>
>return new Promise(function(d,f){var
>h=b.ba(a.name+Zc),k=c.Br({type:yA,Vr:!0}).pipe(fs.createWriteStream(h.nati
>vePath));k.on(Nw,function(){console.log(h.name+ib);d(h)});k.on(vw,function
>(){console.log(hI);f(vw)
>
>This is broken on multiple fronts:
>1. zip. zip.generateNodeStream is renamed to c.Br. Br is quite obviously
>not defined.
>2. streamFiles is renamed to Vr, so the wrong options are being passed
>into jszip. I have no idea why streamFiles is being renamed, but type is
>not.
>
>To fix this you need to do something like this:
>
>				var zipStream:Stream  = zip["generateNodeStream"](
>				{"type":'nodebuffer',"streamFiles":true})["pipe"](
>				fs.createWriteStream(zipFile.nativePath));
>
>Which generates:
>return new Promise(function(d,f){var
>h=b.ba(a.name+Zc),k=c.generateNodeStream({type:yA,streamFiles:!0}).pipe(fs
>.createWriteStream(h.nativePath));k.on(Nw,function(){console.log(h.name+ib
>);d(h)});k.on(vw,function(){console.log(hI);f(vw)})}
>
>I also have no idea why nativePath is not renamed. It’s a property of a
>class which I defined. It seems like it would be a good candidate for
>renaming.
>
>We need some kind of annotation in ActionScript code to enable output of
>annotations for the Google Compiler to know that it’s not okay to rename
>properties of the objects. I’ve had this problem with object literals
>that are being sent as well as accessing properties and methods of
>external objects.
>
>Having manually use bracket notation instead of dot notation is error
>prone. It would be much better to have Falcon automatically change the
>notations or annotate the code in such a way that goog does not rename
>them.
>
>On Dec 6, 2016, at 6:02 PM, Alex Harui <ah...@adobe.com> wrote:
>
>> 
>> 
>> On 12/5/16, 11:47 PM, "Harbs" <ha...@gmail.com> wrote:
>> 
>>> OK. I guess I’ll rework the definitions into extern js files when I
>>>have
>>> time.
>> 
>> In theory, if you use FalconJX to cross-compile those AS files, you
>>should
>> get the right set of JS files to stick a folder called externs (instead
>>of
>> js/out).  The build scripts and settings should be almost the same as
>>how
>> we build the framework SWCs.
>> 
>> HTH,
>> -Alex
>> 
>


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
I’ve been spending WAY too much time dealing with goog renaming.

I have a good example of the kind of issues I’ve been dealing with. I think this is an area where Falcon needs to do a better job.

I have some code which looks like this:

			var JSZip:* = require("jszip");

			var zip:* = new JSZip();
			var name:String = folderToZip.name;
			recursiveAdd(folderToZip,zip,"");
			var promise:Promise = new Promise(function(resolve:*,reject:*):void{
				var zipFile:File = destinationFolder.resolvePath(folderToZip.name + ".zip");
				var zipStream:Stream  = zip.generateNodeStream(
				{type:'nodebuffer',streamFiles:true}).pipe(
				fs.createWriteStream(zipFile.nativePath));

				zipStream.on('finish', function ():* {
    				// JSZip generates a readable stream with a "end" event,
    				// but is piped here in a writable stream which emits a "finish" event.
   		 			console.log(zipFile.name + " written.");
						resolve(zipFile);
				});
				zipStream.on('error',function():void{
					console.log("zip error");
					reject("error");
				})
			});
			return promise;

jszip is a Node module I’m using with require().

This code works perfectly in a debug build of my app.

When I run a release build I get an “undefined function” error.

The problematic code is here:
				var zipStream:Stream  = zip.generateNodeStream(
				{type:'nodebuffer',streamFiles:true}).pipe(
				fs.createWriteStream(zipFile.nativePath));

The code gets minified to this:

return new Promise(function(d,f){var h=b.ba(a.name+Zc),k=c.Br({type:yA,Vr:!0}).pipe(fs.createWriteStream(h.nativePath));k.on(Nw,function(){console.log(h.name+ib);d(h)});k.on(vw,function(){console.log(hI);f(vw)

This is broken on multiple fronts:
1. zip. zip.generateNodeStream is renamed to c.Br. Br is quite obviously not defined.
2. streamFiles is renamed to Vr, so the wrong options are being passed into jszip. I have no idea why streamFiles is being renamed, but type is not.

To fix this you need to do something like this:

				var zipStream:Stream  = zip["generateNodeStream"](
				{"type":'nodebuffer',"streamFiles":true})["pipe"](
				fs.createWriteStream(zipFile.nativePath));

Which generates:
return new Promise(function(d,f){var h=b.ba(a.name+Zc),k=c.generateNodeStream({type:yA,streamFiles:!0}).pipe(fs.createWriteStream(h.nativePath));k.on(Nw,function(){console.log(h.name+ib);d(h)});k.on(vw,function(){console.log(hI);f(vw)})}

I also have no idea why nativePath is not renamed. It’s a property of a class which I defined. It seems like it would be a good candidate for renaming.

We need some kind of annotation in ActionScript code to enable output of annotations for the Google Compiler to know that it’s not okay to rename properties of the objects. I’ve had this problem with object literals that are being sent as well as accessing properties and methods of external objects.

Having manually use bracket notation instead of dot notation is error prone. It would be much better to have Falcon automatically change the notations or annotate the code in such a way that goog does not rename them.

On Dec 6, 2016, at 6:02 PM, Alex Harui <ah...@adobe.com> wrote:

> 
> 
> On 12/5/16, 11:47 PM, "Harbs" <ha...@gmail.com> wrote:
> 
>> OK. I guess I’ll rework the definitions into extern js files when I have
>> time.
> 
> In theory, if you use FalconJX to cross-compile those AS files, you should
> get the right set of JS files to stick a folder called externs (instead of
> js/out).  The build scripts and settings should be almost the same as how
> we build the framework SWCs.
> 
> HTH,
> -Alex
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/5/16, 11:47 PM, "Harbs" <ha...@gmail.com> wrote:

>OK. I guess I’ll rework the definitions into extern js files when I have
>time.

In theory, if you use FalconJX to cross-compile those AS files, you should
get the right set of JS files to stick a folder called externs (instead of
js/out).  The build scripts and settings should be almost the same as how
we build the framework SWCs.

HTH,
-Alex


Re: Avoiding goog renaming

Posted by Harbs <ha...@gmail.com>.
OK. I guess I’ll rework the definitions into extern js files when I have time.

For now, using brackets seems to work.

On Dec 6, 2016, at 9:31 AM, Alex Harui <ah...@adobe.com> wrote:

> 
> 
> On 12/5/16, 11:12 PM, "Harbs" <ha...@gmail.com> wrote:
> 
>> I created a swc library[1] which relies on some typedefs which I created
>> using ActionScript[2].
>> 
>> This all works well when I debug. However, when I compile a release
>> build, the “cep global” methods are being renamed and when executed, I
>> get “function undefined” errors.
>> 
>> I’m not sure what I’m doing wrong. I could change the function calls to
>> use bracket notation, which I expect would prevent goog from renaming
>> them, but that seems like a work-around which should be unnecessary. Is
>> the problem that I’m using ActionnScript rather than “extern” js files to
>> compile the typedef swc?
> 
> Sort of.  Because you are trying to call into third-party code, you have
> to use bracket notation or extern-formatted js files to prevent renaming.
> And, to call that code from other AS, you need .as versions of the API.
> But it doesn't matter whether you generate the JS from AS or vice-versa.
> 
> I don't think we've run any tests of generating externs JS from AS, but it
> should be possible.  But then you need to pack the JS file into the
> typedefs SWC in an folder called "externs".  Unzip google_maps.swc to see
> an example.
> 
> -Alex
> 
>> 
>> Harbs
>> 
>> [1]https://github.com/unhurdle/cep-flexjs/tree/master/CEPTools
>> [2]https://github.com/unhurdle/cep-flexjs/tree/master/CEP6.1
> 


Re: Avoiding goog renaming

Posted by Alex Harui <ah...@adobe.com>.

On 12/5/16, 11:12 PM, "Harbs" <ha...@gmail.com> wrote:

>I created a swc library[1] which relies on some typedefs which I created
>using ActionScript[2].
>
>This all works well when I debug. However, when I compile a release
>build, the “cep global” methods are being renamed and when executed, I
>get “function undefined” errors.
>
>I’m not sure what I’m doing wrong. I could change the function calls to
>use bracket notation, which I expect would prevent goog from renaming
>them, but that seems like a work-around which should be unnecessary. Is
>the problem that I’m using ActionnScript rather than “extern” js files to
>compile the typedef swc?

Sort of.  Because you are trying to call into third-party code, you have
to use bracket notation or extern-formatted js files to prevent renaming.
And, to call that code from other AS, you need .as versions of the API.
But it doesn't matter whether you generate the JS from AS or vice-versa.

I don't think we've run any tests of generating externs JS from AS, but it
should be possible.  But then you need to pack the JS file into the
typedefs SWC in an folder called "externs".  Unzip google_maps.swc to see
an example.

-Alex

>
>Harbs
>
>[1]https://github.com/unhurdle/cep-flexjs/tree/master/CEPTools
>[2]https://github.com/unhurdle/cep-flexjs/tree/master/CEP6.1