Improve error messages for unexpected regexes

This commit is contained in:
Simon Lydell 2015-02-03 20:42:50 +01:00
parent 04b30a6cc4
commit ffa25aae77
4 changed files with 24 additions and 6 deletions

View File

@ -279,7 +279,7 @@
};
Lexer.prototype.regexToken = function() {
var closed, end, flags, index, match, prev, re, ref2, ref3, regex, rparen, tokens;
var closed, end, errorToken, flags, index, match, prev, re, ref2, ref3, regex, rparen, tokens;
switch (false) {
case !(match = REGEX_ILLEGAL.exec(this.chunk)):
this.error("regular expressions cannot begin with " + match[2], match.index + match[1].length);
@ -309,6 +309,7 @@
}
flags = REGEX_FLAGS.exec(this.chunk.slice(index))[0];
end = index + flags.length;
errorToken = this.makeToken('REGEX', this.chunk.slice(0, end), 0, end);
switch (false) {
case !!VALID_FLAGS.test(flags):
this.error("invalid regular expression flags " + flags, index);
@ -318,11 +319,11 @@
break;
case tokens.length !== 1:
re = this.formatHeregex(tokens[0][1]).replace(/\//g, '\\/');
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, end, errorToken);
break;
default:
this.token('IDENTIFIER', 'RegExp', 0, 0);
this.token('CALL_START', '(', 0, 0);
this.token('CALL_START', '(', 0, 0, errorToken);
this.mergeInterpolationTokens(tokens, '"', (function(_this) {
return function(value) {
return _this.formatHeregex(value).replace(/\\/g, '\\\\');

View File

@ -272,6 +272,7 @@ exports.Lexer = class Lexer
[flags] = REGEX_FLAGS.exec @chunk[index..]
end = index + flags.length
errorToken = @makeToken 'REGEX', @chunk[...end], 0, end
switch
when not VALID_FLAGS.test flags
@error "invalid regular expression flags #{flags}", index
@ -279,10 +280,10 @@ exports.Lexer = class Lexer
@token 'REGEX', "#{regex}#{flags}"
when tokens.length is 1
re = @formatHeregex(tokens[0][1]).replace(/\//g, '\\/')
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}", 0, end, errorToken
else
@token 'IDENTIFIER', 'RegExp', 0, 0
@token 'CALL_START', '(', 0, 0
@token 'CALL_START', '(', 0, 0, errorToken
@mergeInterpolationTokens tokens, '"', (value) =>
@formatHeregex(value).replace(/\\/g, '\\\\')
if flags

View File

@ -125,6 +125,22 @@ test "#1096: unexpected generated tokens", ->
for i in [1]:
^
'''
# Unexpected regex
assertErrorFormat '{/a/i: val}', '''
[stdin]:1:2: error: unexpected /a/i
{/a/i: val}
^^^^
'''
assertErrorFormat '{///a///i: val}', '''
[stdin]:1:2: error: unexpected ///a///i
{///a///i: val}
^^^^^^^^
'''
assertErrorFormat '{///#{a}///i: val}', '''
[stdin]:1:2: error: unexpected ///#{a}///i
{///#{a}///i: val}
^^^^^^^^^^^
'''
test "#1316: unexpected end of interpolation", ->
assertErrorFormat '''

View File

@ -446,7 +446,7 @@ test "#3621: Multiline regex and manual `Regex` call with interpolation should
tokenB = tokensB[i]
eq tokenA[0], tokenB[0]
eq tokenA[1], tokenB[1]
eq tokenA.origin?[1], tokenB.origin?[1]
eq tokenA.origin?[1], tokenB.origin?[1] unless tokenA[0] is 'CALL_START'
eq tokenA.stringEnd, tokenB.stringEnd
test "Verify all tokens get a location", ->