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" <aha...@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" <joshtynj...@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 <aha...@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" <joshtynj...@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 >>> >>> >