Require decoratorsBeforeExport option for decorators (#8465)
* Require decoratorsBeforeExport option for syntax-decorators * Also babylon * Enable test
This commit is contained in:
parent
1e0b649485
commit
d79b5eeeff
@ -23,7 +23,9 @@ describe("parse", function() {
|
|||||||
const output = require(fixture("output.json"));
|
const output = require(fixture("output.json"));
|
||||||
|
|
||||||
const result = parse(input, {
|
const result = parse(input, {
|
||||||
parserOpts: { plugins: ["decorators"] },
|
parserOpts: {
|
||||||
|
plugins: [["decorators", { decoratorsBeforeExport: false }]],
|
||||||
|
},
|
||||||
cwd: fixture(),
|
cwd: fixture(),
|
||||||
});
|
});
|
||||||
expect(JSON.parse(JSON.stringify(result))).toEqual(output);
|
expect(JSON.parse(JSON.stringify(result))).toEqual(output);
|
||||||
|
|||||||
@ -41,13 +41,26 @@ export function getPluginOption(
|
|||||||
const PIPELINE_PROPOSALS = ["minimal"];
|
const PIPELINE_PROPOSALS = ["minimal"];
|
||||||
|
|
||||||
export function validatePlugins(plugins: PluginList) {
|
export function validatePlugins(plugins: PluginList) {
|
||||||
if (
|
if (hasPlugin(plugins, "decorators")) {
|
||||||
hasPlugin(plugins, "decorators") &&
|
if (hasPlugin(plugins, "decorators-legacy")) {
|
||||||
hasPlugin(plugins, "decorators-legacy")
|
throw new Error(
|
||||||
) {
|
"Cannot use the decorators and decorators-legacy plugin together",
|
||||||
throw new Error(
|
);
|
||||||
"Cannot use the decorators and decorators-legacy plugin together",
|
}
|
||||||
|
|
||||||
|
const decoratorsBeforeExport = getPluginOption(
|
||||||
|
plugins,
|
||||||
|
"decorators",
|
||||||
|
"decoratorsBeforeExport",
|
||||||
);
|
);
|
||||||
|
if (decoratorsBeforeExport == null) {
|
||||||
|
throw new Error(
|
||||||
|
"The 'decorators' plugin requires a" +
|
||||||
|
" 'decoratorsBeforeExport' option, whose value must be a boolean.",
|
||||||
|
);
|
||||||
|
} else if (typeof decoratorsBeforeExport !== "boolean") {
|
||||||
|
throw new Error("'decoratorsBeforeExport' must be a boolean.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) {
|
if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) {
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["classProperties", "classPrivateProperties", "decorators"]
|
"plugins": [
|
||||||
|
"classProperties",
|
||||||
|
"classPrivateProperties",
|
||||||
|
["decorators", { "decoratorsBeforeExport": false }]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["decorators", "classProperties"]
|
"plugins": [
|
||||||
|
["decorators", { "decoratorsBeforeExport": false }],
|
||||||
|
"classProperties"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
["decorators", { "decoratorsBeforeExport": "yes" }]
|
||||||
|
],
|
||||||
|
"throws": "'decoratorsBeforeExport' must be a boolean."
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["decorators"],
|
||||||
|
"throws": "The 'decorators' plugin requires a 'decoratorsBeforeExport' option, whose value must be a boolean."
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["decorators"]
|
"plugins": [
|
||||||
|
["decorators", { "decoratorsBeforeExport": false }]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,7 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["classProperties", "classPrivateProperties", "decorators"]
|
"plugins": [
|
||||||
|
"classProperties",
|
||||||
|
"classPrivateProperties",
|
||||||
|
["decorators", { "decoratorsBeforeExport": false }]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["classProperties", "decorators"]
|
"plugins": [
|
||||||
|
"classProperties",
|
||||||
|
["decorators", { "decoratorsBeforeExport": false }]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,19 +9,56 @@ describe("plugin options", function() {
|
|||||||
// NOTE: This test is not specific about decorators, it can be applied
|
// NOTE: This test is not specific about decorators, it can be applied
|
||||||
// to any plugin with options.
|
// to any plugin with options.
|
||||||
|
|
||||||
const NAME = "decorators";
|
|
||||||
const OPT_1 = [NAME, { decoratorsBeforeExport: true }];
|
|
||||||
const OPT_2 = [NAME, { decoratorsBeforeExport: false }];
|
|
||||||
const SYNTAX_1 = "@dec export class C {}";
|
|
||||||
const SYNTAX_2 = "export @dec class C {}";
|
|
||||||
const SYNTAX_DEFAULT = "export @dec class C {}";
|
|
||||||
|
|
||||||
it("when they aren't specified", function() {
|
it("when they aren't specified", function() {
|
||||||
expect(getParser(SYNTAX_DEFAULT, [NAME, OPT_1])).not.toThrow();
|
const WITHOUT_FLAG = "flow";
|
||||||
expect(getParser(SYNTAX_DEFAULT, [NAME, OPT_2])).not.toThrow();
|
const WITH_FLAG = ["flow", { all: true }];
|
||||||
|
|
||||||
|
const CODE = "new Foo<x>(y)";
|
||||||
|
|
||||||
|
const AST_WITHOUT_FLAG = {
|
||||||
|
type: "BinaryExpression",
|
||||||
|
operator: ">",
|
||||||
|
left: {
|
||||||
|
type: "BinaryExpression",
|
||||||
|
operator: "<",
|
||||||
|
left: { type: "NewExpression" },
|
||||||
|
right: { type: "Identifier" },
|
||||||
|
},
|
||||||
|
right: { type: "Identifier", extra: { parenthesized: true } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const AST_WITH_FLAG = {
|
||||||
|
type: "NewExpression",
|
||||||
|
callee: { type: "Identifier" },
|
||||||
|
arguments: [{ type: "Identifier" }],
|
||||||
|
typeArguments: {
|
||||||
|
type: "TypeParameterInstantiation",
|
||||||
|
params: [
|
||||||
|
{ type: "GenericTypeAnnotation", id: { type: "Identifier" } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getParser(CODE, [WITHOUT_FLAG, WITH_FLAG])().program.body[0].expression,
|
||||||
|
).toMatchObject(AST_WITHOUT_FLAG);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getParser(CODE, [WITHOUT_FLAG])().program.body[0].expression,
|
||||||
|
).toMatchObject(AST_WITHOUT_FLAG);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getParser(CODE, [WITH_FLAG])().program.body[0].expression,
|
||||||
|
).toMatchObject(AST_WITH_FLAG);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when they are specified", function() {
|
it("when they are specified", function() {
|
||||||
|
const NAME = "decorators";
|
||||||
|
const OPT_1 = [NAME, { decoratorsBeforeExport: true }];
|
||||||
|
const OPT_2 = [NAME, { decoratorsBeforeExport: false }];
|
||||||
|
const SYNTAX_1 = "@dec export class C {}";
|
||||||
|
const SYNTAX_2 = "export @dec class C {}";
|
||||||
|
|
||||||
expect(getParser(SYNTAX_1, [OPT_1, OPT_2])).not.toThrow();
|
expect(getParser(SYNTAX_1, [OPT_1, OPT_2])).not.toThrow();
|
||||||
expect(getParser(SYNTAX_2, [OPT_2, OPT_1])).not.toThrow();
|
expect(getParser(SYNTAX_2, [OPT_2, OPT_1])).not.toThrow();
|
||||||
expect(getParser(SYNTAX_1, [OPT_2, OPT_1])).toThrow();
|
expect(getParser(SYNTAX_1, [OPT_2, OPT_1])).toThrow();
|
||||||
|
|||||||
@ -17,7 +17,14 @@ export default declare((api, options) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { decoratorsBeforeExport } = options;
|
const { decoratorsBeforeExport } = options;
|
||||||
if (decoratorsBeforeExport !== undefined) {
|
if (decoratorsBeforeExport === undefined) {
|
||||||
|
if (!legacy) {
|
||||||
|
throw new Error(
|
||||||
|
"The '@babel/plugin-syntax-decorators' plugin requires a" +
|
||||||
|
" 'decoratorsBeforeExport' option, whose value must be a boolean.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (legacy) {
|
if (legacy) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'decoratorsBeforeExport' can't be used with legacy decorators.",
|
"'decoratorsBeforeExport' can't be used with legacy decorators.",
|
||||||
|
|||||||
@ -37,6 +37,10 @@ describe("'decoratorsBeforeExport' option", function() {
|
|||||||
expect(makeParser("", { decoratorsBeforeExport: "before" })).toThrow();
|
expect(makeParser("", { decoratorsBeforeExport: "before" })).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.skip("is required", function() {
|
||||||
|
expect(makeParser("", { legacy: false })).toThrow(/decoratorsBeforeExport/);
|
||||||
|
});
|
||||||
|
|
||||||
test("is incompatible with legacy", function() {
|
test("is incompatible with legacy", function() {
|
||||||
expect(
|
expect(
|
||||||
makeParser("", { decoratorsBeforeExport: false, legacy: true }),
|
makeParser("", { decoratorsBeforeExport: false, legacy: true }),
|
||||||
@ -47,8 +51,6 @@ describe("'decoratorsBeforeExport' option", function() {
|
|||||||
const AFTER = "export @dec class Foo {}";
|
const AFTER = "export @dec class Foo {}";
|
||||||
|
|
||||||
// These are skipped
|
// These are skipped
|
||||||
run(BEFORE, undefined, true);
|
|
||||||
run(AFTER, undefined, false);
|
|
||||||
run(BEFORE, true, false);
|
run(BEFORE, true, false);
|
||||||
run(AFTER, true, true);
|
run(AFTER, true, true);
|
||||||
run(BEFORE, false, true);
|
run(BEFORE, false, true);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user