From 98d1644c5bed6bc55bd6fe141e7a9267b9cdc6cf Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Sun, 2 Apr 2017 17:36:25 -0700 Subject: [PATCH] Fix #4451: Treat `default` as a keyword in an export statement only when it follows `export` or `as` --- lib/coffee-script/lexer.js | 12 ++++++------ src/lexer.coffee | 2 +- test/modules.coffee | 8 ++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/coffee-script/lexer.js b/lib/coffee-script/lexer.js index 26fb50d273..b8b10603c0 100644 --- a/lib/coffee-script/lexer.js +++ b/lib/coffee-script/lexer.js @@ -69,7 +69,7 @@ }; Lexer.prototype.identifierToken = function() { - var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, ref6, ref7, tag, tagToken; + var alias, colon, colonOffset, id, idLength, input, match, poppedToken, prev, ref2, ref3, ref4, ref5, ref6, ref7, ref8, tag, tagToken; if (!(match = IDENTIFIER.exec(this.chunk))) { return 0; } @@ -99,15 +99,15 @@ this.token('AS', id); return id.length; } - if (id === 'default' && this.seenExport) { + if (id === 'default' && this.seenExport && ((ref4 = this.tag()) === 'EXPORT' || ref4 === 'AS')) { this.token('DEFAULT', id); return id.length; } - ref4 = this.tokens, prev = ref4[ref4.length - 1]; - tag = colon || (prev != null) && (((ref5 = prev[0]) === '.' || ref5 === '?.' || ref5 === '::' || ref5 === '?::') || !prev.spaced && prev[0] === '@') ? 'PROPERTY' : 'IDENTIFIER'; + ref5 = this.tokens, prev = ref5[ref5.length - 1]; + tag = colon || (prev != null) && (((ref6 = prev[0]) === '.' || ref6 === '?.' || ref6 === '::' || ref6 === '?::') || !prev.spaced && prev[0] === '@') ? 'PROPERTY' : 'IDENTIFIER'; if (tag === 'IDENTIFIER' && (indexOf.call(JS_KEYWORDS, id) >= 0 || indexOf.call(COFFEE_KEYWORDS, id) >= 0) && !(this.exportSpecifierList && indexOf.call(COFFEE_KEYWORDS, id) >= 0)) { tag = id.toUpperCase(); - if (tag === 'WHEN' && (ref6 = this.tag(), indexOf.call(LINE_BREAK, ref6) >= 0)) { + if (tag === 'WHEN' && (ref7 = this.tag(), indexOf.call(LINE_BREAK, ref7) >= 0)) { tag = 'LEADING_WHEN'; } else if (tag === 'FOR') { this.seenFor = true; @@ -172,7 +172,7 @@ tagToken.origin = [tag, alias, tagToken[2]]; } if (poppedToken) { - ref7 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref7[0], tagToken[2].first_column = ref7[1]; + ref8 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = ref8[0], tagToken[2].first_column = ref8[1]; } if (colon) { colonOffset = input.lastIndexOf(':'); diff --git a/src/lexer.coffee b/src/lexer.coffee index 6c1be4a5ae..eca06e0d60 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -127,7 +127,7 @@ exports.Lexer = class Lexer if id is 'as' and @seenExport and @tag() is 'IDENTIFIER' @token 'AS', id return id.length - if id is 'default' and @seenExport + if id is 'default' and @seenExport and @tag() in ['EXPORT', 'AS'] @token 'DEFAULT', id return id.length diff --git a/test/modules.coffee b/test/modules.coffee index 9cc0e66c00..63de9eb084 100644 --- a/test/modules.coffee +++ b/test/modules.coffee @@ -749,3 +749,11 @@ test "#4394: export shouldn't prevent variable declarations", -> }; """ eq toJS(input), output + +test "#4451: `default` in an export statement is only treated as a keyword when it follows `export` or `as`", -> + input = "export default { default: 1 }" + output = """ + export default { + "default": 1 + }; + """