fix(compiler-cli): emit correct css string escape sequences (#22776)

Works around an issue with TypeScript 2.6 and 2.7 that causes
the tranformer emit to emit incorrect escapes for css string
literals.

Fixes: #22774

PR Close #22776
This commit is contained in:
Chuck Jazdzewski 2018-03-14 13:31:38 -07:00 committed by Miško Hevery
parent 19e6b8dad5
commit 6e5e819e80
2 changed files with 24 additions and 1 deletions

View File

@ -150,13 +150,28 @@ function firstAfter<T>(a: T[], predicate: (value: T) => boolean) {
// NodeEmitterVisitor
type RecordedNode<T extends ts.Node = ts.Node> = (T & { __recorded: any; }) | null;
function escapeLiteral(value: string): string {
return value.replace(/(\"|\\)/g, '\\$1').replace(/(\n)|(\r)/g, function(v, n, r) {
return n ? '\\n' : '\\r';
});
}
function createLiteral(value: any) {
if (value === null) {
return ts.createNull();
} else if (value === undefined) {
return ts.createIdentifier('undefined');
} else {
return ts.createLiteral(value);
const result = ts.createLiteral(value);
if (ts.isStringLiteral(result) && result.text.indexOf('\\') >= 0) {
// Hack to avoid problems cause indirectly by:
// https://github.com/Microsoft/TypeScript/issues/20192
// This avoids the string escaping normally performed for a string relying on that
// TypeScript just emits the text raw for a numeric literal.
(result as any).kind = ts.SyntaxKind.NumericLiteral;
result.text = `"${escapeLiteral(result.text)}"`;
}
return result;
}
}

View File

@ -176,6 +176,14 @@ describe('TypeScriptNodeEmitter', () => {
]).toStmt())
.replace(/\s+/gm, ''))
.toEqual(`({someKey:1,a:"a","b":"b","*":"star"});`);
// Regressions #22774
expect(emitStmt(o.literal('\\0025BC').toStmt())).toEqual('"\\\\0025BC";');
expect(emitStmt(o.literal('"some value"').toStmt())).toEqual('"\\"some value\\"";');
expect(emitStmt(o.literal('"some \\0025BC value"').toStmt()))
.toEqual('"\\"some \\\\0025BC value\\"";');
expect(emitStmt(o.literal('\n \\0025BC \n ').toStmt())).toEqual('"\\n \\\\0025BC \\n ";');
expect(emitStmt(o.literal('\r \\0025BC \r ').toStmt())).toEqual('"\\r \\\\0025BC \\r ";');
});
it('should support blank literals', () => {