Skip to content

Commit

Permalink
Fix #4609: support new.target (#5106)
Browse files Browse the repository at this point in the history
* support new.target

* check token type
  • Loading branch information
helixbass authored and GeoffreyBooth committed Sep 16, 2018
1 parent c4245e5 commit 6225627
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/coffeescript/lexer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions lib/coffeescript/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/lexer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ exports.Lexer = class Lexer
@tokens.length > 1 and @tokens[@tokens.length - 2][0] not in ['.', '?.', '@']
@error "'#{prev[1]}' cannot be used as a keyword, or as a function call
without parentheses", prev[2]
else if prev[0] is '.' and @tokens.length > 1 and (prevprev = @tokens[@tokens.length - 2])[0] is 'UNARY' and prevprev[1] is 'new'
prevprev[0] = 'IDENTIFIER'
else if @tokens.length > 2
prevprev = @tokens[@tokens.length - 2]
if prev[0] in ['@', 'THIS'] and prevprev and prevprev.spaced and
Expand Down
9 changes: 9 additions & 0 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ exports.Value = class Value extends Base
# operators `?.` interspersed. Then we have to take care not to accidentally
# evaluate anything twice when building the soak chain.
compileNode: (o) ->
@checkNewTarget o
@base.front = @front
props = @properties
if props.length and @base.cached?
Expand All @@ -984,6 +985,14 @@ exports.Value = class Value extends Base

fragments

checkNewTarget: (o) ->
return unless @base instanceof IdentifierLiteral and @base.value is 'new' and @properties.length
if @properties[0] instanceof Access and @properties[0].name.value is 'target'
unless o.scope.parent?
@error "new.target can only occur inside functions"
else
@error "the only valid meta property for new is new.target"

# Unfold a soak into an `If`: `a?.b` -> `a.b if a?`
unfoldSoak: (o) ->
@unfoldedSoak ?= do =>
Expand Down
24 changes: 23 additions & 1 deletion test/classes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1899,4 +1899,26 @@ test "#4868: Incorrect ‘Can’t call super with @params’ error", ->
super class then constructor: (@a) -> @a = 3

d = new (new D).c
eq 3, d.a
eq 3, d.a

test "#4609: Support new.target", ->
class A
constructor: ->
@calledAs = new.target.name

class B extends A

b = new B
eq b.calledAs, 'B'

newTarget = null
Foo = ->
newTarget = !!new.target

Foo()
eq newTarget, no

newTarget = null

new Foo()
eq newTarget, yes
18 changes: 18 additions & 0 deletions test/error_messages.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1907,3 +1907,21 @@ test "#3933: prevent implicit calls when cotrol flow is missing `THEN`", ->
when a ->
^^
'''

test "`new.target` outside of a function", ->
assertErrorFormat '''
new.target
''', '''
[stdin]:1:1: error: new.target can only occur inside functions
new.target
^^^^^^^^^^
'''

test "`new.target` is only allowed meta property", ->
assertErrorFormat '''
-> new.something
''', '''
[stdin]:1:4: error: the only valid meta property for new is new.target
-> new.something
^^^^^^^^^^^^^
'''

0 comments on commit 6225627

Please sign in to comment.