Merge branch 'master' into feat-use-charcode-constants

This commit is contained in:
Sven SAULEAU 2017-11-03 08:52:54 +01:00 committed by GitHub
commit 233e60c765
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1003 additions and 462 deletions

View File

@ -242,6 +242,7 @@ delete opts.quiet;
delete opts.configFile;
delete opts.deleteDirOnStart;
delete opts.keepFileExtension;
delete opts.relative;
// Commander will default the "--no-" arguments to true, but we want to leave them undefined so that
// @babel/core can handle the default-assignment logic on its own.

View File

@ -4,6 +4,12 @@ import { getEnv } from "./helpers/environment";
import path from "path";
import micromatch from "micromatch";
import buildDebug from "debug";
import {
validate,
type ValidatedOptions,
type PluginList,
type IgnoreList,
} from "./options";
const debug = buildDebug("babel:config:config-chain");
@ -11,26 +17,31 @@ import { findConfigs, loadConfig, type ConfigFile } from "./loading/files";
import { makeWeakCache, makeStrongCache } from "./caching";
type ConfigItem = {
type: "options" | "arguments",
options: {},
dirname: string,
alias: string,
loc: string,
};
type ConfigRaw = {
type: "options" | "arguments",
options: {},
export type ConfigItem = {
type: "arguments" | "env" | "file",
options: ValidatedOptions,
alias: string,
dirname: string,
};
export default function buildConfigChain(opts: {}): Array<ConfigItem> | null {
if (typeof opts.filename !== "string" && opts.filename != null) {
throw new Error(".filename must be a string, null, or undefined");
}
type ConfigPart =
| {
part: "config",
config: ConfigItem,
ignore: ?IgnoreList,
only: ?IgnoreList,
activeEnv: string | null,
}
| {
part: "extends",
path: string,
dirname: string,
activeEnv: string | null,
};
export default function buildConfigChain(
opts: ValidatedOptions,
): Array<ConfigItem> | null {
const filename = opts.filename ? path.resolve(opts.filename) : null;
const builder = new ConfigChainBuilder(
filename ? new LoadedFile(filename) : null,
@ -58,21 +69,34 @@ export default function buildConfigChain(opts: {}): Array<ConfigItem> | null {
class ConfigChainBuilder {
file: LoadedFile | null;
configs: Array<ConfigItem> = [];
seenFiles: Set<ConfigFile> = new Set();
constructor(file: LoadedFile | null) {
this.file = file;
}
mergeConfigArguments(opts: {}, dirname: string, envKey: string) {
mergeConfigArguments(
opts: ValidatedOptions,
dirname: string,
envKey: string,
) {
flattenArgumentsOptionsParts(opts, dirname, envKey).forEach(part =>
this._processConfigPart(part, envKey),
);
}
mergeConfigFile(file: ConfigFile, envKey: string) {
flattenFileOptionsParts(file)(envKey).forEach(part =>
this._processConfigPart(part, envKey),
);
if (this.seenFiles.has(file)) {
throw new Error(
`Cycle detected in Babel configuration file through "${file.filepath}".`,
);
}
const parts = flattenFileOptionsParts(file)(envKey);
this.seenFiles.add(file);
parts.forEach(part => this._processConfigPart(part, envKey));
this.seenFiles.delete(file);
}
_processConfigPart(part: ConfigPart, envKey: string) {
@ -92,14 +116,7 @@ class ConfigChainBuilder {
this.configs.push(part.config);
} else {
const extendsConfig = loadConfig(part.path, part.dirname);
const existingConfig = this.configs.some(config => {
return config.alias === extendsConfig.filepath;
});
if (!existingConfig) {
this.mergeConfigFile(extendsConfig, envKey);
}
this.mergeConfigFile(loadConfig(part.path, part.dirname), envKey);
}
}
}
@ -110,43 +127,26 @@ class ConfigChainBuilder {
* object identity preserved between calls so that they can be used for caching.
*/
function flattenArgumentsOptionsParts(
opts: {},
opts: ValidatedOptions,
dirname: string,
envKey: string,
): Array<ConfigPart> {
const {
env,
plugins,
presets,
passPerPreset,
extends: extendsPath,
...options
} = opts;
const raw = [];
const env = typeof opts.env === "object" ? opts.env : null;
const plugins = Array.isArray(opts.plugins) ? opts.plugins : null;
const presets = Array.isArray(opts.presets) ? opts.presets : null;
const passPerPreset =
typeof opts.passPerPreset === "boolean" ? opts.passPerPreset : false;
if (env) {
raw.push(...flattenArgumentsEnvOptionsParts(env)(dirname)(envKey));
}
const innerOpts = Object.assign({}, opts);
// If the env, plugins, and presets values on the object aren't arrays or
// objects, leave them in the base opts so that normal options validation
// will throw errors on them later.
if (env) delete innerOpts.env;
if (plugins) delete innerOpts.plugins;
if (presets) {
delete innerOpts.presets;
delete innerOpts.passPerPreset;
}
delete innerOpts.extends;
if (Object.keys(innerOpts).length > 0) {
raw.push(
...flattenOptionsParts({
type: "arguments",
options: innerOpts,
alias: "base",
dirname,
}),
);
if (Object.keys(options).length > 0) {
raw.push(...flattenOptionsParts(buildArgumentsItem(options, dirname)));
}
if (plugins) {
@ -154,14 +154,14 @@ function flattenArgumentsOptionsParts(
}
if (presets) {
raw.push(
...flattenArgumentsPresetsOptionsParts(presets)(passPerPreset)(dirname),
...flattenArgumentsPresetsOptionsParts(presets)(!!passPerPreset)(dirname),
);
}
if (opts.extends != null) {
if (extendsPath != null) {
raw.push(
...flattenOptionsParts(
buildArgumentsRawConfig({ extends: opts.extends }, dirname),
buildArgumentsItem({ extends: extendsPath }, dirname),
),
);
}
@ -174,10 +174,10 @@ function flattenArgumentsOptionsParts(
* the object identity of the 'env' object.
*/
const flattenArgumentsEnvOptionsParts = makeWeakCache((env: {}) => {
const options = { env };
const options: ValidatedOptions = { env };
return makeStrongCache((dirname: string) =>
flattenOptionsPartsLookup(buildArgumentsRawConfig(options, dirname)),
flattenOptionsPartsLookup(buildArgumentsItem(options, dirname)),
);
});
@ -186,11 +186,11 @@ const flattenArgumentsEnvOptionsParts = makeWeakCache((env: {}) => {
* the object identity of the 'plugins' object.
*/
const flattenArgumentsPluginsOptionsParts = makeWeakCache(
(plugins: Array<mixed>) => {
const options = { plugins };
(plugins: PluginList) => {
const options: ValidatedOptions = { plugins };
return makeStrongCache((dirname: string) =>
flattenOptionsParts(buildArgumentsRawConfig(options, dirname)),
flattenOptionsParts(buildArgumentsItem(options, dirname)),
);
},
);
@ -200,20 +200,23 @@ const flattenArgumentsPluginsOptionsParts = makeWeakCache(
* the object identity of the 'presets' object.
*/
const flattenArgumentsPresetsOptionsParts = makeWeakCache(
(presets: Array<mixed>) =>
makeStrongCache((passPerPreset: ?boolean) => {
(presets: PluginList) =>
makeStrongCache((passPerPreset: boolean) => {
// The concept of passPerPreset is integrally tied to the preset list
// so unfortunately we need to copy both values here, adding an extra
// layer of caching functions.
const options = { presets, passPerPreset };
return makeStrongCache((dirname: string) =>
flattenOptionsParts(buildArgumentsRawConfig(options, dirname)),
flattenOptionsParts(buildArgumentsItem(options, dirname)),
);
}),
);
function buildArgumentsRawConfig(options: {}, dirname: string): ConfigRaw {
function buildArgumentsItem(
options: ValidatedOptions,
dirname: string,
): ConfigItem {
return {
type: "arguments",
options,
@ -229,8 +232,8 @@ function buildArgumentsRawConfig(options: {}, dirname: string): ConfigRaw {
*/
const flattenFileOptionsParts = makeWeakCache((file: ConfigFile) => {
return flattenOptionsPartsLookup({
type: "options",
options: file.options,
type: "file",
options: validate("file", file.options),
alias: file.filepath,
dirname: file.dirname,
});
@ -241,7 +244,7 @@ const flattenFileOptionsParts = makeWeakCache((file: ConfigFile) => {
* the environment passed as the first argument.
*/
function flattenOptionsPartsLookup(
config: ConfigRaw,
config: ConfigItem,
): (string | null) => Array<ConfigPart> {
const parts = flattenOptionsParts(config);
@ -263,107 +266,45 @@ function flattenOptionsPartsLookup(
return envKey => lookup.get(envKey) || def;
}
type ConfigPart =
| {
part: "config",
config: ConfigItem,
ignore: ?Array<mixed>,
only: ?Array<mixed>,
activeEnv: string | null,
}
| {
part: "extends",
path: string,
dirname: string,
activeEnv: string | null,
};
/**
* Given a generic config object, flatten it into its various parts so that
* then can be cached and processed later.
*/
function flattenOptionsParts(
rawConfig: ConfigRaw,
config: ConfigItem,
activeEnv: string | null = null,
): Array<ConfigPart> {
const { type, options: rawOpts, alias, dirname } = rawConfig;
if (rawOpts.ignore != null && !Array.isArray(rawOpts.ignore)) {
throw new Error(
`.ignore should be an array, ${JSON.stringify(rawOpts.ignore)} given`,
);
}
if (rawOpts.only != null && !Array.isArray(rawOpts.only)) {
throw new Error(
`.only should be an array, ${JSON.stringify(rawOpts.only)} given`,
);
}
const ignore = rawOpts.ignore || null;
const only = rawOpts.only || null;
const { options: rawOpts, alias, dirname } = config;
const parts = [];
if (
rawOpts.env != null &&
(typeof rawOpts.env !== "object" || Array.isArray(rawOpts.env))
) {
throw new Error(".env block must be an object, null, or undefined");
if (rawOpts.env) {
for (const envKey of Object.keys(rawOpts.env)) {
if (rawOpts.env[envKey]) {
parts.push(
...flattenOptionsParts(
{
type: "env",
options: rawOpts.env[envKey],
alias: alias + `.env.${envKey}`,
dirname,
},
envKey,
),
);
}
}
}
const rawEnv = rawOpts.env || {};
Object.keys(rawEnv).forEach(envKey => {
const envOpts = rawEnv[envKey];
if (envOpts !== undefined && activeEnv !== null && activeEnv !== envKey) {
throw new Error(`Unreachable .env[${envKey}] block detected`);
}
if (
envOpts != null &&
(typeof envOpts !== "object" || Array.isArray(envOpts))
) {
throw new Error(".env[...] block must be an object, null, or undefined");
}
if (envOpts) {
parts.push(
...flattenOptionsParts(
{
type,
options: envOpts,
alias: alias + `.env.${envKey}`,
dirname,
},
envKey,
),
);
}
});
const options = Object.assign({}, rawOpts);
delete options.env;
delete options.extends;
parts.push({
part: "config",
config: {
type,
options,
alias,
loc: alias,
dirname,
},
ignore,
only,
config,
ignore: rawOpts.ignore,
only: rawOpts.only,
activeEnv,
});
if (rawOpts.extends != null) {
if (typeof rawOpts.extends !== "string") {
throw new Error(".extends must be a string");
}
parts.push({
part: "extends",
path: rawOpts.extends,
@ -390,8 +331,8 @@ class LoadedFile {
* Tests if a filename should be ignored based on "ignore" and "only" options.
*/
shouldIgnore(
ignore: ?Array<mixed>,
only: ?Array<mixed>,
ignore: ?IgnoreList,
only: ?IgnoreList,
dirname: string,
): boolean {
if (ignore) {
@ -425,7 +366,7 @@ class LoadedFile {
* Returns result of calling function with filename if pattern is a function.
* Otherwise returns result of matching pattern Regex with filename.
*/
_matchesPatterns(patterns: Array<mixed>, dirname: string): boolean {
_matchesPatterns(patterns: IgnoreList, dirname: string): boolean {
const res = [];
const strings = [];
const fns = [];
@ -433,12 +374,7 @@ class LoadedFile {
patterns.forEach(pattern => {
if (typeof pattern === "string") strings.push(pattern);
else if (typeof pattern === "function") fns.push(pattern);
else if (pattern instanceof RegExp) res.push(pattern);
else {
throw new Error(
"Patterns must be a string, function, or regular expression",
);
}
else res.push(pattern);
});
const filename = this.filename;

View File

@ -31,7 +31,7 @@ export function makeStrongCache<ArgT, ResultT>(
* configures its caching behavior. Cached values are stored weakly and the function argument must be
* an object type.
*/
export function makeWeakCache<ArgT: {} | Array<*>, ResultT>(
export function makeWeakCache<ArgT: {} | Array<*> | $ReadOnlyArray<*>, ResultT>(
handler: (ArgT, CacheConfigurator) => ResultT,
autoPermacache?: boolean,
): ArgT => ResultT {

View File

@ -16,7 +16,7 @@ export type PluginPasses = Array<PluginPassList>;
* Standard API for loading Babel configuration data. Not for public consumption.
*/
export default function loadConfig(opts: mixed): ResolvedConfig | null {
if (opts != null && typeof opts !== "object") {
if (opts != null && (typeof opts !== "object" || Array.isArray(opts))) {
throw new Error("Babel options must be an object, null, or undefined");
}

View File

@ -0,0 +1,179 @@
// @flow
import type {
IgnoreList,
IgnoreItem,
PluginList,
PluginItem,
PluginTarget,
SourceMapsOption,
SourceTypeOption,
CompactOption,
RootInputSourceMapOption,
} from "./options";
export function assertSourceMaps(
key: string,
value: mixed,
): SourceMapsOption | void {
if (
value !== undefined &&
typeof value !== "boolean" &&
value !== "inline" &&
value !== "both"
) {
throw new Error(
`.${key} must be a boolean, "inline", "both", or undefined`,
);
}
return value;
}
export function assertCompact(key: string, value: mixed): CompactOption | void {
if (value !== undefined && typeof value !== "boolean" && value !== "auto") {
throw new Error(`.${key} must be a boolean, "auto", or undefined`);
}
return value;
}
export function assertSourceType(
key: string,
value: mixed,
): SourceTypeOption | void {
if (value !== undefined && value !== "module" && value !== "script") {
throw new Error(`.${key} must be "module", "script", or undefined`);
}
return value;
}
export function assertInputSourceMap(
key: string,
value: mixed,
): RootInputSourceMapOption | void {
if (
value !== undefined &&
typeof value !== "boolean" &&
(typeof value !== "object" || !value)
) {
throw new Error(".inputSourceMap must be a boolean, object, or undefined");
}
return value;
}
export function assertString(key: string, value: mixed): string | void {
if (value !== undefined && typeof value !== "string") {
throw new Error(`.${key} must be a string, or undefined`);
}
return value;
}
export function assertFunction(key: string, value: mixed): Function | void {
if (value !== undefined && typeof value !== "function") {
throw new Error(`.${key} must be a function, or undefined`);
}
return value;
}
export function assertBoolean(key: string, value: mixed): boolean | void {
if (value !== undefined && typeof value !== "boolean") {
throw new Error(`.${key} must be a boolean, or undefined`);
}
return value;
}
export function assertObject(key: string, value: mixed): {} | void {
if (
value !== undefined &&
(typeof value !== "object" || Array.isArray(value) || !value)
) {
throw new Error(`.${key} must be an object, or undefined`);
}
return value;
}
export function assertIgnoreList(key: string, value: mixed): IgnoreList | void {
const arr = assertArray(key, value);
if (arr) {
arr.forEach((item, i) => assertIgnoreItem(key, i, item));
}
return (arr: any);
}
function assertIgnoreItem(
key: string,
index: number,
value: mixed,
): IgnoreItem {
if (
typeof value !== "string" &&
typeof value !== "function" &&
!(value instanceof RegExp)
) {
throw new Error(
`.${key}[${index}] must be an array of string/Funtion/RegExp values, or or undefined`,
);
}
return value;
}
export function assertPluginList(key: string, value: mixed): PluginList | void {
const arr = assertArray(key, value);
if (arr) {
// Loop instead of using `.map` in order to preserve object identity
// for plugin array for use during config chain processing.
arr.forEach((item, i) => assertPluginItem(key, i, item));
}
return (arr: any);
}
function assertPluginItem(
key: string,
index: number,
value: mixed,
): PluginItem {
if (Array.isArray(value)) {
if (value.length === 0) {
throw new Error(`.${key}[${index}] must include an object`);
}
if (value.length > 2) {
throw new Error(`.${key}[${index}] may only be a two-tuple`);
}
assertPluginTarget(key, index, true, value[0]);
if (value.length === 2) {
const opts = value[1];
if (opts != null && (typeof opts !== "object" || Array.isArray(opts))) {
throw new Error(`.${key}[${index}][1] must be an object, or undefined`);
}
}
} else {
assertPluginTarget(key, index, false, value);
}
return (value: any);
}
function assertPluginTarget(
key: string,
index: number,
inArray: boolean,
value: mixed,
): PluginTarget {
if (
(typeof value !== "object" || !value) &&
typeof value !== "string" &&
typeof value !== "function"
) {
throw new Error(
`.${key}[${index}]${inArray
? `[0]`
: ""} must be a string, object, function`,
);
}
return value;
}
function assertArray(key: string, value: mixed): ?$ReadOnlyArray<mixed> {
if (value != null && !Array.isArray(value)) {
throw new Error(`.${key} must be an array, or undefined`);
}
return value;
}

View File

@ -4,13 +4,13 @@ import * as context from "../index";
import Plugin from "./plugin";
import defaults from "lodash/defaults";
import merge from "lodash/merge";
import removed from "./removed";
import buildConfigChain from "./build-config-chain";
import buildConfigChain, { type ConfigItem } from "./build-config-chain";
import path from "path";
import traverse from "@babel/traverse";
import clone from "lodash/clone";
import { makeWeakCache } from "./caching";
import { getEnv } from "./helpers/environment";
import { validate, type ValidatedOptions, type PluginItem } from "./options";
import {
loadPlugin,
@ -19,54 +19,14 @@ import {
loadGenerator,
} from "./loading/files";
type MergeOptions = {
+type: "arguments" | "options" | "preset",
options: {},
alias: string,
loc: string,
dirname: string,
};
const optionNames = new Set([
"relative",
"filename",
"filenameRelative",
"inputSourceMap",
"env",
"mode",
"retainLines",
"highlightCode",
"suppressDeprecationMessages",
"presets",
"plugins",
"ignore",
"only",
"code",
"ast",
"extends",
"comments",
"shouldPrintComment",
"wrapPluginVisitorMethod",
"compact",
"minified",
"sourceMaps",
"sourceMapTarget",
"sourceFileName",
"sourceRoot",
"babelrc",
"sourceType",
"auxiliaryCommentBefore",
"auxiliaryCommentAfter",
"getModuleId",
"moduleRoot",
"moduleIds",
"moduleId",
"passPerPreset",
// Deprecate top level parserOpts
"parserOpts",
// Deprecate top level generatorOpts
"generatorOpts",
]);
type MergeOptions =
| ConfigItem
| {
type: "preset",
options: ValidatedOptions,
alias: string,
dirname: string,
};
const ALLOWED_PLUGIN_KEYS = new Set([
"name",
@ -86,11 +46,11 @@ export default function manageOptions(opts: {}): {
class OptionManager {
constructor() {
this.options = createInitialOptions();
this.options = {};
this.passes = [[]];
}
options: Object;
options: ValidatedOptions;
passes: Array<Array<Plugin>>;
/**
@ -112,12 +72,6 @@ class OptionManager {
loadPresetDescriptor(descriptor),
);
if (
config.options.passPerPreset != null &&
typeof config.options.passPerPreset !== "boolean"
) {
throw new Error(".passPerPreset must be a boolean or undefined");
}
const passPerPreset = config.options.passPerPreset;
pass = pass || this.passes[0];
@ -141,11 +95,27 @@ class OptionManager {
pass.unshift(...plugins);
}
merge(this.options, result.options);
const options = Object.assign({}, result.options);
delete options.extends;
delete options.env;
delete options.plugins;
delete options.presets;
delete options.passPerPreset;
// "sourceMap" is just aliased to sourceMap, so copy it over as
// we merge the options together.
if (options.sourceMap) {
options.sourceMaps = options.sourceMap;
delete options.sourceMap;
}
merge(this.options, options);
}
init(opts: {}) {
const configChain = buildConfigChain(opts);
init(inputOpts: {}) {
const args = validate("arguments", inputOpts);
const configChain = buildConfigChain(args);
if (!configChain) return null;
try {
@ -156,15 +126,13 @@ class OptionManager {
// There are a few case where thrown errors will try to annotate themselves multiple times, so
// to keep things simple we just bail out if re-wrapping the message.
if (!/^\[BABEL\]/.test(e.message)) {
const filename =
typeof opts.filename === "string" ? opts.filename : null;
e.message = `[BABEL] ${filename || "unknown"}: ${e.message}`;
e.message = `[BABEL] ${args.filename || "unknown"}: ${e.message}`;
}
throw e;
}
opts = this.options;
const opts: Object = merge(createInitialOptions(), this.options);
// Tack the passes onto the object itself so that, if this object is passed back to Babel a second time,
// it will be in the right structure to not change behavior.
@ -173,6 +141,7 @@ class OptionManager {
.slice(1)
.filter(plugins => plugins.length > 0)
.map(plugins => ({ plugins }));
opts.passPerPreset = opts.presets.length > 0;
if (opts.inputSourceMap) {
opts.sourceMaps = true;
@ -217,7 +186,6 @@ type BasicDescriptor = {
options: {} | void,
dirname: string,
alias: string,
loc: string,
};
type LoadedDescriptor = {
@ -225,64 +193,31 @@ type LoadedDescriptor = {
options: {},
dirname: string,
alias: string,
loc: string,
};
/**
* Load and validate the given config into a set of options, plugins, and presets.
*/
const loadConfig = makeWeakCache((config): {
const loadConfig = makeWeakCache((config: MergeOptions): {
options: {},
plugins: Array<BasicDescriptor>,
presets: Array<BasicDescriptor>,
} => {
const options = normalizeOptions(config);
if (
config.options.plugins != null &&
!Array.isArray(config.options.plugins)
) {
throw new Error(".plugins should be an array, null, or undefined");
}
const plugins = (config.options.plugins || []).map((plugin, index) =>
createDescriptor(plugin, loadPlugin, config.dirname, {
index,
alias: config.alias,
}),
);
const plugins = (config.options.plugins || []).map((plugin, index) => {
const { filepath, value, options } = normalizePair(
plugin,
loadPlugin,
config.dirname,
);
return {
alias: filepath || `${config.loc}$${index}`,
loc: filepath || config.loc,
value,
options,
dirname: config.dirname,
};
});
if (
config.options.presets != null &&
!Array.isArray(config.options.presets)
) {
throw new Error(".presets should be an array, null, or undefined");
}
const presets = (config.options.presets || []).map((preset, index) => {
const { filepath, value, options } = normalizePair(
preset,
loadPreset,
config.dirname,
);
return {
alias: filepath || `${config.loc}$${index}`,
loc: filepath || config.loc,
value,
options,
dirname: config.dirname,
};
});
const presets = (config.options.presets || []).map((preset, index) =>
createDescriptor(preset, loadPreset, config.dirname, {
index,
alias: config.alias,
}),
);
return { options, plugins, presets };
});
@ -292,7 +227,7 @@ const loadConfig = makeWeakCache((config): {
*/
const loadDescriptor = makeWeakCache(
(
{ value, options = {}, dirname, alias, loc }: BasicDescriptor,
{ value, options = {}, dirname, alias }: BasicDescriptor,
cache,
): LoadedDescriptor => {
let item = value;
@ -316,7 +251,7 @@ const loadDescriptor = makeWeakCache(
throw new Error("Plugin/Preset did not return an object.");
}
return { value: item, options, dirname, alias, loc };
return { value: item, options, dirname, alias };
},
);
@ -339,7 +274,7 @@ function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin {
const instantiatePlugin = makeWeakCache(
(
{ value: pluginObj, options, dirname, alias, loc }: LoadedDescriptor,
{ value: pluginObj, options, dirname, alias }: LoadedDescriptor,
cache,
): Plugin => {
Object.keys(pluginObj).forEach(key => {
@ -369,8 +304,7 @@ const instantiatePlugin = makeWeakCache(
let inherits;
if (plugin.inherits) {
inheritsDescriptor = {
alias: `${loc}$inherits`,
loc,
alias: `${alias}$inherits`,
value: plugin.inherits,
options,
dirname,
@ -405,12 +339,11 @@ const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => {
};
const instantiatePreset = makeWeakCache(
({ value, dirname, alias, loc }: LoadedDescriptor): MergeOptions => {
({ value, dirname, alias }: LoadedDescriptor): MergeOptions => {
return {
type: "preset",
options: value,
options: validate("preset", value),
alias,
loc,
dirname,
};
},
@ -420,72 +353,12 @@ const instantiatePreset = makeWeakCache(
* Validate and return the options object for the config.
*/
function normalizeOptions(config) {
const alias = config.alias || "foreign";
const type = config.type;
//
if (typeof config.options !== "object" || Array.isArray(config.options)) {
throw new TypeError(`Invalid options type for ${alias}`);
}
//
const options = Object.assign({}, config.options);
if (type !== "arguments") {
if (options.filename !== undefined) {
throw new Error(`${alias}.filename is only allowed as a root argument`);
}
if (options.babelrc !== undefined) {
throw new Error(`${alias}.babelrc is only allowed as a root argument`);
}
}
if (type === "preset") {
if (options.only !== undefined) {
throw new Error(`${alias}.only is not supported in a preset`);
}
if (options.ignore !== undefined) {
throw new Error(`${alias}.ignore is not supported in a preset`);
}
if (options.extends !== undefined) {
throw new Error(`${alias}.extends is not supported in a preset`);
}
if (options.env !== undefined) {
throw new Error(`${alias}.env is not supported in a preset`);
}
}
if (options.sourceMap !== undefined) {
if (options.sourceMaps !== undefined) {
throw new Error(`Both ${alias}.sourceMap and .sourceMaps have been set`);
}
options.sourceMaps = options.sourceMap;
delete options.sourceMap;
}
for (const key in options) {
// check for an unknown option
if (!optionNames.has(key)) {
if (removed[key]) {
const { message, version = 5 } = removed[key];
throw new ReferenceError(
`Using removed Babel ${version} option: ${alias}.${key} - ${message}`,
);
} else {
// eslint-disable-next-line max-len
const unknownOptErr = `Unknown option: ${alias}.${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`;
throw new ReferenceError(unknownOptErr);
}
}
}
if (options.parserOpts && typeof options.parserOpts.parser === "string") {
options.parserOpts = Object.assign({}, options.parserOpts);
options.parserOpts.parser = loadParser(
(options.parserOpts: any).parser = loadParser(
options.parserOpts.parser,
config.dirname,
).value;
@ -496,41 +369,34 @@ function normalizeOptions(config) {
typeof options.generatorOpts.generator === "string"
) {
options.generatorOpts = Object.assign({}, options.generatorOpts);
options.generatorOpts.generator = loadGenerator(
(options.generatorOpts: any).generator = loadGenerator(
options.generatorOpts.generator,
config.dirname,
).value;
}
delete options.passPerPreset;
delete options.plugins;
delete options.presets;
return options;
}
/**
* Given a plugin/preset item, resolve it into a standard format.
*/
function normalizePair(
pair: mixed,
function createDescriptor(
pair: PluginItem,
resolver,
dirname,
): {
filepath: string | null,
value: {} | Function,
options: {} | void,
} {
{
index,
alias,
}: {
index: number,
alias: string,
},
): BasicDescriptor {
let options;
let value = pair;
if (Array.isArray(pair)) {
if (pair.length > 2) {
throw new Error(
`Unexpected extra options ${JSON.stringify(pair.slice(2))}.`,
);
}
[value, options] = pair;
if (Array.isArray(value)) {
[value, options] = value;
}
let filepath = null;
@ -572,7 +438,12 @@ function normalizePair(
}
options = options || undefined;
return { filepath, value, options };
return {
alias: filepath || `${alias}$${index}`,
value,
options,
dirname,
};
}
function chain(a, b) {

View File

@ -0,0 +1,255 @@
// @flow
import removed from "./removed";
import {
assertString,
assertBoolean,
assertObject,
assertInputSourceMap,
assertIgnoreList,
assertPluginList,
assertFunction,
assertSourceMaps,
assertCompact,
assertSourceType,
} from "./option-assertions";
type ValidatorSet = {
[string]: Validator<any>,
};
type Validator<T> = (string, mixed) => T;
const ROOT_VALIDATORS: ValidatorSet = {
filename: (assertString: Validator<
$PropertyType<ValidatedOptions, "filename">,
>),
filenameRelative: (assertString: Validator<
$PropertyType<ValidatedOptions, "filenameRelative">,
>),
babelrc: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "babelrc">,
>),
code: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "code">>),
ast: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "ast">>),
};
const NONPRESET_VALIDATORS: ValidatorSet = {
extends: (assertString: Validator<
$PropertyType<ValidatedOptions, "extends">,
>),
env: (assertEnvSet: Validator<$PropertyType<ValidatedOptions, "env">>),
ignore: (assertIgnoreList: Validator<
$PropertyType<ValidatedOptions, "ignore">,
>),
only: (assertIgnoreList: Validator<$PropertyType<ValidatedOptions, "only">>),
};
const COMMON_VALIDATORS: ValidatorSet = {
// TODO: Should 'inputSourceMap' be moved to be a root-only option?
// We may want a boolean-only version to be a common option, with the
// object only allowed as a root config argument.
inputSourceMap: (assertInputSourceMap: Validator<
$PropertyType<ValidatedOptions, "inputSourceMap">,
>),
presets: (assertPluginList: Validator<
$PropertyType<ValidatedOptions, "presets">,
>),
plugins: (assertPluginList: Validator<
$PropertyType<ValidatedOptions, "plugins">,
>),
passPerPreset: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "passPerPreset">,
>),
retainLines: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "retainLines">,
>),
comments: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "comments">,
>),
shouldPrintComment: (assertFunction: Validator<
$PropertyType<ValidatedOptions, "shouldPrintComment">,
>),
compact: (assertCompact: Validator<
$PropertyType<ValidatedOptions, "compact">,
>),
minified: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "minified">,
>),
auxiliaryCommentBefore: (assertString: Validator<
$PropertyType<ValidatedOptions, "auxiliaryCommentBefore">,
>),
auxiliaryCommentAfter: (assertString: Validator<
$PropertyType<ValidatedOptions, "auxiliaryCommentAfter">,
>),
sourceType: (assertSourceType: Validator<
$PropertyType<ValidatedOptions, "sourceType">,
>),
wrapPluginVisitorMethod: (assertFunction: Validator<
$PropertyType<ValidatedOptions, "wrapPluginVisitorMethod">,
>),
highlightCode: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "highlightCode">,
>),
sourceMaps: (assertSourceMaps: Validator<
$PropertyType<ValidatedOptions, "sourceMaps">,
>),
sourceMap: (assertSourceMaps: Validator<
$PropertyType<ValidatedOptions, "sourceMap">,
>),
sourceMapTarget: (assertString: Validator<
$PropertyType<ValidatedOptions, "sourceMapTarget">,
>),
sourceFileName: (assertString: Validator<
$PropertyType<ValidatedOptions, "sourceFileName">,
>),
sourceRoot: (assertString: Validator<
$PropertyType<ValidatedOptions, "sourceRoot">,
>),
getModuleId: (assertFunction: Validator<
$PropertyType<ValidatedOptions, "getModuleId">,
>),
moduleRoot: (assertString: Validator<
$PropertyType<ValidatedOptions, "moduleRoot">,
>),
moduleIds: (assertBoolean: Validator<
$PropertyType<ValidatedOptions, "moduleIds">,
>),
moduleId: (assertString: Validator<
$PropertyType<ValidatedOptions, "moduleId">,
>),
parserOpts: (assertObject: Validator<
$PropertyType<ValidatedOptions, "parserOpts">,
>),
generatorOpts: (assertObject: Validator<
$PropertyType<ValidatedOptions, "generatorOpts">,
>),
};
export type ValidatedOptions = {
filename?: string,
filenameRelative?: string,
babelrc?: boolean,
code?: boolean,
ast?: boolean,
inputSourceMap?: RootInputSourceMapOption,
extends?: string,
env?: EnvSet<ValidatedOptions>,
ignore?: IgnoreList,
only?: IgnoreList,
presets?: PluginList,
plugins?: PluginList,
passPerPreset?: boolean,
// Options for @babel/generator
retainLines?: boolean,
comments?: boolean,
shouldPrintComment?: Function,
compact?: CompactOption,
minified?: boolean,
auxiliaryCommentBefore?: string,
auxiliaryCommentAfter?: string,
// Parser
sourceType?: SourceTypeOption,
wrapPluginVisitorMethod?: Function,
highlightCode?: boolean,
// Sourcemap generation options.
sourceMaps?: SourceMapsOption,
sourceMap?: SourceMapsOption,
sourceMapTarget?: string,
sourceFileName?: string,
sourceRoot?: string,
// AMD/UMD/SystemJS module naming options.
getModuleId?: Function,
moduleRoot?: string,
moduleIds?: boolean,
moduleId?: string,
// Deprecate top level parserOpts
parserOpts?: {},
// Deprecate top level generatorOpts
generatorOpts?: {},
};
export type EnvSet<T> = {
[string]: ?T,
};
export type IgnoreItem = string | Function | RegExp;
export type IgnoreList = $ReadOnlyArray<IgnoreItem>;
export type PluginTarget = string | {} | Function;
export type PluginItem = PluginTarget | [PluginTarget, {} | void];
export type PluginList = $ReadOnlyArray<PluginItem>;
export type SourceMapsOption = boolean | "inline" | "both";
export type SourceTypeOption = "module" | "script";
export type CompactOption = boolean | "auto";
export type RootInputSourceMapOption = {} | boolean;
export type OptionsType = "arguments" | "file" | "env" | "preset";
export function validate(type: OptionsType, opts: {}): ValidatedOptions {
assertNoDuplicateSourcemap(opts);
Object.keys(opts).forEach(key => {
if (type === "preset" && NONPRESET_VALIDATORS[key]) {
throw new Error(`.${key} is not allowed in preset options`);
}
if (type !== "arguments" && ROOT_VALIDATORS[key]) {
throw new Error(`.${key} is only allowed in root programmatic options`);
}
const validator =
COMMON_VALIDATORS[key] ||
NONPRESET_VALIDATORS[key] ||
ROOT_VALIDATORS[key];
if (validator) validator(key, opts[key]);
else throw buildUnknownError(key);
});
return (opts: any);
}
function buildUnknownError(key: string) {
if (removed[key]) {
const { message, version = 5 } = removed[key];
throw new ReferenceError(
`Using removed Babel ${version} option: .${key} - ${message}`,
);
} else {
// eslint-disable-next-line max-len
const unknownOptErr = `Unknown option: .${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`;
throw new ReferenceError(unknownOptErr);
}
}
function has(obj: {}, key: string) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function assertNoDuplicateSourcemap(opts: {}): void {
if (has(opts, "sourceMap") && has(opts, "sourceMaps")) {
throw new Error(".sourceMap is an alias for .sourceMaps, cannot use both");
}
}
function assertEnvSet(key: string, value: mixed): EnvSet<ValidatedOptions> {
const obj = assertObject(key, value);
if (obj) {
// Validate but don't copy the .env object in order to preserve
// object identity for use during config chain processing.
for (const key of Object.keys(obj)) {
const env = assertObject(key, obj[key]);
if (env) validate("env", env);
}
}
return (obj: any);
}

View File

@ -145,7 +145,7 @@ describe("api", function() {
babel.transform("", {
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
});
}, /Error: \[BABEL\] unknown: Unexpected falsy value: false/);
}, /.plugins\[1\] must be a string, object, function/);
});
it("options merge backwards", function() {
@ -530,31 +530,31 @@ describe("api", function() {
it("default", function() {
const result = babel.transform("foo;", {
env: {
development: { code: false },
development: { comments: false },
},
});
assert.equal(result.code, undefined);
assert.equal(result.options.comments, false);
});
it("BABEL_ENV", function() {
process.env.BABEL_ENV = "foo";
const result = babel.transform("foo;", {
env: {
foo: { code: false },
foo: { comments: false },
},
});
assert.equal(result.code, undefined);
assert.equal(result.options.comments, false);
});
it("NODE_ENV", function() {
process.env.NODE_ENV = "foo";
const result = babel.transform("foo;", {
env: {
foo: { code: false },
foo: { comments: false },
},
});
assert.equal(result.code, undefined);
assert.equal(result.options.comments, false);
});
});

View File

@ -72,7 +72,6 @@ describe("buildConfigChain", function() {
],
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -117,7 +116,6 @@ describe("buildConfigChain", function() {
],
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -374,30 +372,28 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
plugins: ["extended"],
},
alias: fixture("extended.babelrc.json"),
loc: fixture("extended.babelrc.json"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
extends: "./extended.babelrc.json",
plugins: ["root"],
},
alias: fixture(".babelrc"),
loc: fixture(".babelrc"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
@ -406,7 +402,6 @@ describe("buildConfigChain", function() {
filename: fixture("dir1", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -421,21 +416,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
plugins: ["dir2"],
},
alias: fixture("dir2", ".babelrc"),
loc: fixture("dir2", ".babelrc"),
dirname: fixture("dir2"),
},
{
@ -444,7 +437,6 @@ describe("buildConfigChain", function() {
filename: fixture("dir2", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -459,30 +451,28 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
plugins: ["extended"],
},
alias: fixture("extended.babelrc.json"),
loc: fixture("extended.babelrc.json"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
extends: "./extended.babelrc.json",
plugins: ["root"],
},
alias: fixture(".babelrc"),
loc: fixture(".babelrc"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
@ -491,7 +481,6 @@ describe("buildConfigChain", function() {
filename: fixture("dir3", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -506,21 +495,27 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
env: {
bar: {
plugins: ["env-bar"],
},
foo: {
plugins: ["env-foo"],
},
},
plugins: ["env-base"],
},
alias: fixture("env", ".babelrc"),
loc: fixture("env", ".babelrc"),
dirname: fixture("env"),
},
{
@ -529,7 +524,6 @@ describe("buildConfigChain", function() {
filename: fixture("env", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -546,30 +540,35 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
env: {
bar: {
plugins: ["env-bar"],
},
foo: {
plugins: ["env-foo"],
},
},
plugins: ["env-base"],
},
alias: fixture("env", ".babelrc"),
loc: fixture("env", ".babelrc"),
dirname: fixture("env"),
},
{
type: "options",
type: "env",
options: {
plugins: ["env-foo"],
},
alias: fixture("env", ".babelrc.env.foo"),
loc: fixture("env", ".babelrc.env.foo"),
dirname: fixture("env"),
},
{
@ -578,7 +577,6 @@ describe("buildConfigChain", function() {
filename: fixture("env", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -596,30 +594,35 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
env: {
bar: {
plugins: ["env-bar"],
},
foo: {
plugins: ["env-foo"],
},
},
plugins: ["env-base"],
},
alias: fixture("env", ".babelrc"),
loc: fixture("env", ".babelrc"),
dirname: fixture("env"),
},
{
type: "options",
type: "env",
options: {
plugins: ["env-bar"],
},
alias: fixture("env", ".babelrc.env.bar"),
loc: fixture("env", ".babelrc.env.bar"),
dirname: fixture("env"),
},
{
@ -628,7 +631,6 @@ describe("buildConfigChain", function() {
filename: fixture("env", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -645,21 +647,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
plugins: ["pkg-plugin"],
},
alias: fixture("pkg", "package.json"),
loc: fixture("pkg", "package.json"),
dirname: fixture("pkg"),
},
{
type: "options",
type: "file",
options: {
ignore: ["pkg-ignore"],
},
alias: fixture("pkg", ".babelignore"),
loc: fixture("pkg", ".babelignore"),
dirname: fixture("pkg"),
},
{
@ -668,7 +668,6 @@ describe("buildConfigChain", function() {
filename: fixture("pkg", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -683,21 +682,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
plugins: ["foo", "bar"],
},
alias: fixture("js-config", ".babelrc.js"),
loc: fixture("js-config", ".babelrc.js"),
dirname: fixture("js-config"),
},
{
@ -706,7 +703,6 @@ describe("buildConfigChain", function() {
filename: fixture("js-config", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -721,21 +717,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
compact: true,
},
alias: fixture("js-config-function", ".babelrc.js"),
loc: fixture("js-config-function", ".babelrc.js"),
dirname: fixture("js-config-function"),
},
{
@ -744,7 +738,6 @@ describe("buildConfigChain", function() {
filename: fixture("js-config-function", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -759,21 +752,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
plugins: ["foo", "bar"],
},
alias: fixture("js-config-default", ".babelrc.js"),
loc: fixture("js-config-default", ".babelrc.js"),
dirname: fixture("js-config-default"),
},
{
@ -782,7 +773,6 @@ describe("buildConfigChain", function() {
filename: fixture("js-config-default", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -796,30 +786,28 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
plugins: ["extended"],
},
alias: fixture("extended.babelrc.json"),
loc: fixture("extended.babelrc.json"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
extends: "../extended.babelrc.json",
plugins: ["foo", "bar"],
},
alias: fixture("js-config-extended", ".babelrc.js"),
loc: fixture("js-config-extended", ".babelrc.js"),
dirname: fixture("js-config-extended"),
},
{
@ -828,7 +816,6 @@ describe("buildConfigChain", function() {
filename: fixture("js-config-extended", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -846,21 +833,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
plugins: ["json"],
},
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
loc: fixture("json-pkg-config-no-babel", ".babelrc"),
dirname: fixture("json-pkg-config-no-babel"),
},
{
@ -869,7 +854,6 @@ describe("buildConfigChain", function() {
filename: fixture("json-pkg-config-no-babel", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -885,21 +869,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
ignore: ["*", "!src.js"],
},
alias: fixture("ignore-negate", ".babelrc"),
loc: fixture("ignore-negate", ".babelrc"),
dirname: fixture("ignore-negate"),
},
{
@ -908,7 +890,6 @@ describe("buildConfigChain", function() {
filename: fixture("ignore-negate", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];
@ -929,21 +910,19 @@ describe("buildConfigChain", function() {
const expected = [
{
type: "options",
type: "file",
options: {
ignore: ["root-ignore"],
},
alias: fixture(".babelignore"),
loc: fixture(".babelignore"),
dirname: fixture(),
},
{
type: "options",
type: "file",
options: {
ignore: ["*", "!folder"],
},
alias: fixture("ignore-negate-folder", ".babelrc"),
loc: fixture("ignore-negate-folder", ".babelrc"),
dirname: fixture("ignore-negate-folder"),
},
{
@ -952,7 +931,6 @@ describe("buildConfigChain", function() {
filename: fixture("ignore-negate-folder", "folder", "src.js"),
},
alias: "base",
loc: "base",
dirname: base(),
},
];

View File

@ -17,7 +17,7 @@ describe("option-manager", () => {
manageOptions({
randomOption: true,
});
}, /Unknown option: base.randomOption/);
}, /Unknown option: .randomOption/);
});
it("throws for removed babel 5 options", () => {
@ -29,7 +29,7 @@ describe("option-manager", () => {
});
},
// eslint-disable-next-line max-len
/Using removed Babel 5 option: base.auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/,
/Using removed Babel 5 option: .auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/,
);
});
@ -47,7 +47,7 @@ describe("option-manager", () => {
describe("source type", function() {
it("should set module for .mjs extension", () => {
const config = manageOptions({
sourceType: "program",
sourceType: "script",
filename: "foo.mjs",
});

View File

@ -259,7 +259,6 @@ export default function(
filenameRelative: task.expect.filename,
sourceFileName: task.actual.filename,
sourceMapTarget: task.expect.filename,
suppressDeprecationMessages: true,
babelrc: false,
sourceMap: !!(task.sourceMappings || task.sourceMap),
});

View File

@ -18,7 +18,7 @@ Installation
There are several ways to get a copy of @babel/standalone. Pick whichever one you like:
- Use it via UNPKG: https://unpkg.com/@babel/standalone@6/babel.min.js. This is a simple way to embed it on a webpage without having to do any other setup.
- Use it via UNPKG: https://unpkg.com/@babel/standalone/babel.min.js. This is a simple way to embed it on a webpage without having to do any other setup.
- Install via Bower: `bower install @babel/standalone`
- Install via NPM: `npm install --save @babel/standalone`
- Manually grab `babel.js` and/or `babel.min.js` from the [GitHub releases page](https://github.com/Daniel15/babel-standalone/releases). Every release includes these files.

View File

@ -437,6 +437,7 @@ export default class Tokenizer extends LocationParser {
let type = code === charCodes.asterisk ? tt.star : tt.modulo;
let width = 1;
let next = this.input.charCodeAt(this.state.pos + 1);
const exprAllowed = this.state.exprAllowed;
// Exponentiation operator **
if (code === charCodes.asterisk && next === charCodes.asterisk) {
@ -445,7 +446,7 @@ export default class Tokenizer extends LocationParser {
type = tt.exponent;
}
if (next === charCodes.equalsTo) {
if (next === charCodes.equalsTo && !exprAllowed) {
width++;
type = tt.assign;
}

View File

@ -0,0 +1 @@
const x = ():*=>{}

View File

@ -0,0 +1,152 @@
{
"type": "File",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"program": {
"type": "Program",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"sourceType": "module",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 18
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 6,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 18
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "x"
},
"name": "x"
},
"init": {
"type": "ArrowFunctionExpression",
"start": 10,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 18
}
},
"predicate": null,
"returnType": {
"type": "TypeAnnotation",
"start": 12,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 14
}
},
"typeAnnotation": {
"type": "ExistsTypeAnnotation",
"start": 13,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 13
},
"end": {
"line": 1,
"column": 14
}
}
}
},
"id": null,
"generator": false,
"expression": false,
"async": false,
"params": [],
"body": {
"type": "BlockStatement",
"start": 16,
"end": 18,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 18
}
},
"body": [],
"directives": []
}
}
}
],
"kind": "const"
}
],
"directives": []
}
}

View File

@ -0,0 +1 @@
class C { field:*=null }

View File

@ -0,0 +1,164 @@
{
"type": "File",
"start": 0,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 24
}
},
"program": {
"type": "Program",
"start": 0,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 24
}
},
"sourceType": "module",
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 24
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
},
"identifierName": "C"
},
"name": "C"
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 8,
"end": 24,
"loc": {
"start": {
"line": 1,
"column": 8
},
"end": {
"line": 1,
"column": 24
}
},
"body": [
{
"type": "ClassProperty",
"start": 10,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 22
}
},
"static": false,
"key": {
"type": "Identifier",
"start": 10,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 15
},
"identifierName": "field"
},
"name": "field"
},
"computed": false,
"variance": null,
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 15,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 1,
"column": 17
}
},
"typeAnnotation": {
"type": "ExistsTypeAnnotation",
"start": 16,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 1,
"column": 17
}
}
}
},
"value": {
"type": "NullLiteral",
"start": 18,
"end": 22,
"loc": {
"start": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 22
}
}
}
}
]
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
{
"plugins": ["flow", "classProperties"]
}