Skip to content

Commit

Permalink
Addressed some CR feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRosenwasser committed Feb 28, 2015
1 parent 5437b3d commit b1837c8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2211,7 +2211,7 @@ module ts {

function getDoubleQuotedStringTextOfLiteral(node: LiteralExpression): string {
var result = escapeString(node.text);
result = replaceNonAsciiCharacters(result);
result = escapeNonAsciiCharacters(result);

return '"' + result + '"';
}
Expand Down
45 changes: 30 additions & 15 deletions src/compiler/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,20 +609,26 @@ module ts {
return +(text.substring(start, pos));
}

/**
* Scans the given number of hexadecimal digits in the text,
* returning -1 if the given number is unavailable.
*/
function scanExactNumberOfHexDigits(count: number): number {
return scanHexDigits(/*minCount*/ count, /*maxCount*/ count);
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false);
}

/**
* Scans as many hexadecimal digits as are available in the text,
* returning -1 if the given number of digits was unavailable.
*/
function scanMinimumNumberOfHexDigits(count: number): number {
return scanHexDigits(/*minCount*/ count, /*maxCount*/ undefined);
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true);
}

function scanHexDigits(minCount: number, maxCount?: number): number {
var maxCountSpecified = maxCount !== undefined;

function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean): number {
var digits = 0;
var value = 0;
while (!maxCountSpecified || digits < maxCount) {
while (digits < minCount || scanAsManyAsPossible) {
var ch = text.charCodeAt(pos);
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
value = value * 16 + ch - CharacterCodes._0;
Expand Down Expand Up @@ -777,22 +783,19 @@ module ts {
case CharacterCodes.doubleQuote:
return "\"";
case CharacterCodes.u:
// '\u{DDDDDDDD}'
if (pos < len && text.charCodeAt(pos) === CharacterCodes.openBrace) {
hasExtendedUnicodeEscape = true;
pos++;
return scanExtendedUnicodeEscape();
}

// fall through
// '\uDDDD'
return scanHexadecimalEscape(/*numDigits*/ 4)

case CharacterCodes.x:
var escapedValue = scanExactNumberOfHexDigits(ch === CharacterCodes.x ? 2 : 4);
if (escapedValue >= 0) {
return String.fromCharCode(escapedValue);
}
else {
error(Diagnostics.Hexadecimal_digit_expected);
return ""
}
// '\xDD'
return scanHexadecimalEscape(/*numDigits*/ 2)

// when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
// the line terminator is interpreted to be "the empty code unit sequence".
Expand All @@ -810,6 +813,18 @@ module ts {
}
}

function scanHexadecimalEscape(numDigits: number): string {
var escapedValue = scanExactNumberOfHexDigits(numDigits);

if (escapedValue >= 0) {
return String.fromCharCode(escapedValue);
}
else {
error(Diagnostics.Hexadecimal_digit_expected);
return ""
}
}

function scanExtendedUnicodeEscape(): string {
var escapedValue = scanMinimumNumberOfHexDigits(1);
var isInvalidExtendedEscape = false;
Expand Down
18 changes: 10 additions & 8 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ module ts {
newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
}

return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength: */ newEndN - oldStartN);
return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Mar 2, 2015

Contributor

newLength:

}

// @internal
Expand Down Expand Up @@ -1213,8 +1213,12 @@ module ts {
}
}

var backslashOrDoubleQuote = /[\"\\]/g;
var escapedCharsRegExp = /[\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
// This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
// the language service. These characters should be escaped when printing, and if any characters are added,
// the map below must be updated. Note that this regexp *does not* include the 'delete' character.
// There is no reason for this other than that JSON.stringify does not handle it either.
var escapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
var escapedCharsMap: Map<string> = {
"\0": "\\0",
"\t": "\\t",
Expand All @@ -1231,13 +1235,11 @@ module ts {
};

/**
* Based heavily on the abstract 'Quote'/ 'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
* but augmented for a few select characters.
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
* but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
* Note that this doesn't actually wrap the input in double quotes.
*/
export function escapeString(s: string): string {
// Prioritize '"' and '\'
s = backslashOrDoubleQuote.test(s) ? s.replace(backslashOrDoubleQuote, getReplacement) : s;
s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;

return s;
Expand All @@ -1254,7 +1256,7 @@ module ts {
}

var nonAsciiCharacters = /[^\u0000-\u007F]/g;
export function replaceNonAsciiCharacters(s: string): string {
export function escapeNonAsciiCharacters(s: string): string {
// Replace non-ASCII characters with '\uNNNN' escapes if any exist.
// Otherwise just return the original string.
return nonAsciiCharacters.test(s) ?
Expand Down

0 comments on commit b1837c8

Please sign in to comment.