Skip to content

Commit

Permalink
Fixed error when parsing slashes in RegExp literals.
Browse files Browse the repository at this point in the history
Basically we weren't recognizing that a slash can occur in a character class, so we were bailing out too early on code like `/[/]/`.

Fixes issue #318.
  • Loading branch information
DanielRosenwasser committed Jul 31, 2014
1 parent 853288b commit 35803db
Show file tree
Hide file tree
Showing 14 changed files with 62 additions and 67 deletions.
22 changes: 17 additions & 5 deletions src/compiler/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -831,34 +831,46 @@ module ts {
if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) {
var p = tokenPos + 1;
var inEscape = false;
var inClass = false;
var inCharacterClass = false;
while (true) {
// If we've hit EOF without closing off the regex,
// simply return the token we originally parsed.
if (p >= len) {
return token;
}

var ch = text.charCodeAt(p);

// Line breaks are not permissible in the middle of a RegExp.
if (isLineBreak(ch)) {
return token;
}

if (inEscape) {
// Parsing an escape character;
// reset the flag and just advance to the next char.
inEscape = false;
}
else if (ch === CharacterCodes.slash) {
else if (ch === CharacterCodes.slash && !inCharacterClass) {
// A slash within a character class is permissible,
// but in general it signals the end of the regexp literal.
break;
}
else if (ch === CharacterCodes.openBracket) {
inClass = true;
inCharacterClass = true;
}
else if (ch === CharacterCodes.backslash) {
inEscape = true;
}
else if (ch === CharacterCodes.closeBracket) {
inClass = false;
inCharacterClass = false;
}
p++;
}
p++;
while (isIdentifierPart(text.charCodeAt(p))) p++;
while (isIdentifierPart(text.charCodeAt(p))) {
p++;
}
pos = p;
tokenValue = text.substring(tokenPos, pos);
token = SyntaxKind.RegularExpressionLiteral;
Expand Down
8 changes: 0 additions & 8 deletions tests/baselines/reference/parser596700.errors.txt

This file was deleted.

5 changes: 5 additions & 0 deletions tests/baselines/reference/parser596700.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//// [parser596700.ts]
var regex2 = /[a-z/]$/i;

//// [parser596700.js]
var regex2 = /[a-z/]$/i;
12 changes: 0 additions & 12 deletions tests/baselines/reference/parser630933.errors.txt

This file was deleted.

8 changes: 8 additions & 0 deletions tests/baselines/reference/parser630933.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [parser630933.ts]
var a = "Hello";
var b = a.match(/\/ver=([^/]+)/);


//// [parser630933.js]
var a = "Hello";
var b = a.match(/\/ver=([^/]+)/);
8 changes: 0 additions & 8 deletions tests/baselines/reference/parser645086_3.errors.txt

This file was deleted.

5 changes: 5 additions & 0 deletions tests/baselines/reference/parser645086_3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//// [parser645086_3.ts]
var v = /[\]/]/

//// [parser645086_3.js]
var v = /[\]/]/;
8 changes: 0 additions & 8 deletions tests/baselines/reference/parser645086_4.errors.txt

This file was deleted.

5 changes: 5 additions & 0 deletions tests/baselines/reference/parser645086_4.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//// [parser645086_4.ts]
var v = /[^\]/]/

//// [parser645086_4.js]
var v = /[^\]/]/;
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
==== tests/cases/conformance/parser/ecmascript5/RegularExpressions/parserRegularExpression2.ts (4 errors) ====
==== tests/cases/conformance/parser/ecmascript5/RegularExpressions/parserRegularExpression2.ts (1 errors) ====
href.match(/:\/\/(.[^/]+)/)[1];
~
!!! ',' expected.
~
!!! Expression expected.
~
!!! Expression expected.
~~~~
!!! Cannot find name 'href'.
5 changes: 5 additions & 0 deletions tests/baselines/reference/parserRegularExpression2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//// [parserRegularExpression2.ts]
href.match(/:\/\/(.[^/]+)/)[1];

//// [parserRegularExpression2.js]
href.match(/:\/\/(.[^/]+)/)[1];
10 changes: 10 additions & 0 deletions tests/baselines/reference/regExpWithSlashInCharClass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//// [regExpWithSlashInCharClass.ts]
var foo1 = "a/".replace(/.[/]/, "");
var foo2 = "a//".replace(/.[//]/g, "");
var foo3 = "a/".replace(/.[/no sleep /till/]/, "bugfix");


//// [regExpWithSlashInCharClass.js]
var foo1 = "a/".replace(/.[/]/, "");
var foo2 = "a//".replace(/.[//]/g, "");
var foo3 = "a/".replace(/.[/no sleep /till/]/, "bugfix");
22 changes: 3 additions & 19 deletions tests/baselines/reference/validRegexp.errors.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
==== tests/cases/compiler/validRegexp.ts (9 errors) ====
==== tests/cases/compiler/validRegexp.ts (1 errors) ====
var x = / [a - z /]$ / i;
~
!!! ',' expected.
~
!!! '=' expected.
~
!!! Cannot find name 'i'.
var x1 = /[a-z/]$/i;
~
!!! ',' expected.
~
!!! '=' expected.
~
!!! Cannot find name 'i'.
var x2 = /[a-z/]$ /i;
~
!!! ',' expected.
~
!!! '=' expected.
~
!!! Cannot find name 'i'.
var x1 = /[a-z/]$/i;
var x2 = /[a-z/]$ /i;
3 changes: 3 additions & 0 deletions tests/cases/compiler/regExpWithSlashInCharClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var foo1 = "a/".replace(/.[/]/, "");
var foo2 = "a//".replace(/.[//]/g, "");
var foo3 = "a/".replace(/.[/no sleep /till/]/, "bugfix");

0 comments on commit 35803db

Please sign in to comment.