From 5a319fd553ff28761488c29995d90545e7873c29 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Mon, 16 Mar 2015 01:23:57 +1100 Subject: [PATCH] automate option generation --- bin/babel/index.js | 71 ++++----- src/babel/transformation/file.js | 121 +++++---------- src/babel/transformation/options.json | 152 +++++++++++++++++++ src/babel/transformation/transformer-pass.js | 10 +- 4 files changed, 222 insertions(+), 132 deletions(-) create mode 100644 src/babel/transformation/options.json diff --git a/bin/babel/index.js b/bin/babel/index.js index da34ba6fe2..99ab67d1f7 100755 --- a/bin/babel/index.js +++ b/bin/babel/index.js @@ -2,32 +2,38 @@ var commander = require("commander"); var transform = require("../../lib/babel/transformation"); +var kebabCase = require("lodash/string/kebabCase"); +var File = require("../../lib/babel/transformation/file"); var util = require("../../lib/babel/util"); -var fs = require("fs"); var each = require("lodash/collection/each"); var keys = require("lodash/object/keys"); +var fs = require("fs"); + +each(File.options, function (option, key) { + if (option.hidden) return; + + var arg = kebabCase(key); + + if (option.type !== "boolean") { + arg += ` [${option.type || "string"}]`; + } + + if (option.type === "boolean" && option.default === true) { + arg = `no-${key}`; + } + + arg = `--${arg}`; + + if (option.shorthand) { + arg = `-${option.shorthand}, ${arg}`; + } + + commander.option(arg, option.description); +}) -commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to bottom of code"); -commander.option("-s, --source-maps", "Save source map alongside the compiled code"); -commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin"); commander.option("-w, --watch", "Recompile files on changes"); -commander.option("-r, --external-helpers", "Replace helpers with references to a `babelHelpers` global"); -commander.option("-e, --experimental", "Enable experimental support for proposed ES7 features"); -commander.option("-p, --playground", "Enable playground support"); - -commander.option("-c, --compact [mode]", "When set to \"auto\" compact is `true` when the input size exceeds 100KB. (auto|true|false)", "auto"); -commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common"); -commander.option("-l, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list); -commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list); -commander.option("-i, --optional [list]", "List of optional transformers to enable", util.list); -commander.option("-L, --loose [list]", "List of transformers to enable loose mode ON", util.list); commander.option("-o, --out-file [out]", "Compile all input files into a single file"); commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory"); -commander.option("-c, --remove-comments", "Remove comments from the compiled code", false); -commander.option("-M, --module-ids", "Insert module id in modules", false); -commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code"); -commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false); -commander.option("-a, --auxiliary-comment [comment]", "Comment text to prepend to all auxiliary code"); commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files"); commander.on("--help", function () { @@ -38,9 +44,7 @@ commander.on("--help", function () { each(keys(obj).sort(), function (key) { if (key[0] === "_") return; - if (obj[key].optional) { - key = "[" + key + "]"; - } + if (obj[key].optional) key = `[${key}]`; console.log(" - " + key); }); @@ -100,24 +104,11 @@ if (errors.length) { // -exports.opts = { - keepModuleIdExtensions: commander.keepModuleIdExtensions, - auxiliaryComment: commander.auxiliaryComment, - externalHelpers: commander.externalHelpers, - sourceMapName: commander.outFile, - experimental: commander.experimental, - reactCompat: commander.reactCompat, - playground: commander.playground, - moduleIds: commander.moduleIds, - blacklist: commander.blacklist, - whitelist: commander.whitelist, - sourceMap: commander.sourceMaps || commander.sourceMapsInline, - optional: commander.optional, - comments: !commander.removeComments, - modules: commander.modules, - compact: commander.compact, - loose: commander.loose -}; +exports.opts = {}; + +each(File.options, function (opt, key) { + exports.opts[key] = commander[key]; +}); var fn; diff --git a/src/babel/transformation/file.js b/src/babel/transformation/file.js index 3d1c5b1766..a8a63a02f8 100644 --- a/src/babel/transformation/file.js +++ b/src/babel/transformation/file.js @@ -82,52 +82,7 @@ export default class File { "self-global" ]; - static validOptions = [ - "filename", - "filenameRelative", - - "blacklist", - "whitelist", - "optional", - - "loose", - "playground", - "experimental", - - "modules", - "moduleIds", - "moduleId", - "resolveModuleSource", - "keepModuleIdExtensions", - - "code", - "ast", - - "comments", - "compact", - - "auxiliaryComment", - "externalHelpers", - "returnUsedHelpers", - - "inputSourceMap", - "sourceMap", - "sourceMapName", - "sourceFileName", - "sourceRoot", - "moduleRoot", - - "ignore", - "only", - - // legacy - "format", - "reactCompat", - - // these are used by plugins - "extensions", - "accept" - ]; + static options = require("./options"); normalizeOptions(opts: Object) { opts = assign({}, opts); @@ -136,36 +91,32 @@ export default class File { opts = resolveRc(opts.filename, opts); } - for (var key in opts) { - if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) { - throw new ReferenceError(`Unknown option: ${key}`); - } + // + + for (let key in opts) { + if (key[0] === "_") continue; + + let option = File.options[key]; + if (!option) throw new ReferenceError(`Unknown option: ${key}`); } + for (let key in File.options) { + let option = File.options[key]; + + var val = opts[key]; + if (val == null) val = option.default || null; + opts[key] = val; + } + + // + defaults(opts, { - keepModuleIdExtensions: false, - resolveModuleSource: null, - returnUsedHelpers: false, - externalHelpers: false, - auxilaryComment: "", - inputSourceMap: null, - experimental: false, - reactCompat: false, - playground: false, - moduleIds: false, - blacklist: [], - whitelist: [], - sourceMap: false, - optional: [], - comments: true, - filename: "unknown", - modules: "common", - compact: "auto", - loose: [], - ignore: [], - only: [], - code: true, - ast: true + blacklist: [], + whitelist: [], + optional: [], + loose: [], + ignore: [], + only: [], }); if (opts.inputSourceMap) { @@ -213,9 +164,7 @@ export default class File { sourceMapName: opts.filenameRelative }); - if (opts.playground) { - opts.experimental = true; - } + // if (opts.externalHelpers) { this.set("helpersNamespace", t.identifier("babelHelpers")); @@ -226,15 +175,6 @@ export default class File { opts.optional = transform._ensureTransformerNames("optional", opts.optional); opts.loose = transform._ensureTransformerNames("loose", opts.loose); - var ensureEnabled = function (key) { - var namespace = transform.transformerNamespaces[key]; - if (namespace === "es7") opts.experimental = true; - if (namespace === "playground") opts.playground = true; - }; - - each(opts.whitelist, ensureEnabled); - each(opts.optional, ensureEnabled); - return opts; }; @@ -242,6 +182,10 @@ export default class File { return includes(this.opts.loose, key); } + buildPlugins(stack) { + + } + buildTransformers() { var file = this; @@ -250,6 +194,8 @@ export default class File { var secondaryStack = []; var stack = []; + this.buildPlugins(stack); + each(transform.transformers, function (transformer, key) { var pass = transformers[key] = transformer.buildPass(file); @@ -551,6 +497,7 @@ export default class File { } generate(): { + usedHelpers?: Array; code: string; map?: Object; ast?: Object; @@ -560,8 +507,8 @@ export default class File { var result = { code: "", - map: null, - ast: null + map: null, + ast: null }; if (this.opts.returnUsedHelpers) { diff --git a/src/babel/transformation/options.json b/src/babel/transformation/options.json new file mode 100644 index 0000000000..97c633f137 --- /dev/null +++ b/src/babel/transformation/options.json @@ -0,0 +1,152 @@ +{ + "filename": { + "type": "string", + "description": "Filename to use when reading from stdin - this will be used in source-maps, errors etc", + "default": "unknown", + "shorthand": "f" + }, + + "filenameRelative": { + "hidden": true, + "type": "string" + }, + + "inputSourceMap": { + "hidden": true + }, + + "moduleId": { + + }, + + "resolveModuleSource": { + "hidden": true + }, + + "experimental": { + "description": "Enable all ES7+ transformers", + "shorthand": "e", + "type": "boolean", + "default": false + }, + + "playground": { + "description": "Enable all playground transformers", + "shorthand": "p", + "type": "boolean", + "default": false + }, + + "blacklist": { + "type": "transformerList", + "description": "Blacklist of transformers to NOT use", + "shorthand": "b" + }, + + "whitelist": { + "type": "transformerList", + "description": "Whitelist of transformers to ONLY use", + "shorthand": "l" + }, + + "optional": { + "type": "transformerList", + "description": "List of optional transformers to enable" + }, + + "modules": { + "type": "string", + "description": "Module formatter type to use [common]", + "default": "common", + "shorthand": "m" + }, + + "moduleIds": { + "type": "boolean", + "default": false, + "shorthand": "M" + }, + + "loose": { + "type": "transformerList", + "description": "List of transformers to enable loose mode ON", + "shorthand": "L" + }, + + "ignore": { + "type": "list" + }, + + "only": { + "type": "list" + }, + + "code": { + "hidden": true, + "default": true, + "type": "boolean" + }, + + "ast": { + "hidden": true, + "default": true, + "type": "boolean" + }, + + "comments": { + "type": "boolean", + "default": true + }, + + "compact": { + "type": "string", + "default": "auto" + }, + + "keepModuleIdExtensions": { + "type": "boolean", + "description": "Keep extensions when generating module ids", + "default": false, + "shorthand": "k" + }, + + "auxiliaryComment": { + "type": "string", + "default": "", + "shorthand": "a" + }, + + "externalHelpers": { + "type": "string", + "default": false, + "shorthand": "r" + }, + + "returnUsedHelpers": { + "type": "boolean", + "default": false, + "hidden": true + }, + + "sourceMap": { + "type": "string", + "default": false, + "shorthand": "s" + }, + + "sourceMapName": { + "type": "string" + }, + + "sourceFileName": { + "type": "string" + }, + + "sourceRoot": { + "type": "string" + }, + + "moduleRoot": { + "type": "string" + } +} diff --git a/src/babel/transformation/transformer-pass.js b/src/babel/transformation/transformer-pass.js index dd8fab0431..0d9897f259 100644 --- a/src/babel/transformation/transformer-pass.js +++ b/src/babel/transformation/transformer-pass.js @@ -32,14 +32,14 @@ export default class TransformerPass { var whitelist = opts.whitelist; if (whitelist.length) return includes(whitelist, key); - // optional - if (transformer.optional && !includes(opts.optional, key)) return false; - // experimental - if (transformer.experimental && !opts.experimental) return false; + if (transformer.experimental && opts.experimental) return true; // playground - if (transformer.playground && !opts.playground) return false; + if (transformer.playground && opts.playground) return true; + + // optional + if (transformer.optional && !includes(opts.optional, key)) return false; return true; }