* master: (222 commits) Set correct methods name Use toPropertyKey in the "decorate" helper Allow function types in type params within arrow return types (#8954) Fix message when plugin of a wrong type is passed (#8950) rename colliding let bindings with for loop init (#8937) edge incomplete support for arrow destructuring (babel #8349) (#8926) fix single-arg async arrows when retainLines=true (#8868) [flow] Explicit inexact objects with `...` (#8884) Update preset-env data (#8898) Treat break inside block inside loop (#8914) fixed "source map" formatting in comment (#8878) [skip ci] fix typo in contributing guidelines (#8901) [skip ci] fix: Expression x === 'y' && '' should not evaluate to undefined. (#8880) fixed an extra word Fixes #8865 (#8866) v7.1.4 v7.1.3 Bump Babel deps (#8770) flow-bin@0.82.0 (#8832) Insertafter jsx fix (#8833) ... # Conflicts: # packages/babel-parser/src/tokenizer/index.js # packages/babel-parser/test/fixtures/experimental/class-private-properties/failure-numeric-literal/options.json # packages/babel-parser/test/fixtures/experimental/pipeline-operator/invalid-proposal/options.json
100 lines
2.7 KiB
JavaScript
100 lines
2.7 KiB
JavaScript
// @flow
|
|
|
|
import type Parser from "./parser";
|
|
|
|
export type Plugin = string | [string, Object];
|
|
|
|
export type PluginList = $ReadOnlyArray<Plugin>;
|
|
|
|
export type MixinPlugin = (superClass: Class<Parser>) => Class<Parser>;
|
|
|
|
export function hasPlugin(plugins: PluginList, name: string): boolean {
|
|
return plugins.some(plugin => {
|
|
if (Array.isArray(plugin)) {
|
|
return plugin[0] === name;
|
|
} else {
|
|
return plugin === name;
|
|
}
|
|
});
|
|
}
|
|
|
|
export function getPluginOption(
|
|
plugins: PluginList,
|
|
name: string,
|
|
option: string,
|
|
) {
|
|
const plugin = plugins.find(plugin => {
|
|
if (Array.isArray(plugin)) {
|
|
return plugin[0] === name;
|
|
} else {
|
|
return plugin === name;
|
|
}
|
|
});
|
|
|
|
if (plugin && Array.isArray(plugin)) {
|
|
return plugin[1][option];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
const PIPELINE_PROPOSALS = ["minimal", "smart"];
|
|
|
|
export function validatePlugins(plugins: PluginList) {
|
|
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. If you are migrating from" +
|
|
" Babylon/Babel 6 or want to use the old decorators proposal, you" +
|
|
" should use the 'decorators-legacy' plugin instead of 'decorators'.",
|
|
);
|
|
} else if (typeof decoratorsBeforeExport !== "boolean") {
|
|
throw new Error("'decoratorsBeforeExport' must be a boolean.");
|
|
}
|
|
}
|
|
|
|
if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) {
|
|
throw new Error("Cannot combine flow and typescript plugins.");
|
|
}
|
|
|
|
if (
|
|
hasPlugin(plugins, "pipelineOperator") &&
|
|
!PIPELINE_PROPOSALS.includes(
|
|
getPluginOption(plugins, "pipelineOperator", "proposal"),
|
|
)
|
|
) {
|
|
throw new Error(
|
|
"'pipelineOperator' requires 'proposal' option whose value should be one of: " +
|
|
PIPELINE_PROPOSALS.map(p => `'${p}'`).join(", "),
|
|
);
|
|
}
|
|
}
|
|
|
|
// These plugins are defined using a mixin which extends the parser class.
|
|
|
|
import estree from "./plugins/estree";
|
|
import flow from "./plugins/flow";
|
|
import jsx from "./plugins/jsx";
|
|
import typescript from "./plugins/typescript";
|
|
|
|
// NOTE: estree must load first; flow and typescript must load last.
|
|
export const mixinPluginNames = ["estree", "jsx", "flow", "typescript"];
|
|
export const mixinPlugins: { [name: string]: MixinPlugin } = {
|
|
estree,
|
|
jsx,
|
|
flow,
|
|
typescript,
|
|
};
|