Correctly output escapes in directives (#9501)
This commit is contained in:
parent
0f685d9b42
commit
83cbc11d46
@ -50,8 +50,35 @@ export function Directive(node: Object) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
// These regexes match an even number of \ followed by a quote
|
||||
const unescapedSingleQuoteRE = /(?:^|[^\\])(?:\\\\)*'/;
|
||||
const unescapedDoubleQuoteRE = /(?:^|[^\\])(?:\\\\)*"/;
|
||||
|
||||
export function DirectiveLiteral(node: Object) {
|
||||
const raw = this.getPossibleRaw(node);
|
||||
if (raw != null) {
|
||||
this.token(raw);
|
||||
return;
|
||||
}
|
||||
|
||||
const { value } = node;
|
||||
|
||||
// NOTE: In directives we can't change escapings,
|
||||
// because they change the behavior.
|
||||
// e.g. "us\x65 string" (\x65 is e) is not a "use strict" directive.
|
||||
|
||||
if (!unescapedDoubleQuoteRE.test(value)) {
|
||||
this.token(`"${value}"`);
|
||||
} else if (!unescapedSingleQuoteRE.test(value)) {
|
||||
this.token(`'${value}'`);
|
||||
} else {
|
||||
throw new Error(
|
||||
"Malformed AST: it is not possible to print a directive containing" +
|
||||
" both unescaped single and double quotes.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function InterpreterDirective(node: Object) {
|
||||
this.token(`#!${node.value}\n`);
|
||||
}
|
||||
|
||||
export { StringLiteral as DirectiveLiteral } from "./types";
|
||||
|
||||
@ -1 +1,2 @@
|
||||
0; // Not a directive
|
||||
"©";
|
||||
|
||||
@ -1 +1,2 @@
|
||||
0;// Not a directive
|
||||
"\u00A9";
|
||||
@ -384,6 +384,48 @@ describe("programmatic generation", function() {
|
||||
[key: any]: number
|
||||
}`);
|
||||
});
|
||||
|
||||
describe("directives", function() {
|
||||
it("preserves escapes", function() {
|
||||
const directive = t.directive(
|
||||
t.directiveLiteral(String.raw`us\x65 strict`),
|
||||
);
|
||||
const output = generate(directive).code;
|
||||
|
||||
expect(output).toBe(String.raw`"us\x65 strict";`);
|
||||
});
|
||||
|
||||
it("preserves escapes in minified output", function() {
|
||||
// https://github.com/babel/babel/issues/4767
|
||||
|
||||
const directive = t.directive(t.directiveLiteral(String.raw`foo\n\t\r`));
|
||||
const output = generate(directive, { minified: true }).code;
|
||||
|
||||
expect(output).toBe(String.raw`"foo\n\t\r";`);
|
||||
});
|
||||
|
||||
it("unescaped single quote", function() {
|
||||
const directive = t.directive(t.directiveLiteral(String.raw`'\'\"`));
|
||||
const output = generate(directive).code;
|
||||
|
||||
expect(output).toBe(String.raw`"'\'\"";`);
|
||||
});
|
||||
|
||||
it("unescaped double quote", function() {
|
||||
const directive = t.directive(t.directiveLiteral(String.raw`"\'\"`));
|
||||
const output = generate(directive).code;
|
||||
|
||||
expect(output).toBe(String.raw`'"\'\"';`);
|
||||
});
|
||||
|
||||
it("unescaped single and double quotes together throw", function() {
|
||||
const directive = t.directive(t.directiveLiteral(String.raw`'"`));
|
||||
|
||||
expect(() => {
|
||||
generate(directive);
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("CodeGenerator", function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user