avoid ascii escaping literal text

This commit is contained in:
Arthur Ozga
2017-05-15 18:42:49 -07:00
parent d8f29a5fe8
commit bba41a8a0c
8 changed files with 25 additions and 20 deletions

View File

@@ -2385,7 +2385,7 @@ namespace ts {
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
}
if (type.flags & (TypeFlags.StringLiteral)) {
return createLiteralTypeNode((createLiteral((<LiteralType>type).text)));
return createLiteralTypeNode(setEmitFlags(createLiteral((<LiteralType>type).text), EmitFlags.NoAsciiEscaping));
}
if (type.flags & (TypeFlags.NumberLiteral)) {
return createLiteralTypeNode((createNumericLiteral((<LiteralType>type).text)));
@@ -2783,7 +2783,9 @@ namespace ts {
let returnTypeNode: TypeNode;
if (signature.typePredicate) {
const typePredicate = signature.typePredicate;
const parameterName = typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier((<IdentifierTypePredicate>typePredicate).parameterName) : createThisTypeNode();
const parameterName = typePredicate.kind === TypePredicateKind.Identifier ?
setEmitFlags(createIdentifier((<IdentifierTypePredicate>typePredicate).parameterName), EmitFlags.NoAsciiEscaping) :
createThisTypeNode();
const typeNode = typeToTypeNodeHelper(typePredicate.type, context);
returnTypeNode = createTypePredicateNode(parameterName, typeNode);
}
@@ -2894,7 +2896,7 @@ namespace ts {
}
const symbolName = getNameOfSymbol(symbol, context);
const identifier = createIdentifier(symbolName, typeParameterNodes);
const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
}

View File

@@ -2653,7 +2653,9 @@ namespace ts {
if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
const textSourceNode = (<StringLiteral>node).textSourceNode;
if (isIdentifier(textSourceNode)) {
return "\"" + escapeNonAsciiCharacters(escapeString(getTextOfNode(textSourceNode))) + "\"";
return getEmitFlags(node) & EmitFlags.NoAsciiEscaping ?
`"${escapeString(getTextOfNode(textSourceNode))}"` :
`"${escapeNonAsciiCharacters(escapeString(getTextOfNode(textSourceNode)))}"`;
}
else {
return getLiteralTextOfNode(textSourceNode);

View File

@@ -3985,6 +3985,7 @@ namespace ts {
NoHoisting = 1 << 21, // Do not hoist this declaration in --module system
HasEndOfDeclarationMarker = 1 << 22, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
}
export interface EmitHelper {

View File

@@ -328,19 +328,22 @@ namespace ts {
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
}
const escapeText = getEmitFlags(node) & EmitFlags.NoAsciiEscaping ?
(text: string) => escapeString(text) :
(text: string) => escapeNonAsciiCharacters(escapeString(text));
// If we can't reach the original source text, use the canonical form if it's a number,
// or an escaped quoted form of the original text if it's string-like.
// or a (possibly escaped) quoted form of the original text if it's string-like.
switch (node.kind) {
case SyntaxKind.StringLiteral:
return getQuotedEscapedLiteralText('"', node.text, '"');
return '"' + escapeText(node.text) + '"';
case SyntaxKind.NoSubstitutionTemplateLiteral:
return getQuotedEscapedLiteralText("`", node.text, "`");
return "`" + escapeText(node.text) + "`";
case SyntaxKind.TemplateHead:
return getQuotedEscapedLiteralText("`", node.text, "${");
return "`" + escapeText(node.text) + "${";
case SyntaxKind.TemplateMiddle:
return getQuotedEscapedLiteralText("}", node.text, "${");
return "}" + escapeText(node.text) + "${";
case SyntaxKind.TemplateTail:
return getQuotedEscapedLiteralText("}", node.text, "`");
return "}" + escapeText(node.text) + "`";
case SyntaxKind.NumericLiteral:
return node.text;
}
@@ -348,10 +351,6 @@ namespace ts {
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
}
function getQuotedEscapedLiteralText(leftQuote: string, text: string, rightQuote: string) {
return leftQuote + escapeNonAsciiCharacters(escapeString(text)) + rightQuote;
}
// Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__'
export function escapeIdentifier(identifier: string): string {
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;

View File

@@ -0,0 +1 @@
var = "Ü­ਲĭ";

View File

@@ -1,11 +1,11 @@
/// <reference path='fourslash.ts' />
//// interface I<X> {
//// [x: string]: X;
//// [Ƚ: string]: X;
//// }
////
//// class C implements I<number> {[| |]}
verify.rangeAfterCodeFix(`
[x: string]: number;
[Ƚ: string]: number;
`);

View File

@@ -2,12 +2,12 @@
//// abstract class C1 { }
//// abstract class C2 {
//// abstract f1<T extends number>();
//// abstract f<T extends number>();
//// }
//// interface I1 extends C1, C2 { }
//// class C3 implements I1 {[| |]}
verify.rangeAfterCodeFix(`f1<T extends number>(){
verify.rangeAfterCodeFix(`f<T extends number>(){
throw new Error("Method not implemented.");
}
`);

View File

@@ -4,7 +4,7 @@
//// x: number;
//// }
//// interface I2 {
//// y: number;
//// y: "𣋝ઢȴ¬⏊";
//// }
////
//// class C implements I1,I2 {[|
@@ -12,7 +12,7 @@
//// }
verify.rangeAfterCodeFix(`
y: number;
y: "𣋝ઢȴ¬⏊";
`);
verify.not.codeFixAvailable();