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();
|
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) {
|
export function InterpreterDirective(node: Object) {
|
||||||
this.token(`#!${node.value}\n`);
|
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";
|
"\u00A9";
|
||||||
@ -384,6 +384,48 @@ describe("programmatic generation", function() {
|
|||||||
[key: any]: number
|
[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() {
|
describe("CodeGenerator", function() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user