diff --git a/lib/lexer.js b/lib/lexer.js index cfd1fb57ee..a5c96d9f8a 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -1,5 +1,5 @@ (function() { - var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, last, op, starts, _ref; + var ASSIGNED, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, last, op, starts, _ref; var __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (this[i] === item) return i; @@ -175,7 +175,6 @@ return 0; } comment = match[0], here = match[1]; - this.line += count(comment, '\n'); if (here) { this.token('HERECOMMENT', this.sanitizeHeredoc(here, { herecomment: true, @@ -183,6 +182,7 @@ })); this.token('TERMINATOR', '\n'); } + this.line += count(comment, '\n'); return comment.length; }; Lexer.prototype.jsToken = function() { @@ -398,10 +398,14 @@ Lexer.prototype.sanitizeHeredoc = function(doc, options) { var attempt, herecomment, indent, match, _ref; indent = options.indent, herecomment = options.herecomment; - if (herecomment && 0 > doc.indexOf('\n')) { - return doc; - } - if (!herecomment) { + if (herecomment) { + if (HEREDOC_ILLEGAL.test(doc)) { + throw new Error("block comment cannot contain \"*/\", starting on line " + (this.line + 1)); + } + if (doc.indexOf('\n') <= 0) { + return doc; + } + } else { while (match = HEREDOC_INDENT.exec(doc)) { attempt = match[1]; if (indent === null || (0 < (_ref = attempt.length) && _ref < indent.length)) { @@ -618,6 +622,7 @@ HEREGEX_OMIT = /\s+(?:#.*)?/g; MULTILINER = /\n/g; HEREDOC_INDENT = /\n+([^\n\S]*)/g; + HEREDOC_ILLEGAL = /\*\//; ASSIGNED = /^\s*@?([$A-Za-z_][$\w\x7f-\uffff]*|['"].*['"])[^\n\S]*?[:=][^:=>]/; LINE_CONTINUER = /^\s*(?:,|\??\.(?!\.)|::)/; TRAILING_SPACES = /\s+$/; diff --git a/src/lexer.coffee b/src/lexer.coffee index 6bf7962807..3d9612d31f 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -170,11 +170,11 @@ exports.Lexer = class Lexer commentToken: -> return 0 unless match = @chunk.match COMMENT [comment, here] = match - @line += count comment, '\n' if here @token 'HERECOMMENT', @sanitizeHeredoc here, herecomment: true, indent: Array(@indent + 1).join(' ') @token 'TERMINATOR', '\n' + @line += count comment, '\n' comment.length # Matches JavaScript interpolated directly into the source via backticks. @@ -343,8 +343,11 @@ exports.Lexer = class Lexer # erasing all external indentation on the left-hand side. sanitizeHeredoc: (doc, options) -> {indent, herecomment} = options - return doc if herecomment and 0 > doc.indexOf '\n' - unless herecomment + if herecomment + if HEREDOC_ILLEGAL.test doc + throw new Error "block comment cannot contain \"*/\", starting on line #{@line + 1}" + return doc if doc.indexOf('\n') <= 0 + else while match = HEREDOC_INDENT.exec doc attempt = match[1] indent = attempt if indent is null or 0 < attempt.length < indent.length @@ -593,6 +596,8 @@ MULTILINER = /\n/g HEREDOC_INDENT = /\n+([^\n\S]*)/g +HEREDOC_ILLEGAL = /\*\// + ASSIGNED = /^\s*@?([$A-Za-z_][$\w\x7f-\uffff]*|['"].*['"])[^\n\S]*?[:=][^:=>]/ LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?!\.) | :: ) /// diff --git a/test/compilation.coffee b/test/compilation.coffee index 6de9d986d5..6558df68dc 100644 --- a/test/compilation.coffee +++ b/test/compilation.coffee @@ -55,3 +55,6 @@ test "#1026", -> else d ''' + +test "#1050", -> + cantCompile "### */ ###" \ No newline at end of file