Require decoratorsBeforeExport option for decorators (#8465)
* Require decoratorsBeforeExport option for syntax-decorators * Also babylon * Enable test
This commit is contained in:
@@ -41,13 +41,26 @@ export function getPluginOption(
|
||||
const PIPELINE_PROPOSALS = ["minimal"];
|
||||
|
||||
export function validatePlugins(plugins: PluginList) {
|
||||
if (
|
||||
hasPlugin(plugins, "decorators") &&
|
||||
hasPlugin(plugins, "decorators-legacy")
|
||||
) {
|
||||
throw new Error(
|
||||
"Cannot use the decorators and decorators-legacy plugin together",
|
||||
if (hasPlugin(plugins, "decorators")) {
|
||||
if (hasPlugin(plugins, "decorators-legacy")) {
|
||||
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")) {
|
||||
|
||||
@@ -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
|
||||
// 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() {
|
||||
expect(getParser(SYNTAX_DEFAULT, [NAME, OPT_1])).not.toThrow();
|
||||
expect(getParser(SYNTAX_DEFAULT, [NAME, OPT_2])).not.toThrow();
|
||||
const WITHOUT_FLAG = "flow";
|
||||
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() {
|
||||
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_2, [OPT_2, OPT_1])).not.toThrow();
|
||||
expect(getParser(SYNTAX_1, [OPT_2, OPT_1])).toThrow();
|
||||
|
||||
Reference in New Issue
Block a user