-
Notifications
You must be signed in to change notification settings - Fork 2k
Fix super-related tagging of Code
nodes
#3237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* Fixes jashkenas#2949: Detect reserved names (not only for instance methods) * Don't assign names which might result in incorrect `super` calls
@@ -1005,6 +1005,10 @@ exports.Class = class Class extends Base | |||
else if node instanceof Code | |||
node.klass = name | |||
node.context = name if node.bound | |||
else if node instanceof Assign and | |||
node.variable.base.value in ['this', name] and | |||
node.variable.properties[0]?.name?.value isnt 'prototype' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we refactor this, maybe ?
Good work otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly, but I'm not quite sure what you have in mind exactly.
In the long run I would like to replace the METHOD_DEF
logic by a function that operates on nodes, instead of regexp-matching a temporary compilation. That would then be utilized here as well. But this PR is just meant as a band-aid to get those issues fixed before 1.7
Or did you just look for something like
else if node instanceof Assign and
node.variable.base.value in ['this', name] and
prop = node.variable.properties[0] and
name = prop.name and
name.value isnt 'prototype'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, I meant something like node instanceof Assign and node.isStatic()
indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like static
is still being set in 2 different places, here for the @=
version, and addParameters
for the @:
version.
In #3232 (comment) I put a testStatic
method that handles both @foo:
and @foo=
.
As best I can tell addProperties
does not need to set context
; setContext
takes care of that.
if func.bound
func.context = name`
That testStatic
works at this setContext
location with:
else
Class::testStatic node # try alt location
I haven't identified the comparative advantages of this testing in setContext
versus a bit later in walkBody
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like
static
is still being set in 2 different places
I think this duplication is preferable to iterating twice over object properties (in different places), as in your solution.
I haven't identified the comparative advantages of this testing in
setContext
versus a bit later inwalkBody
.
In walkBody
we don't have to check for this
and the class name (an edge case that's very dear to me ;) And, well, it doesn't actually 'setContext'.
As best I can tell
addProperties
does not need to setcontext
;setContext
takes care of that.
Very nice find. And a brainfart on my side: The current solution also tags this: ->
and properties with the same name as the class as static.
Ammended the commit -- looks even better now. (fuck yeah code reviews :)
Fantastic deductive work. Do you think this is ready to merge ... or would you like to keep going on it a bit more? |
@jashkenas: Maybe we could let it sit for a day or so, to give everyone (e.g. @Nami-Doc) a chance to reply / voice concerns. |
Sounds good. I agree completely about the METHOD_DEF bit — I wonder how that ever got added in the first place ;) |
(and remove duplicate `context` assigment)
Fix super-related tagging of `Code` nodes
super
compiles now in static methods with reserved names (Compiler error when callingsuper
from a method named with a reserved word #2949)@fn: -> super
and@fn = -> super
produce the same compilation (super compiles differently depending on how class method is defined #3232)super
will no longer compile for ambiguous / wrong super-targets (see Implications below)Theory of Operation / Changes
super
compiles only within aCode
node that eitherClass
).name
and.klass
set.name
but is contained by anotherCode
with both propertiesIf the
Code
node also has a truthy.static
the super call will be compiled accordingly..static
is set byClass
for object assigns with a@
. Changed: 97d9a63 looks also at non-object assignments. This fixes #3232..klass
is set byClass
to all its functions (on the class-level, not nested functions)Assign
to prototype functions, i.e. if the LHS begins with the form {CLASS_NAME}.prototype.{IDENTIFIER|INDEX}. This has been changed to match only this exact form. (see also below).name
is set byAssign
which inspects its LHS with the help of theMETHOD_DEF
regexp. (Except constructors, they get their name fromClass.ensureConstructor
.)Changed: 138c25f restricts
METHOD_DEF
to match onlyC::f = ->
But no longer to properties of objects on prototypes, e.g.
C::f.g = ->
C.static = ->
But no longer to anything else that ends with an IDENTIFIER, e.g.
C.a.b = ->
Both cases are now detected in the same way. This fixes #2949.
Implications
The following examples do not work anymore and will throw a 'cannot call super ...' error. None of those look correct or useful to me.
The following examples will no longer throw 'cannot call super ...' but compile. (This is related to #1606 -- but by no means complete or usable).