Skip to content

Commit

Permalink
Throw an error if get or set are used as keywords before what looks l…
Browse files Browse the repository at this point in the history
…ike a function or method with an interpolated/dynamic name
  • Loading branch information
GeoffreyBooth committed Apr 5, 2017
1 parent ed4c828 commit 962374a
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
60 changes: 36 additions & 24 deletions lib/coffeescript/lexer.js

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

10 changes: 8 additions & 2 deletions src/lexer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ exports.Lexer = class Lexer
isForFrom(prev)
tag = 'FORFROM'
@seenFor = no
# Throw an error on attempts to use `get` or `set` as keywords, or
# what CoffeeScript would normally interpret as calls to functions named
# `get` or `set`, i.e. `get({foo: function () {}})`
else if tag is 'PROPERTY' and prev
if prev.spaced and prev[0] in CALLABLE and /^[gs]et$/.test(prev[1])
@error "'#{prev[1]}' cannot be used as a keyword, or as a function call without parentheses", prev[2]
Expand Down Expand Up @@ -246,8 +249,11 @@ exports.Lexer = class Lexer

# If the preceding token is `from` and this is an import or export statement,
# properly tag the `from`.
if @tokens.length and @value() is 'from' and (@seenImport or @seenExport)
@tokens[@tokens.length - 1][0] = 'FROM'
if prev and @value() is 'from' and (@seenImport or @seenExport)
prev[0] = 'FROM'

if prev and prev.spaced and prev[0] in CALLABLE and /^[gs]et$/.test(prev[1])
@error "'#{prev[1]}' cannot be used as a keyword, or as a function call without parentheses", prev[2]

regex = switch quote
when "'" then STRING_SINGLE
Expand Down
20 changes: 20 additions & 0 deletions test/error_messages.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1476,3 +1476,23 @@ test "setter keyword before static method", ->
set @foo = ->
^^^
'''

test "getter keyword with dynamic property name", ->
assertErrorFormat '''
class A
get "#{'foo'}": ->
''', '''
[stdin]:2:3: error: 'get' cannot be used as a keyword, or as a function call without parentheses
get "#{'foo'}": ->
^^^
'''

test "setter keyword with dynamic property name", ->
assertErrorFormat '''
class A
set "#{'foo'}": ->
''', '''
[stdin]:2:3: error: 'set' cannot be used as a keyword, or as a function call without parentheses
set "#{'foo'}": ->
^^^
'''
4 changes: 4 additions & 0 deletions test/function_invocation.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -712,11 +712,15 @@ test "get and set can be used as function names when not ambiguous with `get`/`s
set = (val) -> val
eq 2, get(2)
eq 3, set(3)
eq 'a', get('a')
eq 'b', set('b')

get = ({val}) -> val
set = ({val}) -> val
eq 4, get({val: 4})
eq 5, set({val: 5})
eq 'c', get({val: 'c'})
eq 'd', set({val: 'd'})

test "get and set can be used as variable and property names", ->
get = 2
Expand Down

0 comments on commit 962374a

Please sign in to comment.