flex-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Josh Tynjala <joshtynj...@gmail.com>
Subject Re: Using reserved words as member variable/method names
Date Thu, 24 Sep 2015 19:10:49 GMT
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 <aharui@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" <joshtynjala@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 <aharui@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" <aharui@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" <joshtynjala@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 <aharui@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" <joshtynjala@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
> >> >>>
> >> >>>
> >> >
> >>
> >>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message