From 1e12bb6a23d7a5ad19b220d6f342fb6f19e21d1c Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Thu, 5 Oct 2017 21:24:52 -0400 Subject: [PATCH 1/5] Add more types around descriptor processing. --- .../babel-core/src/config/option-manager.js | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/packages/babel-core/src/config/option-manager.js b/packages/babel-core/src/config/option-manager.js index 2e504fe161..90189e400f 100644 --- a/packages/babel-core/src/config/option-manager.js +++ b/packages/babel-core/src/config/option-manager.js @@ -220,6 +220,11 @@ type BasicDescriptor = { loc: string, }; +type LoadedDescriptor = { + value: {}, + descriptor: BasicDescriptor, +}; + /** * Load and validate the given config into a set of options, plugins, and presets. */ @@ -282,38 +287,40 @@ const loadConfig = makeWeakCache((config): { /** * Load a generic plugin/preset from the given descriptor loaded from the config object. */ -const loadDescriptor = makeWeakCache((descriptor, cache) => { - if (typeof descriptor.value !== "function") { - return { value: descriptor.value, descriptor }; - } - const { value, options } = descriptor; - - const api = Object.assign(Object.create(context), { - cache, - env: () => cache.using(() => getEnv()), - }); - - let item; - try { - item = value(api, options, { dirname: descriptor.dirname }); - } catch (e) { - if (descriptor.alias) { - e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`; +const loadDescriptor = makeWeakCache( + (descriptor: BasicDescriptor, cache): LoadedDescriptor => { + if (typeof descriptor.value !== "function") { + return { value: descriptor.value, descriptor }; } - throw e; - } + const { value, options } = descriptor; - if (!item || typeof item !== "object") { - throw new Error("Plugin/Preset did not return an object."); - } + const api = Object.assign(Object.create(context), { + cache, + env: () => cache.using(() => getEnv()), + }); - return { value: item, descriptor }; -}); + let item; + try { + item = value(api, options, { dirname: descriptor.dirname }); + } catch (e) { + if (descriptor.alias) { + e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`; + } + throw e; + } + + if (!item || typeof item !== "object") { + throw new Error("Plugin/Preset did not return an object."); + } + + return { value: item, descriptor }; + }, +); /** * Instantiate a plugin for the given descriptor, returning the plugin/options pair. */ -function loadPluginDescriptor(descriptor: BasicDescriptor) { +function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin { if (descriptor.value instanceof Plugin) { if (descriptor.options) { throw new Error( @@ -328,7 +335,7 @@ function loadPluginDescriptor(descriptor: BasicDescriptor) { } const instantiatePlugin = makeWeakCache( - ({ value: pluginObj, descriptor }, cache) => { + ({ value: pluginObj, descriptor }: LoadedDescriptor, cache): Plugin => { Object.keys(pluginObj).forEach(key => { if (!ALLOWED_PLUGIN_KEYS.has(key)) { throw new Error( @@ -391,15 +398,17 @@ const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => { return instantiatePreset(loadDescriptor(descriptor)); }; -const instantiatePreset = makeWeakCache(({ value, descriptor }) => { - return { - type: "preset", - options: value, - alias: descriptor.alias, - loc: descriptor.loc, - dirname: descriptor.dirname, - }; -}); +const instantiatePreset = makeWeakCache( + ({ value, descriptor }: LoadedDescriptor): MergeOptions => { + return { + type: "preset", + options: value, + alias: descriptor.alias, + loc: descriptor.loc, + dirname: descriptor.dirname, + }; + }, +); /** * Validate and return the options object for the config. From e01ac56b1cffcb1b1537a8989ae926073c99bd44 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Thu, 5 Oct 2017 21:28:30 -0400 Subject: [PATCH 2/5] Simplify descriptor loading. --- .../babel-core/src/config/option-manager.js | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/babel-core/src/config/option-manager.js b/packages/babel-core/src/config/option-manager.js index 90189e400f..e628ac665d 100644 --- a/packages/babel-core/src/config/option-manager.js +++ b/packages/babel-core/src/config/option-manager.js @@ -289,24 +289,25 @@ const loadConfig = makeWeakCache((config): { */ const loadDescriptor = makeWeakCache( (descriptor: BasicDescriptor, cache): LoadedDescriptor => { - if (typeof descriptor.value !== "function") { - return { value: descriptor.value, descriptor }; - } const { value, options } = descriptor; - const api = Object.assign(Object.create(context), { - cache, - env: () => cache.using(() => getEnv()), - }); + let item = value; + if (typeof value === "function") { + const api = Object.assign(Object.create(context), { + cache, + env: () => cache.using(() => getEnv()), + }); - let item; - try { - item = value(api, options, { dirname: descriptor.dirname }); - } catch (e) { - if (descriptor.alias) { - e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`; + try { + item = value(api, options, { dirname: descriptor.dirname }); + } catch (e) { + if (descriptor.alias) { + e.message += ` (While processing: ${JSON.stringify( + descriptor.alias, + )})`; + } + throw e; } - throw e; } if (!item || typeof item !== "object") { From 597f1a12cfb2f300195aa87063cd2f7f70395be1 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Thu, 5 Oct 2017 21:32:54 -0400 Subject: [PATCH 3/5] Refactor loaded descriptors to allow mutation of options. --- .../babel-core/src/config/option-manager.js | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/babel-core/src/config/option-manager.js b/packages/babel-core/src/config/option-manager.js index e628ac665d..9fd98346f4 100644 --- a/packages/babel-core/src/config/option-manager.js +++ b/packages/babel-core/src/config/option-manager.js @@ -222,7 +222,10 @@ type BasicDescriptor = { type LoadedDescriptor = { value: {}, - descriptor: BasicDescriptor, + options: ?{}, + dirname: string, + alias: string, + loc: string, }; /** @@ -289,7 +292,7 @@ const loadConfig = makeWeakCache((config): { */ const loadDescriptor = makeWeakCache( (descriptor: BasicDescriptor, cache): LoadedDescriptor => { - const { value, options } = descriptor; + const { value, options, dirname, alias, loc } = descriptor; let item = value; if (typeof value === "function") { @@ -314,7 +317,7 @@ const loadDescriptor = makeWeakCache( throw new Error("Plugin/Preset did not return an object."); } - return { value: item, descriptor }; + return { value: item, options, descriptor, dirname, alias, loc }; }, ); @@ -336,11 +339,14 @@ function loadPluginDescriptor(descriptor: BasicDescriptor): Plugin { } const instantiatePlugin = makeWeakCache( - ({ value: pluginObj, descriptor }: LoadedDescriptor, cache): Plugin => { + ( + { value: pluginObj, options, dirname, alias, loc }: LoadedDescriptor, + cache, + ): Plugin => { Object.keys(pluginObj).forEach(key => { if (!ALLOWED_PLUGIN_KEYS.has(key)) { throw new Error( - `Plugin ${descriptor.alias} provided an invalid property of ${key}`, + `Plugin ${alias} provided an invalid property of ${key}`, ); } }); @@ -364,11 +370,11 @@ const instantiatePlugin = makeWeakCache( let inherits; if (plugin.inherits) { inheritsDescriptor = { - alias: `${descriptor.loc}$inherits`, - loc: descriptor.loc, + alias: `${loc}$inherits`, + loc, value: plugin.inherits, - options: descriptor.options, - dirname: descriptor.dirname, + options, + dirname, }; // If the inherited plugin changes, reinstantiate this plugin. @@ -388,7 +394,7 @@ const instantiatePlugin = makeWeakCache( ]); } - return new Plugin(plugin, descriptor.options, descriptor.alias); + return new Plugin(plugin, options, alias); }, ); @@ -400,13 +406,13 @@ const loadPresetDescriptor = (descriptor: BasicDescriptor): MergeOptions => { }; const instantiatePreset = makeWeakCache( - ({ value, descriptor }: LoadedDescriptor): MergeOptions => { + ({ value, dirname, alias, loc }: LoadedDescriptor): MergeOptions => { return { type: "preset", options: value, - alias: descriptor.alias, - loc: descriptor.loc, - dirname: descriptor.dirname, + alias, + loc, + dirname, }; }, ); From ca4460c0b8943bfed6ab05c42d0964fdb059febf Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Thu, 5 Oct 2017 21:40:16 -0400 Subject: [PATCH 4/5] Standardize on {}|void instead of ?{} options. --- packages/babel-core/src/config/option-manager.js | 7 ++++--- packages/babel-core/src/config/plugin.js | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/babel-core/src/config/option-manager.js b/packages/babel-core/src/config/option-manager.js index 9fd98346f4..d2232ef98d 100644 --- a/packages/babel-core/src/config/option-manager.js +++ b/packages/babel-core/src/config/option-manager.js @@ -214,7 +214,7 @@ class OptionManager { type BasicDescriptor = { value: {} | Function, - options: ?{}, + options: {} | void, dirname: string, alias: string, loc: string, @@ -222,7 +222,7 @@ type BasicDescriptor = { type LoadedDescriptor = { value: {}, - options: ?{}, + options: {} | void, dirname: string, alias: string, loc: string, @@ -520,7 +520,7 @@ function normalizePair( ): { filepath: string | null, value: {} | Function, - options: ?{}, + options: {} | void, } { let options; let value = pair; @@ -562,6 +562,7 @@ function normalizePair( "Plugin/Preset options must be an object, null, or undefined", ); } + options = options || undefined; return { filepath, value, options }; } diff --git a/packages/babel-core/src/config/plugin.js b/packages/babel-core/src/config/plugin.js index fbf0e1b13e..324e482226 100644 --- a/packages/babel-core/src/config/plugin.js +++ b/packages/babel-core/src/config/plugin.js @@ -9,7 +9,7 @@ export default class Plugin { options: {} | void; - constructor(plugin: {}, options: ?{}, key?: string) { + constructor(plugin: {}, options: {} | void, key?: string) { if (plugin.name != null && typeof plugin.name !== "string") { throw new Error("Plugin .name must be a string, null, or undefined"); } @@ -37,6 +37,6 @@ export default class Plugin { this.post = plugin.post; this.pre = plugin.pre; this.visitor = plugin.visitor; - this.options = options || undefined; + this.options = options; } } From b3331c0217fe84ce8f25650a1bd1fe3e01fc010e Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Thu, 5 Oct 2017 22:03:39 -0400 Subject: [PATCH 5/5] Ensure that the options object always exists. --- packages/babel-core/src/config/option-manager.js | 4 ++-- packages/babel-core/src/config/plugin.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/babel-core/src/config/option-manager.js b/packages/babel-core/src/config/option-manager.js index d2232ef98d..6b39bbd274 100644 --- a/packages/babel-core/src/config/option-manager.js +++ b/packages/babel-core/src/config/option-manager.js @@ -222,7 +222,7 @@ type BasicDescriptor = { type LoadedDescriptor = { value: {}, - options: {} | void, + options: {}, dirname: string, alias: string, loc: string, @@ -292,7 +292,7 @@ const loadConfig = makeWeakCache((config): { */ const loadDescriptor = makeWeakCache( (descriptor: BasicDescriptor, cache): LoadedDescriptor => { - const { value, options, dirname, alias, loc } = descriptor; + const { value, options = {}, dirname, alias, loc } = descriptor; let item = value; if (typeof value === "function") { diff --git a/packages/babel-core/src/config/plugin.js b/packages/babel-core/src/config/plugin.js index 324e482226..fec1ecdbe1 100644 --- a/packages/babel-core/src/config/plugin.js +++ b/packages/babel-core/src/config/plugin.js @@ -7,9 +7,9 @@ export default class Plugin { pre: ?Function; visitor: ?{}; - options: {} | void; + options: {}; - constructor(plugin: {}, options: {} | void, key?: string) { + constructor(plugin: {}, options: {}, key?: string) { if (plugin.name != null && typeof plugin.name !== "string") { throw new Error("Plugin .name must be a string, null, or undefined"); }