babel/packages/babel-parser/src/plugin-utils.js
mAAdhaTTah 4521204ea0 Merge branch 'master' into implement-smart-pipeline-in-parser
* 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
2018-11-03 14:00:12 -04:00

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,
};