You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flex.apache.org by Josh Tynjala <jo...@gmail.com> on 2015/10/01 01:14:57 UTC

Re: Using reserved words as member variable/method names

I just gave the latest nightly a try, and I successfully compiled some
classes that had reserved words as method names. Thanks, Alex!

- Josh

On Thu, Sep 24, 2015 at 12:10 PM, Josh Tynjala <jo...@gmail.com>
wrote:

> I think with FlexJS still in an evolving state, this doesn't seem like a
> huge risk. We're not pushing these changes into the older compiler, which
> has a larger audience with more legacy code. Regardless, since the reserved
> words were not allowed by the compiler in the past, it seems like there is
> a smaller chance of something breaking because legacy code can't rely on
> them.
>
> We should give the examples a thorough testing to be sure that they're
> working properly in both Flash Player and in browsers after being compiled
> with these changes. I'll double-check my Feathers CreateJS prototype too.
>
> Some members are currently excluded from JS.swc because they're reserved
> words, and we can include them again and check that they're working as
> expected. Additionally, if these get into the release, I'll be sure to
> confirm that the compiler will accept my converted TypeScript definitions
> that contain reserved words as members too.
>
> I'm not be opposed to waiting for the next release, though. For what I
> personally want to do in the coming months, it can wait, if it makes us
> feel safer. Developers can use bracket syntax as a temporary workaround, if
> needed.
>
> - Josh
>
> On Thu, Sep 24, 2015 at 11:08 AM, Alex Harui <ah...@adobe.com> wrote:
>
>> OK, well that made things “easier”.  I’ve pushed changes with a few tests
>> into the JsToAs branch.  Volunteers are welcome to add more tests for the
>> other keywords
>>
>> Now the question is:  Do we gamble and merge these changes into the
>> develop branch for the upcoming release?
>>
>> -Alex
>>
>> On 9/24/15, 9:15 AM, "Josh Tynjala" <jo...@gmail.com> wrote:
>>
>> >Requiring "this." before a reserved word when it's used as the name of a
>> >member seems perfectly reasonable. It's sort of the same thing as when a
>> >function parameter is named the same as a member variable.
>> >
>> >function(param:String):void
>> >{
>> >    this.param = param;
>> >}
>> >
>> >Sometimes, certain naming conflicts require you to use "this." to access
>> >what you want, and that's okay.
>> >
>> >- Josh
>> >
>> >On Thu, Sep 24, 2015 at 8:53 AM, Alex Harui <ah...@adobe.com> wrote:
>> >
>> >> Well, this is turning out to be trickier than I thought.  I’m not a
>> >> language person, but one difficulty in getting this to work in our
>> >> compiler seems to have to do with a key difference between AS and JS.
>> >>
>> >> As Josh mentioned in the links below, in JS identifierNames can be used
>> >> essentially anywhere you can use bracket access.  My current theory is
>> >> that this is allowed in JS because all identifierNames have to be
>> >>accessed
>> >> as obj.identifierName.
>> >>
>> >> But in AS, obj is assumed and that makes lexing and parsing difficult
>> >>in a
>> >> couple of situations.  For example:
>> >>
>> >> JS:
>> >>
>> >> Foo = function() {};
>> >> Foo.prototype.return = function(someParam) {
>> >> };
>> >> Foo.prototype.test = function() {
>> >>   this.return(10+20);
>> >>   return (10+20);
>> >> };
>> >>
>> >> In the above example, I can create a function called “return” and call
>> >>it
>> >> with an expression as a parameter and then return an expression.
>> >>
>> >> But now look at the AS:
>> >>
>> >> class Foo
>> >> {
>> >>   function return(someParam)
>> >>   {
>> >>   }
>> >>   function test():int
>> >>   {
>> >>      return(10+20);
>> >>      return (10+20);
>> >>   }
>> >> }
>> >>
>> >> Because AS assumes ‘this’, I can’t think of a way to distinguish
>> >>between a
>> >> call to a function called “return” and the return keyword that returns
>> >>an
>> >> expression.  Same for “catch” and probably “new” and maybe even
>> “throw”.
>> >> I think this is why JS disallows keywords for local variable and local
>> >> function names.
>> >>
>> >> I think other keywords like “default” and “as” and “is” can be
>> >> distinguished from the token stream which can look back one token and
>> >> ahead a few tokens.  I gave up trying to handle this on the parsing
>> side
>> >> because the set of allowed tokens was going to greatly complicate the
>> >> grammar.
>> >>
>> >> My current plan is to “do the best we can” which means that there will
>> >>be
>> >> funky rules when using keywords in identifierNames.  I think the only
>> >> other option is to simply disallow some keywords as identifierNames.
>> >>
>> >> So the funky rules are going to be things like:
>> >> 1. You can use “return” and “catch” as identifierNames but you must use
>> >> “this.” or some other “.” expression in order to access it.
>> >> 2. You can use “break” and “continue” as identifierNames but plain
>> >> “break;” is the keyword and not a call to the getter. Same for
>> >>“continue”;
>> >>
>> >> Thoughts?
>> >> -Alex
>> >>
>> >> On 9/22/15, 10:56 AM, "Alex Harui" <ah...@adobe.com> wrote:
>> >>
>> >> >I’m going to see what compiler changes are needed for this.
>> >> >
>> >> >-Alex
>> >> >
>> >> >On 9/18/15, 4:56 PM, "Josh Tynjala" <jo...@gmail.com> wrote:
>> >> >
>> >> >>Here's the section on reserved words in the ES5.1 spec:
>> >> >>
>> >> >>http://www.ecma-international.org/ecma-262/5.1/#sec-7.6.1
>> >> >>
>> >> >>And the same section in the ES6 / ES2015 spec:
>> >> >>
>> >> >>http://www.ecma-international.org/ecma-262/6.0/#sec-reserved-words
>> >> >>
>> >> >>The rule seems to hinge on whether something is an "identifier" or an
>> >> >>"identifier name". It says that an "identifier" is any valid
>> >>"identifier
>> >> >>name", not including reserved words.
>> >> >>
>> >> >>I'm not an expert at reading language specs, so I can't find the
>> >>places
>> >> >>where the spec clearly shows that an "identifier name" is allowed.
>> >> >>
>> >> >>Mozilla's docs have a clearer explanation, though.
>> >> >>
>> >>
>> >>
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical
>> >> >>_
>> >> >>grammar#Keywords
>> >> >>
>> >> >>Basically, in JS, it seems to boil down to places where you're
>> >>allowed to
>> >> >>optionally put quotes around something:
>> >> >>
>> >> >>1. obj.identifierName
>> >> >>
>> >> >>2. obj.indentifierName()
>> >> >>
>> >> >>3. { identifierName: 2 }
>> >> >>
>> >> >>They could all be rewritten with quotes:
>> >> >>
>> >> >>1. obj["identifierName"]
>> >> >>
>> >> >>2. obj["indentifierName"]
>> >> >>
>> >> >>3. { "identifierName": 2 }
>> >> >>
>> >> >>The Mozilla doc notes that this is not allowed, though:
>> >> >>
>> >> >>function identifierName() {} //error
>> >> >>
>> >> >>At first, I noticed similarity to member functions in AS3:
>> >> >>
>> >> >>class MyClass
>> >> >>{
>> >> >>    public function identifierName() {} //is this considered the same
>> >>as
>> >> >>above?
>> >> >>}
>> >> >>
>> >> >>However, the first one could be rewritten like this, where it's a
>> >> >>variable,
>> >> >>which must be an "identifier" instead of an "identifier name":
>> >> >>
>> >> >>var identifierName = function() {} //error because identifier names
>> >>are
>> >> >>not
>> >> >>allowed!
>> >> >>
>> >> >>If classes are considered syntactic sugar for prototypes, then the
>> AS3
>> >> >>version might be considered to be equivalent to this:
>> >> >>
>> >> >>MyClass.prototype.identifierName = function() {}
>> >> >>
>> >> >>We can rewrite that one with quotes, so the original sugar seems safe
>> >>as
>> >> >>an
>> >> >>"identifier name", assuming that AS3 should follow the same logic.
>> >> >>
>> >> >>MyClass.prototype["identifierName"] = function() {}
>> >> >>
>> >> >>Anyway, just trying to wrap my head around it all.
>> >> >>
>> >> >>- Josh
>> >> >>
>> >> >>On Fri, Sep 18, 2015 at 2:03 PM, Alex Harui <ah...@adobe.com>
>> wrote:
>> >> >>
>> >> >>> Josh,
>> >> >>>
>> >> >>> The key question here is whether is it is not valid AS3 per the
>> >> >>>language
>> >> >>> spec, or whether the runtime and/or the compiler won’t let you
>> >>compile
>> >> >>>it.
>> >> >>>
>> >> >>> AFAICT, what you want to do here is valid AS3 and I would expect
>> the
>> >> >>> runtime to run the expected ABC code, so it should be possible to
>> >>get
>> >> >>>the
>> >> >>> compiler to allow it.  Where to look in the compiler code, I’m not
>> >> >>>sure.
>> >> >>> My trick is to set a breakpoint on the CompilerProblem constructors
>> >>and
>> >> >>> look up the stack to see who decided it was time to generate an
>> >>error
>> >> >>>and
>> >> >>> why.
>> >> >>>
>> >> >>> One more scenario that I ran into today and haven’t tested on JS:
>> >> >>>
>> >> >>> I was porting the MXML feature test base class and to create AS
>> >>feature
>> >> >>> tests.  It had:
>> >> >>>         var mxml:String = generateMXMLForTest();
>> >> >>>
>> >> >>> Which I changed to:
>> >> >>>         var as:String = generateASForTest();
>> >> >>>
>> >> >>> I would expect this to be valid in JS because “as” is not a keyword
>> >>in
>> >> >>>JS.
>> >> >>>  It is interesting that you can’t do “var var” in JS or AS3, but
>> >>since
>> >> >>>AS3
>> >> >>> has more keywords like that than JS, it is possible someone might
>> >>have
>> >> >>>a
>> >> >>> d.ts file with an API with an AS-only keyword in it and then I’m
>> not
>> >> >>>sure
>> >> >>> what to do there.  In this case, though, I think it should be ok to
>> >> >>>have a
>> >> >>> local variable names “as”.
>> >> >>>
>> >> >>> So, do we know in JS where keywords are and aren’t allowed?
>> >> >>>
>> >> >>> Can you do:
>> >> >>>   var in;
>> >> >>>
>> >> >>> Or:
>> >> >>>
>> >> >>>   foo = function(in, out)
>> >> >>>
>> >> >>> We should probably get the big picture of where keywords are
>> allowed
>> >> >>> before making changes in this area.
>> >> >>>
>> >> >>> Thanks,
>> >> >>> -Alex
>> >> >>>
>> >> >>>
>> >> >>> On 9/18/15, 12:39 PM, "Josh Tynjala" <jo...@gmail.com>
>> wrote:
>> >> >>>
>> >> >>> >JavaScript allows the use of reserved words as members of
>> >> >>> >classes/interfaces, but AS3 does not.
>> >> >>> >
>> >> >>> >In JS and AS3, this is not valid:
>> >> >>> >
>> >> >>> >var var = 5;
>> >> >>> >
>> >> >>> >However, in JS, this is valid:
>> >> >>> >
>> >> >>> >var obj = {};
>> >> >>> >obj.var = 5;
>> >> >>> >
>> >> >>> >Not in AS3, though.
>> >> >>> >
>> >> >>> >Similarly, these are not valid AS3, but some JS types have methods
>> >> >>>with
>> >> >>> >these exact names, so that needs to change:
>> >> >>> >
>> >> >>> >class Test
>> >> >>> >{
>> >> >>> >    public function delete():void {}
>> >> >>> >    public function continue():void {}
>> >> >>> >}
>> >> >>> >
>> >> >>> >As far as I can tell, this JS behavior became valid in ES5. I
>> >>assume
>> >> >>>after
>> >> >>> >ES4 was cancelled. There are even some APIs in the JS standard
>> >>library
>> >> >>> >take
>> >> >>> >advantage of this behavior already, and I'm sure that many JS
>> >> >>>libraries do
>> >> >>> >too.
>> >> >>> >
>> >> >>> >Right now, to successfully build a standard library with externc
>> >>(or
>> >> >>>my
>> >> >>> >dts2as tool), these APIs need to be completely excluded. It's fine
>> >>for
>> >> >>>a
>> >> >>> >temporary workaround, but it will become an issue eventually.
>> >> >>> >
>> >> >>> >Alex, since you've been talking about compiler changes, I thought
>> >>I'd
>> >> >>> >throw
>> >> >>> >this one into the ring too.
>> >> >>> >
>> >> >>> >(I'm not yet familiar with this part of the compiler, but if I
>> knew
>> >> >>>where
>> >> >>> >to look, I might be able to figure it out.)
>> >> >>> >
>> >> >>> >- Josh
>> >> >>>
>> >> >>>
>> >> >
>> >>
>> >>
>>
>>
>