Run prettier
This commit is contained in:
parent
93cc22dae1
commit
e4b35f680d
35
Gulpfile.js
35
Gulpfile.js
@ -21,32 +21,41 @@ function swapSrcWithLib(srcPath) {
|
||||
|
||||
gulp.task("default", ["build"]);
|
||||
|
||||
gulp.task("build", function () {
|
||||
return gulp.src(scripts, { base: base })
|
||||
.pipe(plumber({
|
||||
errorHandler: function (err) {
|
||||
gulp.task("build", function() {
|
||||
return gulp
|
||||
.src(scripts, { base: base })
|
||||
.pipe(
|
||||
plumber({
|
||||
errorHandler: function(err) {
|
||||
gutil.log(err.stack);
|
||||
},
|
||||
}))
|
||||
.pipe(newer({
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
newer({
|
||||
dest: base,
|
||||
map: swapSrcWithLib,
|
||||
}))
|
||||
.pipe(through.obj(function (file, enc, callback) {
|
||||
})
|
||||
)
|
||||
.pipe(
|
||||
through.obj(function(file, enc, callback) {
|
||||
gutil.log("Compiling", "'" + chalk.cyan(file.relative) + "'...");
|
||||
callback(null, file);
|
||||
}))
|
||||
})
|
||||
)
|
||||
.pipe(babel())
|
||||
.pipe(through.obj(function (file, enc, callback) {
|
||||
.pipe(
|
||||
through.obj(function(file, enc, callback) {
|
||||
// Passing 'file.relative' because newer() above uses a relative path and this keeps it consistent.
|
||||
file.path = path.resolve(file.base, swapSrcWithLib(file.relative));
|
||||
callback(null, file);
|
||||
}))
|
||||
})
|
||||
)
|
||||
.pipe(gulp.dest(base));
|
||||
});
|
||||
|
||||
gulp.task("watch", ["build"], function () {
|
||||
watch(scripts, { debounceDelay: 200 }, function () {
|
||||
gulp.task("watch", ["build"], function() {
|
||||
watch(scripts, { debounceDelay: 200 }, function() {
|
||||
gulp.start("build");
|
||||
});
|
||||
});
|
||||
|
||||
@ -24,9 +24,21 @@ function collect(value, previousValue): Array<string> {
|
||||
/* eslint-disable max-len */
|
||||
program.option("-e, --eval [script]", "Evaluate script");
|
||||
program.option("-p, --print [code]", "Evaluate script and print result");
|
||||
program.option("-o, --only [globs]", "A comma-separated list of glob patterns to compile", collect);
|
||||
program.option("-i, --ignore [globs]", "A comma-separated list of glob patterns to skip compiling", collect);
|
||||
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx,.mjs]", collect);
|
||||
program.option(
|
||||
"-o, --only [globs]",
|
||||
"A comma-separated list of glob patterns to compile",
|
||||
collect,
|
||||
);
|
||||
program.option(
|
||||
"-i, --ignore [globs]",
|
||||
"A comma-separated list of glob patterns to skip compiling",
|
||||
collect,
|
||||
);
|
||||
program.option(
|
||||
"-x, --extensions [extensions]",
|
||||
"List of extensions to hook into [.es6,.js,.es,.jsx,.mjs]",
|
||||
collect,
|
||||
);
|
||||
program.option("-w, --plugins [string]", "", collect);
|
||||
program.option("-b, --presets [string]", "", collect);
|
||||
/* eslint-enable max-len */
|
||||
@ -55,23 +67,28 @@ const replPlugin = ({ types: t }) => ({
|
||||
|
||||
VariableDeclaration(path) {
|
||||
if (path.node.kind !== "var") {
|
||||
throw path.buildCodeFrameError("Only `var` variables are supported in the REPL");
|
||||
throw path.buildCodeFrameError(
|
||||
"Only `var` variables are supported in the REPL",
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
Program(path) {
|
||||
if (path.get("body").some((child) => child.isExpressionStatement())) return;
|
||||
if (path.get("body").some(child => child.isExpressionStatement())) return;
|
||||
|
||||
// If the executed code doesn't evaluate to a value,
|
||||
// prevent implicit strict mode from printing 'use strict'.
|
||||
path.pushContainer("body", t.expressionStatement(t.identifier("undefined")));
|
||||
path.pushContainer(
|
||||
"body",
|
||||
t.expressionStatement(t.identifier("undefined")),
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
const _eval = function (code, filename) {
|
||||
const _eval = function(code, filename) {
|
||||
code = code.trim();
|
||||
if (!code) return undefined;
|
||||
|
||||
@ -113,7 +130,7 @@ if (program.eval || program.print) {
|
||||
|
||||
let i = 0;
|
||||
let ignoreNext = false;
|
||||
args.some(function (arg, i2) {
|
||||
args.some(function(arg, i2) {
|
||||
if (ignoreNext) {
|
||||
ignoreNext = false;
|
||||
return;
|
||||
@ -133,7 +150,9 @@ if (program.eval || program.print) {
|
||||
|
||||
// make the filename absolute
|
||||
const filename = args[0];
|
||||
if (!path.isAbsolute(filename)) args[0] = path.join(process.cwd(), filename);
|
||||
if (!path.isAbsolute(filename)) {
|
||||
args[0] = path.join(process.cwd(), filename);
|
||||
}
|
||||
|
||||
// add back on node and concat the sliced args
|
||||
process.argv = ["node"].concat(args);
|
||||
|
||||
@ -10,8 +10,16 @@ function collect(value, previousValue): Array<string> {
|
||||
return previousValue ? previousValue.concat(values) : values;
|
||||
}
|
||||
|
||||
commander.option("-l, --whitelist [whitelist]", "Whitelist of helpers to ONLY include", collect);
|
||||
commander.option("-t, --output-type [type]", "Type of output (global|umd|var)", "global");
|
||||
commander.option(
|
||||
"-l, --whitelist [whitelist]",
|
||||
"Whitelist of helpers to ONLY include",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"-t, --output-type [type]",
|
||||
"Type of output (global|umd|var)",
|
||||
"global",
|
||||
);
|
||||
|
||||
commander.usage("[options]");
|
||||
commander.parse(process.argv);
|
||||
|
||||
@ -33,7 +33,7 @@ function getNormalizedV8Flag(arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
getV8Flags(function (err, v8Flags) {
|
||||
getV8Flags(function(err, v8Flags) {
|
||||
babelArgs.forEach(function(arg) {
|
||||
const flag = arg.split("=")[0];
|
||||
|
||||
@ -59,7 +59,10 @@ getV8Flags(function (err, v8Flags) {
|
||||
break;
|
||||
|
||||
default:
|
||||
if (v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 || arg.indexOf("--trace") === 0) {
|
||||
if (
|
||||
v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 ||
|
||||
arg.indexOf("--trace") === 0
|
||||
) {
|
||||
args.unshift(arg);
|
||||
} else {
|
||||
args.push(arg);
|
||||
@ -80,9 +83,11 @@ getV8Flags(function (err, v8Flags) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
const child_process = require("child_process");
|
||||
const proc = child_process.spawn(process.argv[0], args, { stdio: "inherit" });
|
||||
proc.on("exit", function (code, signal) {
|
||||
process.on("exit", function () {
|
||||
const proc = child_process.spawn(process.argv[0], args, {
|
||||
stdio: "inherit",
|
||||
});
|
||||
proc.on("exit", function(code, signal) {
|
||||
process.on("exit", function() {
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
} else {
|
||||
|
||||
@ -6,19 +6,27 @@ import fs from "fs";
|
||||
|
||||
import * as util from "./util";
|
||||
|
||||
export default function (commander, filenames, opts) {
|
||||
export default function(commander, filenames, opts) {
|
||||
function write(src, relative) {
|
||||
if (!util.isCompilableExtension(relative, commander.extensions)) return false;
|
||||
if (!util.isCompilableExtension(relative, commander.extensions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove extension and then append back on .js
|
||||
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||
|
||||
const dest = path.join(commander.outDir, relative);
|
||||
|
||||
const data = util.compile(src, defaults({
|
||||
const data = util.compile(
|
||||
src,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: slash(path.relative(dest + "/..", src)),
|
||||
sourceMapTarget: path.basename(relative),
|
||||
}, opts));
|
||||
},
|
||||
opts,
|
||||
),
|
||||
);
|
||||
|
||||
if (!data) return false;
|
||||
|
||||
@ -55,7 +63,7 @@ export default function (commander, filenames, opts) {
|
||||
if (stat.isDirectory(filename)) {
|
||||
const dirname = filename;
|
||||
|
||||
util.readdir(dirname).forEach(function (filename) {
|
||||
util.readdir(dirname).forEach(function(filename) {
|
||||
const src = path.join(dirname, filename);
|
||||
handleFile(src, filename);
|
||||
});
|
||||
@ -71,7 +79,7 @@ export default function (commander, filenames, opts) {
|
||||
if (commander.watch) {
|
||||
const chokidar = util.requireChokidar();
|
||||
|
||||
filenames.forEach(function (dirname) {
|
||||
filenames.forEach(function(dirname) {
|
||||
const watcher = chokidar.watch(dirname, {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
@ -81,8 +89,8 @@ export default function (commander, filenames, opts) {
|
||||
},
|
||||
});
|
||||
|
||||
["add", "change"].forEach(function (type) {
|
||||
watcher.on(type, function (filename) {
|
||||
["add", "change"].forEach(function(type) {
|
||||
watcher.on(type, function(filename) {
|
||||
const relative = path.relative(dirname, filename) || filename;
|
||||
try {
|
||||
handleFile(filename, relative);
|
||||
|
||||
@ -7,14 +7,14 @@ import fs from "fs";
|
||||
|
||||
import * as util from "./util";
|
||||
|
||||
export default function (commander, filenames, opts) {
|
||||
export default function(commander, filenames, opts) {
|
||||
if (commander.sourceMaps === "inline") {
|
||||
opts.sourceMaps = true;
|
||||
}
|
||||
|
||||
let results = [];
|
||||
|
||||
const buildResult = function () {
|
||||
const buildResult = function() {
|
||||
const map = new sourceMap.SourceMapGenerator({
|
||||
file: path.basename(commander.outFile || "") || "stdout",
|
||||
sourceRoot: opts.sourceRoot,
|
||||
@ -23,14 +23,14 @@ export default function (commander, filenames, opts) {
|
||||
let code = "";
|
||||
let offset = 0;
|
||||
|
||||
results.forEach(function (result) {
|
||||
results.forEach(function(result) {
|
||||
code += result.code + "\n";
|
||||
|
||||
if (result.map) {
|
||||
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
const sources = new Set();
|
||||
|
||||
consumer.eachMapping(function (mapping) {
|
||||
consumer.eachMapping(function(mapping) {
|
||||
if (mapping.source != null) sources.add(mapping.source);
|
||||
|
||||
map.addMapping({
|
||||
@ -39,14 +39,17 @@ export default function (commander, filenames, opts) {
|
||||
column: mapping.generatedColumn,
|
||||
},
|
||||
source: mapping.source,
|
||||
original: mapping.source == null ? null : {
|
||||
original:
|
||||
mapping.source == null
|
||||
? null
|
||||
: {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
sources.forEach((source) => {
|
||||
sources.forEach(source => {
|
||||
const content = consumer.sourceContentFor(source, true);
|
||||
if (content !== null) {
|
||||
map.setSourceContent(source, content);
|
||||
@ -59,7 +62,10 @@ export default function (commander, filenames, opts) {
|
||||
|
||||
// add the inline sourcemap comment if we've either explicitly asked for inline source
|
||||
// maps, or we've requested them without any output file
|
||||
if (commander.sourceMaps === "inline" || (!commander.outFile && commander.sourceMaps)) {
|
||||
if (
|
||||
commander.sourceMaps === "inline" ||
|
||||
(!commander.outFile && commander.sourceMaps)
|
||||
) {
|
||||
code += "\n" + convertSourceMap.fromObject(map).toComment();
|
||||
}
|
||||
|
||||
@ -69,7 +75,7 @@ export default function (commander, filenames, opts) {
|
||||
};
|
||||
};
|
||||
|
||||
const output = function () {
|
||||
const output = function() {
|
||||
const result = buildResult();
|
||||
|
||||
if (commander.outFile) {
|
||||
@ -86,36 +92,45 @@ export default function (commander, filenames, opts) {
|
||||
}
|
||||
};
|
||||
|
||||
const stdin = function () {
|
||||
const stdin = function() {
|
||||
let code = "";
|
||||
|
||||
process.stdin.setEncoding("utf8");
|
||||
|
||||
process.stdin.on("readable", function () {
|
||||
process.stdin.on("readable", function() {
|
||||
const chunk = process.stdin.read();
|
||||
if (chunk !== null) code += chunk;
|
||||
});
|
||||
|
||||
process.stdin.on("end", function () {
|
||||
results.push(util.transform(commander.filename, code, defaults({
|
||||
process.stdin.on("end", function() {
|
||||
results.push(
|
||||
util.transform(
|
||||
commander.filename,
|
||||
code,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: "stdin",
|
||||
}, opts)));
|
||||
},
|
||||
opts,
|
||||
),
|
||||
),
|
||||
);
|
||||
output();
|
||||
});
|
||||
};
|
||||
|
||||
const walk = function () {
|
||||
const walk = function() {
|
||||
const _filenames = [];
|
||||
results = [];
|
||||
|
||||
filenames.forEach(function (filename) {
|
||||
filenames.forEach(function(filename) {
|
||||
if (!fs.existsSync(filename)) return;
|
||||
|
||||
const stat = fs.statSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
const dirname = filename;
|
||||
|
||||
util.readdirFilter(filename).forEach(function (filename) {
|
||||
util.readdirFilter(filename).forEach(function(filename) {
|
||||
_filenames.push(path.join(dirname, filename));
|
||||
});
|
||||
} else {
|
||||
@ -123,16 +138,25 @@ export default function (commander, filenames, opts) {
|
||||
}
|
||||
});
|
||||
|
||||
_filenames.forEach(function (filename) {
|
||||
_filenames.forEach(function(filename) {
|
||||
let sourceFilename = filename;
|
||||
if (commander.outFile) {
|
||||
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
|
||||
sourceFilename = path.relative(
|
||||
path.dirname(commander.outFile),
|
||||
sourceFilename,
|
||||
);
|
||||
}
|
||||
sourceFilename = slash(sourceFilename);
|
||||
|
||||
const data = util.compile(filename, defaults({
|
||||
const data = util.compile(
|
||||
filename,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: sourceFilename,
|
||||
}, opts));
|
||||
},
|
||||
opts,
|
||||
),
|
||||
);
|
||||
|
||||
if (!data) return;
|
||||
|
||||
@ -142,23 +166,26 @@ export default function (commander, filenames, opts) {
|
||||
output();
|
||||
};
|
||||
|
||||
const files = function () {
|
||||
|
||||
const files = function() {
|
||||
if (!commander.skipInitialBuild) {
|
||||
walk();
|
||||
}
|
||||
|
||||
if (commander.watch) {
|
||||
const chokidar = util.requireChokidar();
|
||||
chokidar.watch(filenames, {
|
||||
chokidar
|
||||
.watch(filenames, {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 50,
|
||||
pollInterval: 10,
|
||||
},
|
||||
}).on("all", function (type, filename) {
|
||||
if (!util.isCompilableExtension(filename, commander.extensions)) return;
|
||||
})
|
||||
.on("all", function(type, filename) {
|
||||
if (!util.isCompilableExtension(filename, commander.extensions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === "add" || type === "change") {
|
||||
util.log(type + " " + filename);
|
||||
|
||||
@ -34,45 +34,117 @@ function collect(value, previousValue): Array<string> {
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// Standard Babel input configs.
|
||||
commander.option("-f, --filename [filename]", "filename to use when reading from stdin - this will be used in source-maps, errors etc");
|
||||
commander.option("--presets [list]", "comma-separated list of preset names", collect);
|
||||
commander.option("--plugins [list]", "comma-separated list of plugin names", collect);
|
||||
commander.option(
|
||||
"-f, --filename [filename]",
|
||||
"filename to use when reading from stdin - this will be used in source-maps, errors etc",
|
||||
);
|
||||
commander.option(
|
||||
"--presets [list]",
|
||||
"comma-separated list of preset names",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--plugins [list]",
|
||||
"comma-separated list of plugin names",
|
||||
collect,
|
||||
);
|
||||
|
||||
// Basic file input configuration.
|
||||
commander.option("--source-type [script|module]", "");
|
||||
commander.option("--no-babelrc", "Whether or not to look up .babelrc and .babelignore files");
|
||||
commander.option("--ignore [list]", "list of glob paths to **not** compile", collect);
|
||||
commander.option("--only [list]", "list of glob paths to **only** compile", collect);
|
||||
commander.option(
|
||||
"--no-babelrc",
|
||||
"Whether or not to look up .babelrc and .babelignore files",
|
||||
);
|
||||
commander.option(
|
||||
"--ignore [list]",
|
||||
"list of glob paths to **not** compile",
|
||||
collect,
|
||||
);
|
||||
commander.option(
|
||||
"--only [list]",
|
||||
"list of glob paths to **only** compile",
|
||||
collect,
|
||||
);
|
||||
|
||||
// Misc babel config.
|
||||
commander.option("--no-highlight-code", "enable/disable ANSI syntax highlighting of code frames (on by default)");
|
||||
commander.option(
|
||||
"--no-highlight-code",
|
||||
"enable/disable ANSI syntax highlighting of code frames (on by default)",
|
||||
);
|
||||
|
||||
// General output formatting.
|
||||
commander.option("--no-comments", "write comments to generated output (true by default)");
|
||||
commander.option("--retain-lines", "retain line numbers - will result in really ugly code");
|
||||
commander.option("--compact [true|false|auto]", "do not include superfluous whitespace characters and line terminators", booleanify);
|
||||
commander.option(
|
||||
"--no-comments",
|
||||
"write comments to generated output (true by default)",
|
||||
);
|
||||
commander.option(
|
||||
"--retain-lines",
|
||||
"retain line numbers - will result in really ugly code",
|
||||
);
|
||||
commander.option(
|
||||
"--compact [true|false|auto]",
|
||||
"do not include superfluous whitespace characters and line terminators",
|
||||
booleanify,
|
||||
);
|
||||
commander.option("--minified", "save as much bytes when printing [true|false]");
|
||||
commander.option("--auxiliary-comment-before [string]", "print a comment before any injected non-user code");
|
||||
commander.option("--auxiliary-comment-after [string]", "print a comment after any injected non-user code");
|
||||
commander.option(
|
||||
"--auxiliary-comment-before [string]",
|
||||
"print a comment before any injected non-user code",
|
||||
);
|
||||
commander.option(
|
||||
"--auxiliary-comment-after [string]",
|
||||
"print a comment after any injected non-user code",
|
||||
);
|
||||
|
||||
// General soucemap formatting.
|
||||
commander.option("-s, --source-maps [true|false|inline|both]", "", booleanify);
|
||||
commander.option("--source-map-target [string]", "set `file` on returned source map");
|
||||
commander.option("--source-file-name [string]", "set `sources[0]` on returned source map");
|
||||
commander.option("--source-root [filename]", "the root from which all sources are relative");
|
||||
commander.option(
|
||||
"--source-map-target [string]",
|
||||
"set `file` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-file-name [string]",
|
||||
"set `sources[0]` on returned source map",
|
||||
);
|
||||
commander.option(
|
||||
"--source-root [filename]",
|
||||
"the root from which all sources are relative",
|
||||
);
|
||||
|
||||
// Config params for certain module output formats.
|
||||
commander.option("--module-root [filename]", "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions");
|
||||
commander.option(
|
||||
"--module-root [filename]",
|
||||
"optional prefix for the AMD module formatter that will be prepend to the filename on module definitions",
|
||||
);
|
||||
commander.option("-M, --module-ids", "insert an explicit id for modules");
|
||||
commander.option("--module-id [string]", "specify a custom name for module ids");
|
||||
commander.option(
|
||||
"--module-id [string]",
|
||||
"specify a custom name for module ids",
|
||||
);
|
||||
|
||||
// "babel" command specific arguments that are not passed to babel-core.
|
||||
commander.option("-x, --extensions [extensions]", "List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx,.mjs]", collect);
|
||||
commander.option(
|
||||
"-x, --extensions [extensions]",
|
||||
"List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx,.mjs]",
|
||||
collect,
|
||||
);
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option("--skip-initial-build", "Do not compile files before watching");
|
||||
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("-D, --copy-files", "When compiling a directory copy over non-compilable files");
|
||||
commander.option(
|
||||
"--skip-initial-build",
|
||||
"Do not compile files before watching",
|
||||
);
|
||||
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(
|
||||
"-D, --copy-files",
|
||||
"When compiling a directory copy over non-compilable files",
|
||||
);
|
||||
commander.option("-q, --quiet", "Don't log anything");
|
||||
/* eslint-enable max-len */
|
||||
|
||||
@ -84,7 +156,7 @@ commander.parse(process.argv);
|
||||
|
||||
const errors = [];
|
||||
|
||||
let filenames = commander.args.reduce(function (globbed, input) {
|
||||
let filenames = commander.args.reduce(function(globbed, input) {
|
||||
let files = glob.sync(input);
|
||||
if (!files.length) files = [input];
|
||||
return globbed.concat(files);
|
||||
@ -92,7 +164,7 @@ let filenames = commander.args.reduce(function (globbed, input) {
|
||||
|
||||
filenames = uniq(filenames);
|
||||
|
||||
filenames.forEach(function (filename) {
|
||||
filenames.forEach(function(filename) {
|
||||
if (!fs.existsSync(filename)) {
|
||||
errors.push(filename + " doesn't exist");
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ export function chmod(src, dest) {
|
||||
}
|
||||
|
||||
export function readdirFilter(filename) {
|
||||
return readdir(filename).filter(function (filename) {
|
||||
return readdir(filename).filter(function(filename) {
|
||||
return isCompilableExtension(filename);
|
||||
});
|
||||
}
|
||||
@ -20,7 +20,10 @@ export { readdir };
|
||||
/**
|
||||
* Test if a filename ends with a compilable extension.
|
||||
*/
|
||||
export function isCompilableExtension(filename: string, altExts?: Array<string>): boolean {
|
||||
export function isCompilableExtension(
|
||||
filename: string,
|
||||
altExts?: Array<string>,
|
||||
): boolean {
|
||||
const exts = altExts || babel.DEFAULT_EXTENSIONS;
|
||||
const ext = path.extname(filename);
|
||||
return includes(exts, ext);
|
||||
@ -63,7 +66,7 @@ function toErrorStack(err) {
|
||||
}
|
||||
}
|
||||
|
||||
process.on("uncaughtException", function (err) {
|
||||
process.on("uncaughtException", function(err) {
|
||||
console.error(toErrorStack(err));
|
||||
process.exit(1);
|
||||
});
|
||||
@ -74,7 +77,7 @@ export function requireChokidar() {
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"The optional dependency chokidar failed to install and is required for " +
|
||||
"--watch. Chokidar is likely not supported on your platform."
|
||||
"--watch. Chokidar is likely not supported on your platform.",
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@ -27,34 +27,39 @@ const pluginLocs = [
|
||||
path.join(__dirname, "/../../babel-plugin-transform-es2015-modules-commonjs"),
|
||||
].join(",");
|
||||
|
||||
const readDir = function (loc, filter) {
|
||||
const readDir = function(loc, filter) {
|
||||
const files = {};
|
||||
if (fs.existsSync(loc)) {
|
||||
readdir(loc, filter).forEach(function (filename) {
|
||||
readdir(loc, filter).forEach(function(filename) {
|
||||
files[filename] = helper.readFile(path.join(loc, filename));
|
||||
});
|
||||
}
|
||||
return files;
|
||||
};
|
||||
|
||||
const saveInFiles = function (files) {
|
||||
const saveInFiles = function(files) {
|
||||
// Place an empty .babelrc in each test so tests won't unexpectedly get to repo-level config.
|
||||
outputFileSync(".babelrc", "{}");
|
||||
|
||||
Object.keys(files).forEach(function (filename) {
|
||||
Object.keys(files).forEach(function(filename) {
|
||||
const content = files[filename];
|
||||
outputFileSync(filename, content);
|
||||
});
|
||||
};
|
||||
|
||||
const assertTest = function (stdout, stderr, opts) {
|
||||
const assertTest = function(stdout, stderr, opts) {
|
||||
const expectStderr = opts.stderr.trim();
|
||||
stderr = stderr.trim();
|
||||
|
||||
if (opts.stderr) {
|
||||
if (opts.stderrContains) {
|
||||
assert.ok(includes(stderr, expectStderr), "stderr " + JSON.stringify(stderr) +
|
||||
" didn't contain " + JSON.stringify(expectStderr));
|
||||
assert.ok(
|
||||
includes(stderr, expectStderr),
|
||||
"stderr " +
|
||||
JSON.stringify(stderr) +
|
||||
" didn't contain " +
|
||||
JSON.stringify(expectStderr),
|
||||
);
|
||||
} else {
|
||||
chai.expect(stderr).to.equal(expectStderr, "stderr didn't match");
|
||||
}
|
||||
@ -68,8 +73,13 @@ const assertTest = function (stdout, stderr, opts) {
|
||||
|
||||
if (opts.stdout) {
|
||||
if (opts.stdoutContains) {
|
||||
assert.ok(includes(stdout, expectStdout), "stdout " + JSON.stringify(stdout) +
|
||||
" didn't contain " + JSON.stringify(expectStdout));
|
||||
assert.ok(
|
||||
includes(stdout, expectStdout),
|
||||
"stdout " +
|
||||
JSON.stringify(stdout) +
|
||||
" didn't contain " +
|
||||
JSON.stringify(expectStdout),
|
||||
);
|
||||
} else {
|
||||
chai.expect(stdout).to.equal(expectStdout, "stdout didn't match");
|
||||
}
|
||||
@ -80,30 +90,34 @@ const assertTest = function (stdout, stderr, opts) {
|
||||
if (opts.outFiles) {
|
||||
const actualFiles = readDir(path.join(tmpLoc));
|
||||
|
||||
Object.keys(actualFiles).forEach(function (filename) {
|
||||
Object.keys(actualFiles).forEach(function(filename) {
|
||||
if (!opts.inFiles.hasOwnProperty(filename)) {
|
||||
const expect = opts.outFiles[filename];
|
||||
const actual = actualFiles[filename];
|
||||
|
||||
chai.expect(expect, "Output is missing: " + filename).to.not.be.undefined;
|
||||
chai.expect(expect, "Output is missing: " + filename).to.not.be
|
||||
.undefined;
|
||||
|
||||
if (expect) {
|
||||
chai.expect(actual).to.equal(expect, "Compiled output does not match: " + filename);
|
||||
chai
|
||||
.expect(actual)
|
||||
.to.equal(expect, "Compiled output does not match: " + filename);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(opts.outFiles).forEach(function(filename) {
|
||||
chai.expect(actualFiles, "Extraneous file in output: " + filename)
|
||||
chai
|
||||
.expect(actualFiles, "Extraneous file in output: " + filename)
|
||||
.to.contain.key(filename);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const buildTest = function (binName, testName, opts) {
|
||||
const buildTest = function(binName, testName, opts) {
|
||||
const binLoc = path.join(__dirname, "../lib", binName);
|
||||
|
||||
return function (callback) {
|
||||
return function(callback) {
|
||||
clear();
|
||||
saveInFiles(opts.inFiles);
|
||||
|
||||
@ -124,15 +138,15 @@ const buildTest = function (binName, testName, opts) {
|
||||
let stderr = "";
|
||||
let stdout = "";
|
||||
|
||||
spawn.stderr.on("data", function (chunk) {
|
||||
spawn.stderr.on("data", function(chunk) {
|
||||
stderr += chunk;
|
||||
});
|
||||
|
||||
spawn.stdout.on("data", function (chunk) {
|
||||
spawn.stdout.on("data", function(chunk) {
|
||||
stdout += chunk;
|
||||
});
|
||||
|
||||
spawn.on("close", function () {
|
||||
spawn.on("close", function() {
|
||||
let err;
|
||||
|
||||
try {
|
||||
@ -142,7 +156,8 @@ const buildTest = function (binName, testName, opts) {
|
||||
}
|
||||
|
||||
if (err) {
|
||||
err.message = args.map((arg) => `"${ arg }"`).join(" ") + ": " + err.message;
|
||||
err.message =
|
||||
args.map(arg => `"${arg}"`).join(" ") + ": " + err.message;
|
||||
}
|
||||
|
||||
callback(err);
|
||||
@ -155,19 +170,19 @@ const buildTest = function (binName, testName, opts) {
|
||||
};
|
||||
};
|
||||
|
||||
const clear = function () {
|
||||
const clear = function() {
|
||||
process.chdir(__dirname);
|
||||
if (fs.existsSync(tmpLoc)) rimraf.sync(tmpLoc);
|
||||
fs.mkdirSync(tmpLoc);
|
||||
process.chdir(tmpLoc);
|
||||
};
|
||||
|
||||
fs.readdirSync(fixtureLoc).forEach(function (binName) {
|
||||
fs.readdirSync(fixtureLoc).forEach(function(binName) {
|
||||
if (binName[0] === ".") return;
|
||||
|
||||
const suiteLoc = path.join(fixtureLoc, binName);
|
||||
describe("bin/" + binName, function () {
|
||||
fs.readdirSync(suiteLoc).forEach(function (testName) {
|
||||
describe("bin/" + binName, function() {
|
||||
fs.readdirSync(suiteLoc).forEach(function(testName) {
|
||||
if (testName[0] === ".") return;
|
||||
|
||||
const testLoc = path.join(suiteLoc, testName);
|
||||
@ -179,7 +194,7 @@ fs.readdirSync(fixtureLoc).forEach(function (binName) {
|
||||
const optionsLoc = path.join(testLoc, "options.json");
|
||||
if (fs.existsSync(optionsLoc)) merge(opts, require(optionsLoc));
|
||||
|
||||
["stdout", "stdin", "stderr"].forEach(function (key) {
|
||||
["stdout", "stdin", "stderr"].forEach(function(key) {
|
||||
const loc = path.join(testLoc, key + ".txt");
|
||||
if (fs.existsSync(loc)) {
|
||||
opts[key] = helper.readFile(loc);
|
||||
|
||||
@ -90,11 +90,11 @@ function getTokenType(match) {
|
||||
*/
|
||||
|
||||
function highlight(defs: Object, text: string) {
|
||||
return text.replace(jsTokens, function (...args) {
|
||||
return text.replace(jsTokens, function(...args) {
|
||||
const type = getTokenType(args);
|
||||
const colorize = defs[type];
|
||||
if (colorize) {
|
||||
return args[0].split(NEWLINE).map((str) => colorize(str)).join("\n");
|
||||
return args[0].split(NEWLINE).map(str => colorize(str)).join("\n");
|
||||
} else {
|
||||
return args[0];
|
||||
}
|
||||
@ -106,9 +106,15 @@ function highlight(defs: Object, text: string) {
|
||||
*/
|
||||
|
||||
function getMarkerLines(
|
||||
loc: NodeLocation, source: Array<string>, opts: Object
|
||||
loc: NodeLocation,
|
||||
source: Array<string>,
|
||||
opts: Object,
|
||||
): { start: number, end: number, markerLines: Object } {
|
||||
const startLoc: Location = Object.assign({}, { column: 0, line: -1 }, loc.start);
|
||||
const startLoc: Location = Object.assign(
|
||||
{},
|
||||
{ column: 0, line: -1 },
|
||||
loc.start,
|
||||
);
|
||||
const endLoc: Location = Object.assign({}, startLoc, loc.end);
|
||||
const linesAbove = opts.linesAbove || 2;
|
||||
const linesBelow = opts.linesBelow || 3;
|
||||
@ -165,12 +171,13 @@ function getMarkerLines(
|
||||
return { start, end, markerLines };
|
||||
}
|
||||
|
||||
export function codeFrameColumns (
|
||||
export function codeFrameColumns(
|
||||
rawLines: string,
|
||||
loc: NodeLocation,
|
||||
opts: Object = {},
|
||||
): string {
|
||||
const highlighted = (opts.highlightCode && Chalk.supportsColor) || opts.forceColor;
|
||||
const highlighted =
|
||||
(opts.highlightCode && Chalk.supportsColor) || opts.forceColor;
|
||||
let chalk = Chalk;
|
||||
if (opts.forceColor) {
|
||||
chalk = new Chalk.constructor({ enabled: true });
|
||||
@ -186,7 +193,9 @@ export function codeFrameColumns (
|
||||
|
||||
const numberMaxWidth = String(end).length;
|
||||
|
||||
const frame = lines.slice(start, end).map((line, index) => {
|
||||
const frame = lines
|
||||
.slice(start, end)
|
||||
.map((line, index) => {
|
||||
const number = start + 1 + index;
|
||||
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
||||
const gutter = ` ${paddedNumber} | `;
|
||||
@ -194,7 +203,9 @@ export function codeFrameColumns (
|
||||
if (hasMarker) {
|
||||
let markerLine = "";
|
||||
if (Array.isArray(hasMarker)) {
|
||||
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " ");
|
||||
const markerSpacing = line
|
||||
.slice(0, Math.max(hasMarker[0] - 1, 0))
|
||||
.replace(/[^\t]/g, " ");
|
||||
const numberOfMarkers = hasMarker[1] || 1;
|
||||
|
||||
markerLine = [
|
||||
@ -213,7 +224,8 @@ export function codeFrameColumns (
|
||||
} else {
|
||||
return ` ${maybeHighlight(defs.gutter, gutter)}${line}`;
|
||||
}
|
||||
}).join("\n");
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
if (highlighted) {
|
||||
return chalk.reset(frame);
|
||||
@ -226,7 +238,7 @@ export function codeFrameColumns (
|
||||
* Create a code frame, adding line numbers, code highlighting, and pointing to a given position.
|
||||
*/
|
||||
|
||||
export default function (
|
||||
export default function(
|
||||
rawLines: string,
|
||||
lineNumber: number,
|
||||
colNumber: ?number,
|
||||
@ -236,7 +248,7 @@ export default function (
|
||||
deprecationWarningShown = true;
|
||||
|
||||
const deprecationError = new Error(
|
||||
"Passing lineNumber and colNumber is deprecated to babel-code-frame. Please use `codeFrameColumns`."
|
||||
"Passing lineNumber and colNumber is deprecated to babel-code-frame. Please use `codeFrameColumns`.",
|
||||
);
|
||||
deprecationError.name = "DeprecationWarning";
|
||||
|
||||
@ -249,7 +261,9 @@ export default function (
|
||||
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
const location: NodeLocation = { start: { column: colNumber, line: lineNumber } };
|
||||
const location: NodeLocation = {
|
||||
start: { column: colNumber, line: lineNumber },
|
||||
};
|
||||
|
||||
return codeFrameColumns(rawLines, location, opts);
|
||||
}
|
||||
|
||||
@ -2,35 +2,29 @@ import assert from "assert";
|
||||
import chalk from "chalk";
|
||||
import codeFrame, { codeFrameColumns } from "..";
|
||||
|
||||
describe("babel-code-frame", function () {
|
||||
it("basic usage", function () {
|
||||
const rawLines = [
|
||||
"class Foo {",
|
||||
" constructor()",
|
||||
"};",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 2, 16), [
|
||||
describe("babel-code-frame", function() {
|
||||
it("basic usage", function() {
|
||||
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 2, 16),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor()",
|
||||
" | ^",
|
||||
" 3 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("optional column number", function () {
|
||||
const rawLines = [
|
||||
"class Foo {",
|
||||
" constructor()",
|
||||
"};",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 2, null), [
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor()",
|
||||
" 3 | };",
|
||||
].join("\n"));
|
||||
it("optional column number", function() {
|
||||
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 2, null),
|
||||
[" 1 | class Foo {", "> 2 | constructor()", " 3 | };"].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("maximum context lines and padding", function () {
|
||||
it("maximum context lines and padding", function() {
|
||||
const rawLines = [
|
||||
"/**",
|
||||
" * Sums two numbers.",
|
||||
@ -44,7 +38,9 @@ describe("babel-code-frame", function () {
|
||||
" return a + b",
|
||||
"}",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 7, 2), [
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 7, 2),
|
||||
[
|
||||
" 5 | * @param b Number",
|
||||
" 6 | * @returns Number",
|
||||
"> 7 | */",
|
||||
@ -52,10 +48,11 @@ describe("babel-code-frame", function () {
|
||||
" 8 | ",
|
||||
" 9 | function sum(a, b) {",
|
||||
" 10 | return a + b",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("no unnecessary padding due to one-off errors", function () {
|
||||
it("no unnecessary padding due to one-off errors", function() {
|
||||
const rawLines = [
|
||||
"/**",
|
||||
" * Sums two numbers.",
|
||||
@ -69,7 +66,9 @@ describe("babel-code-frame", function () {
|
||||
" return a + b",
|
||||
"}",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 6, 2), [
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 6, 2),
|
||||
[
|
||||
" 4 | * @param a Number",
|
||||
" 5 | * @param b Number",
|
||||
"> 6 | * @returns Number",
|
||||
@ -77,35 +76,39 @@ describe("babel-code-frame", function () {
|
||||
" 7 | */",
|
||||
" 8 | ",
|
||||
" 9 | function sum(a, b) {",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("tabs", function () {
|
||||
it("tabs", function() {
|
||||
const rawLines = [
|
||||
"\tclass Foo {",
|
||||
"\t \t\t constructor\t(\t)",
|
||||
"\t};",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 2, 25), [
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 2, 25),
|
||||
[
|
||||
" 1 | \tclass Foo {",
|
||||
"> 2 | \t \t\t constructor\t(\t)",
|
||||
" | \t \t\t \t \t ^",
|
||||
" 3 | \t};",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("opts.highlightCode", function () {
|
||||
it("opts.highlightCode", function() {
|
||||
const rawLines = "console.log('babel')";
|
||||
const result = codeFrame(rawLines, 1, 9, { highlightCode: true });
|
||||
const stripped = chalk.stripColor(result);
|
||||
assert.ok(result.length > stripped.length);
|
||||
assert.equal(stripped, [
|
||||
"> 1 | console.log('babel')",
|
||||
" | ^",
|
||||
].join("\n"));
|
||||
assert.equal(
|
||||
stripped,
|
||||
["> 1 | console.log('babel')", " | ^"].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("opts.linesAbove", function () {
|
||||
it("opts.linesAbove", function() {
|
||||
const rawLines = [
|
||||
"/**",
|
||||
" * Sums two numbers.",
|
||||
@ -119,17 +122,20 @@ describe("babel-code-frame", function () {
|
||||
" return a + b",
|
||||
"}",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 7, 2, { linesAbove: 1 }), [
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 7, 2, { linesAbove: 1 }),
|
||||
[
|
||||
" 6 | * @returns Number",
|
||||
"> 7 | */",
|
||||
" | ^",
|
||||
" 8 | ",
|
||||
" 9 | function sum(a, b) {",
|
||||
" 10 | return a + b",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("opts.linesBelow", function () {
|
||||
it("opts.linesBelow", function() {
|
||||
const rawLines = [
|
||||
"/**",
|
||||
" * Sums two numbers.",
|
||||
@ -143,16 +149,19 @@ describe("babel-code-frame", function () {
|
||||
" return a + b",
|
||||
"}",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 7, 2, { linesBelow: 1 }), [
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 7, 2, { linesBelow: 1 }),
|
||||
[
|
||||
" 5 | * @param b Number",
|
||||
" 6 | * @returns Number",
|
||||
"> 7 | */",
|
||||
" | ^",
|
||||
" 8 | ",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("opts.linesAbove and opts.linesBelow", function () {
|
||||
it("opts.linesAbove and opts.linesBelow", function() {
|
||||
const rawLines = [
|
||||
"/**",
|
||||
" * Sums two numbers.",
|
||||
@ -166,78 +175,82 @@ describe("babel-code-frame", function () {
|
||||
" return a + b",
|
||||
"}",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 7, 2, { linesAbove: 1, linesBelow: 1 }), [
|
||||
" 6 | * @returns Number",
|
||||
"> 7 | */",
|
||||
" | ^",
|
||||
" 8 | ",
|
||||
].join("\n"));
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 7, 2, { linesAbove: 1, linesBelow: 1 }),
|
||||
[" 6 | * @returns Number", "> 7 | */", " | ^", " 8 | "].join(
|
||||
"\n",
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("opts.forceColor", function() {
|
||||
const marker = chalk.red.bold;
|
||||
const gutter = chalk.grey;
|
||||
|
||||
const rawLines = [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
].join("\n");
|
||||
assert.equal(codeFrame(rawLines, 3, null, { linesAbove: 1, linesBelow: 1, forceColor: true }),
|
||||
chalk.reset([
|
||||
const rawLines = ["", "", "", ""].join("\n");
|
||||
assert.equal(
|
||||
codeFrame(rawLines, 3, null, {
|
||||
linesAbove: 1,
|
||||
linesBelow: 1,
|
||||
forceColor: true,
|
||||
}),
|
||||
chalk.reset(
|
||||
[
|
||||
" " + gutter(" 2 | "),
|
||||
marker(">") + gutter(" 3 | "),
|
||||
" " + gutter(" 4 | "),
|
||||
].join("\n"))
|
||||
].join("\n"),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it("basic usage, new API", function () {
|
||||
const rawLines = [
|
||||
"class Foo {",
|
||||
" constructor()",
|
||||
"};",
|
||||
].join("\n");
|
||||
assert.equal(codeFrameColumns(rawLines, { start: { line: 2, column: 16 } }), [
|
||||
it("basic usage, new API", function() {
|
||||
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||
assert.equal(
|
||||
codeFrameColumns(rawLines, { start: { line: 2, column: 16 } }),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor()",
|
||||
" | ^",
|
||||
" 3 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("mark multiple columns", function() {
|
||||
const rawLines = [
|
||||
"class Foo {",
|
||||
" constructor()",
|
||||
"};",
|
||||
].join("\n");
|
||||
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||
assert.equal(
|
||||
codeFrameColumns(rawLines, { start: { line: 2, column: 3 }, end: { line: 2, column: 16 } }), [
|
||||
codeFrameColumns(rawLines, {
|
||||
start: { line: 2, column: 3 },
|
||||
end: { line: 2, column: 16 },
|
||||
}),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor()",
|
||||
" | ^^^^^^^^^^^^^",
|
||||
" 3 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("mark multiple columns across lines", function() {
|
||||
const rawLines = [
|
||||
"class Foo {",
|
||||
" constructor() {",
|
||||
" }",
|
||||
"};",
|
||||
].join("\n");
|
||||
const rawLines = ["class Foo {", " constructor() {", " }", "};"].join(
|
||||
"\n",
|
||||
);
|
||||
assert.equal(
|
||||
codeFrameColumns(rawLines, { start: { line: 2, column: 17 }, end: { line: 3, column: 3 } }), [
|
||||
codeFrameColumns(rawLines, {
|
||||
start: { line: 2, column: 17 },
|
||||
end: { line: 3, column: 3 },
|
||||
}),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor() {",
|
||||
" | ^",
|
||||
"> 3 | }",
|
||||
" | ^^^",
|
||||
" 4 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("mark multiple columns across multiple lines", function() {
|
||||
@ -249,7 +262,11 @@ describe("babel-code-frame", function () {
|
||||
"};",
|
||||
].join("\n");
|
||||
assert.equal(
|
||||
codeFrameColumns(rawLines, { start: { line: 2, column: 17 }, end: { line: 4, column: 3 } }), [
|
||||
codeFrameColumns(rawLines, {
|
||||
start: { line: 2, column: 17 },
|
||||
end: { line: 4, column: 3 },
|
||||
}),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor() {",
|
||||
" | ^",
|
||||
@ -258,7 +275,8 @@ describe("babel-code-frame", function () {
|
||||
"> 4 | }",
|
||||
" | ^^^",
|
||||
" 5 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("mark across multiple lines without columns", function() {
|
||||
@ -270,12 +288,14 @@ describe("babel-code-frame", function () {
|
||||
"};",
|
||||
].join("\n");
|
||||
assert.equal(
|
||||
codeFrameColumns(rawLines, { start: { line: 2 }, end: { line: 4 } }), [
|
||||
codeFrameColumns(rawLines, { start: { line: 2 }, end: { line: 4 } }),
|
||||
[
|
||||
" 1 | class Foo {",
|
||||
"> 2 | constructor() {",
|
||||
"> 3 | console.log(arguments);",
|
||||
"> 4 | }",
|
||||
" 5 | };",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -7,14 +7,14 @@ import micromatch from "micromatch";
|
||||
import { findConfigs, loadConfig } from "./loading/files";
|
||||
|
||||
type ConfigItem = {
|
||||
type: "options"|"arguments",
|
||||
type: "options" | "arguments",
|
||||
options: {},
|
||||
dirname: string,
|
||||
alias: string,
|
||||
loc: string,
|
||||
};
|
||||
|
||||
export default function buildConfigChain(opts: {}): Array<ConfigItem>|null {
|
||||
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");
|
||||
}
|
||||
@ -44,9 +44,9 @@ export default function buildConfigChain(opts: {}): Array<ConfigItem>|null {
|
||||
}
|
||||
|
||||
class ConfigChainBuilder {
|
||||
filename: string|null;
|
||||
filename: string | null;
|
||||
configs: Array<ConfigItem>;
|
||||
possibleDirs: null|Array<string>;
|
||||
possibleDirs: null | Array<string>;
|
||||
|
||||
constructor(filename) {
|
||||
this.configs = [];
|
||||
@ -57,16 +57,14 @@ class ConfigChainBuilder {
|
||||
/**
|
||||
* Tests if a filename should be ignored based on "ignore" and "only" options.
|
||||
*/
|
||||
shouldIgnore(
|
||||
ignore: mixed,
|
||||
only: mixed,
|
||||
dirname: string,
|
||||
): boolean {
|
||||
shouldIgnore(ignore: mixed, only: mixed, dirname: string): boolean {
|
||||
if (!this.filename) return false;
|
||||
|
||||
if (ignore) {
|
||||
if (!Array.isArray(ignore)) {
|
||||
throw new Error(`.ignore should be an array, ${JSON.stringify(ignore)} given`);
|
||||
throw new Error(
|
||||
`.ignore should be an array, ${JSON.stringify(ignore)} given`,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.matchesPatterns(ignore, dirname)) return true;
|
||||
@ -74,7 +72,9 @@ class ConfigChainBuilder {
|
||||
|
||||
if (only) {
|
||||
if (!Array.isArray(only)) {
|
||||
throw new Error(`.only should be an array, ${JSON.stringify(only)} given`);
|
||||
throw new Error(
|
||||
`.only should be an array, ${JSON.stringify(only)} given`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.matchesPatterns(only, dirname)) return true;
|
||||
@ -89,21 +89,27 @@ class ConfigChainBuilder {
|
||||
*/
|
||||
matchesPatterns(patterns: Array<mixed>, dirname: string) {
|
||||
const filename = this.filename;
|
||||
if (!filename) throw new Error("Assertion failure: .filename should always exist here");
|
||||
if (!filename) {
|
||||
throw new Error("Assertion failure: .filename should always exist here");
|
||||
}
|
||||
|
||||
const res = [];
|
||||
const strings = [];
|
||||
const fns = [];
|
||||
|
||||
patterns.forEach((pattern) => {
|
||||
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 {
|
||||
throw new Error(
|
||||
"Patterns must be a string, function, or regular expression",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (res.some((re) => re.test(filename))) return true;
|
||||
if (fns.some((fn) => fn(filename))) return true;
|
||||
if (res.some(re => re.test(filename))) return true;
|
||||
if (fns.some(fn => fn(filename))) return true;
|
||||
|
||||
if (strings.length > 0) {
|
||||
let possibleDirs = this.possibleDirs;
|
||||
@ -123,7 +129,7 @@ class ConfigChainBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
const absolutePatterns = strings.map((pattern) => {
|
||||
const absolutePatterns = strings.map(pattern => {
|
||||
// Preserve the "!" prefix so that micromatch can use it for negation.
|
||||
const negate = pattern[0] === "!";
|
||||
if (negate) pattern = pattern.slice(1);
|
||||
@ -131,7 +137,9 @@ class ConfigChainBuilder {
|
||||
return (negate ? "!" : "") + path.resolve(dirname, pattern);
|
||||
});
|
||||
|
||||
if (micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0) {
|
||||
if (
|
||||
micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -150,16 +158,16 @@ class ConfigChainBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
mergeConfig({
|
||||
type,
|
||||
options: rawOpts,
|
||||
alias,
|
||||
dirname,
|
||||
}) {
|
||||
mergeConfig({ type, options: rawOpts, alias, dirname }) {
|
||||
// Bail out ASAP if this file is ignored so that we run as little logic as possible on ignored files.
|
||||
if (this.filename && this.shouldIgnore(rawOpts.ignore || null, rawOpts.only || null, dirname)) {
|
||||
if (
|
||||
this.filename &&
|
||||
this.shouldIgnore(rawOpts.ignore || null, rawOpts.only || null, dirname)
|
||||
) {
|
||||
// TODO(logan): This is a really cross way to bail out. Avoid this in rewrite.
|
||||
throw Object.assign((new Error("This file has been ignored."): any), { code: "BABEL_IGNORED_FILE" });
|
||||
throw Object.assign((new Error("This file has been ignored."): any), {
|
||||
code: "BABEL_IGNORED_FILE",
|
||||
});
|
||||
}
|
||||
|
||||
const options = Object.assign({}, rawOpts);
|
||||
@ -168,13 +176,19 @@ class ConfigChainBuilder {
|
||||
|
||||
const envKey = getEnv();
|
||||
|
||||
if (rawOpts.env != null && (typeof rawOpts.env !== "object" || Array.isArray(rawOpts.env))) {
|
||||
if (
|
||||
rawOpts.env != null &&
|
||||
(typeof rawOpts.env !== "object" || Array.isArray(rawOpts.env))
|
||||
) {
|
||||
throw new Error(".env block must be an object, null, or undefined");
|
||||
}
|
||||
|
||||
const envOpts = rawOpts.env && rawOpts.env[envKey];
|
||||
|
||||
if (envOpts != null && (typeof envOpts !== "object" || Array.isArray(envOpts))) {
|
||||
if (
|
||||
envOpts != null &&
|
||||
(typeof envOpts !== "object" || Array.isArray(envOpts))
|
||||
) {
|
||||
throw new Error(".env[...] block must be an object, null, or undefined");
|
||||
}
|
||||
|
||||
@ -196,11 +210,13 @@ class ConfigChainBuilder {
|
||||
});
|
||||
|
||||
if (rawOpts.extends) {
|
||||
if (typeof rawOpts.extends !== "string") throw new Error(".extends must be a string");
|
||||
if (typeof rawOpts.extends !== "string") {
|
||||
throw new Error(".extends must be a string");
|
||||
}
|
||||
|
||||
const extendsConfig = loadConfig(rawOpts.extends, dirname);
|
||||
|
||||
const existingConfig = this.configs.some((config) => {
|
||||
const existingConfig = this.configs.some(config => {
|
||||
return config.alias === extendsConfig.filepath;
|
||||
});
|
||||
if (!existingConfig) {
|
||||
@ -214,4 +230,3 @@ class ConfigChainBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ type CacheConfiguratorObj = {
|
||||
invalidate: <T>(handler: () => T) => T,
|
||||
};
|
||||
|
||||
type CacheEntry<ResultT> = Array<[ ResultT, () => boolean ]>;
|
||||
type CacheEntry<ResultT> = Array<[ResultT, () => boolean]>;
|
||||
|
||||
/**
|
||||
* Given a function with a single argument, cache its results based on its argument and how it
|
||||
@ -22,7 +22,7 @@ type CacheEntry<ResultT> = Array<[ ResultT, () => boolean ]>;
|
||||
export function makeStrongCache<ArgT, ResultT>(
|
||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||
autoPermacache?: boolean,
|
||||
): (ArgT) => ResultT {
|
||||
): ArgT => ResultT {
|
||||
return makeCachedFunction(new Map(), handler, autoPermacache);
|
||||
}
|
||||
|
||||
@ -34,22 +34,24 @@ export function makeStrongCache<ArgT, ResultT>(
|
||||
export function makeWeakCache<ArgT: {}, ResultT>(
|
||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||
autoPermacache?: boolean,
|
||||
): (ArgT) => ResultT {
|
||||
): ArgT => ResultT {
|
||||
return makeCachedFunction(new WeakMap(), handler, autoPermacache);
|
||||
}
|
||||
|
||||
type CacheMap<ArgT, ResultT> = Map<ArgT, CacheEntry<ResultT>>|WeakMap<ArgT, CacheEntry<ResultT>>;
|
||||
type CacheMap<ArgT, ResultT> =
|
||||
| Map<ArgT, CacheEntry<ResultT>>
|
||||
| WeakMap<ArgT, CacheEntry<ResultT>>;
|
||||
|
||||
function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||
callCache: Cache,
|
||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||
autoPermacache: boolean = true,
|
||||
): (ArgT) => ResultT {
|
||||
): ArgT => ResultT {
|
||||
return function cachedFunction(arg) {
|
||||
let cachedValue: CacheEntry<ResultT>|void = callCache.get(arg);
|
||||
let cachedValue: CacheEntry<ResultT> | void = callCache.get(arg);
|
||||
|
||||
if (cachedValue) {
|
||||
for (const [ value, valid ] of cachedValue) {
|
||||
for (const [value, valid] of cachedValue) {
|
||||
if (valid()) return value;
|
||||
}
|
||||
}
|
||||
@ -64,7 +66,8 @@ function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||
|
||||
if (!result.configured) {
|
||||
// eslint-disable-next-line max-len
|
||||
throw new Error([
|
||||
throw new Error(
|
||||
[
|
||||
"Caching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured",
|
||||
"for various types of caching, using the first param of their handler functions:",
|
||||
"",
|
||||
@ -83,12 +86,12 @@ function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||
"",
|
||||
" // If testing for a specific env, we recommend specifics to avoid instantiating a plugin for",
|
||||
" // any possible NODE_ENV value that might come up during plugin execution.",
|
||||
" var isProd = api.cache(() => process.env.NODE_ENV === \"production\");",
|
||||
' var isProd = api.cache(() => process.env.NODE_ENV === "production");',
|
||||
"",
|
||||
" // .cache(fn) will perform a linear search though instances to find the matching plugin based",
|
||||
" // based on previous instantiated plugins. If you want to recreate the plugin and discard the",
|
||||
" // previous instance whenever something changes, you may use:",
|
||||
" var isProd = api.cache.invalidate(() => process.env.NODE_ENV === \"production\");",
|
||||
' var isProd = api.cache.invalidate(() => process.env.NODE_ENV === "production");',
|
||||
"",
|
||||
" // Note, we also expose the following more-verbose versions of the above examples:",
|
||||
" api.cache.forever(); // api.cache(true)",
|
||||
@ -98,21 +101,18 @@ function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||
" // Return the value that will be cached.",
|
||||
" return { };",
|
||||
"};",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
}
|
||||
|
||||
if (!result.never) {
|
||||
if (result.forever) {
|
||||
cachedValue = [
|
||||
[value, () => true],
|
||||
];
|
||||
cachedValue = [[value, () => true]];
|
||||
} else if (result.invalidate) {
|
||||
cachedValue = [
|
||||
[value, result.valid],
|
||||
];
|
||||
cachedValue = [[value, result.valid]];
|
||||
} else {
|
||||
cachedValue = cachedValue || [];
|
||||
cachedValue.push([ value, result.valid ]);
|
||||
cachedValue.push([value, result.valid]);
|
||||
}
|
||||
callCache.set(arg, cachedValue);
|
||||
}
|
||||
@ -121,7 +121,11 @@ function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||
};
|
||||
}
|
||||
|
||||
function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: () => void } {
|
||||
function makeCacheConfig(): {
|
||||
cache: CacheConfigurator,
|
||||
result: *,
|
||||
deactivate: () => void,
|
||||
} {
|
||||
const pairs = [];
|
||||
|
||||
const result = {
|
||||
@ -137,7 +141,8 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
||||
active = false;
|
||||
};
|
||||
|
||||
const cache: CacheConfigurator = Object.assign((function cacheFn(val) {
|
||||
const cache: CacheConfigurator = Object.assign(
|
||||
(function cacheFn(val) {
|
||||
if (typeof val === "boolean") {
|
||||
if (val) cache.forever();
|
||||
else cache.never();
|
||||
@ -145,43 +150,71 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
||||
}
|
||||
|
||||
return cache.using(val);
|
||||
}: any), ({
|
||||
}: any),
|
||||
({
|
||||
forever() {
|
||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
||||
if (result.never) throw new Error("Caching has already been configured with .never()");
|
||||
if (!active) {
|
||||
throw new Error(
|
||||
"Cannot change caching after evaluation has completed.",
|
||||
);
|
||||
}
|
||||
if (result.never) {
|
||||
throw new Error("Caching has already been configured with .never()");
|
||||
}
|
||||
result.forever = true;
|
||||
result.configured = true;
|
||||
},
|
||||
never() {
|
||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
||||
if (result.forever) throw new Error("Caching has already been configured with .forever()");
|
||||
if (!active) {
|
||||
throw new Error(
|
||||
"Cannot change caching after evaluation has completed.",
|
||||
);
|
||||
}
|
||||
if (result.forever) {
|
||||
throw new Error(
|
||||
"Caching has already been configured with .forever()",
|
||||
);
|
||||
}
|
||||
result.never = true;
|
||||
result.configured = true;
|
||||
},
|
||||
using<T>(handler: () => T): T {
|
||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
||||
if (!active) {
|
||||
throw new Error(
|
||||
"Cannot change caching after evaluation has completed.",
|
||||
);
|
||||
}
|
||||
if (result.never || result.forever) {
|
||||
throw new Error("Caching has already been configured with .never or .forever()");
|
||||
throw new Error(
|
||||
"Caching has already been configured with .never or .forever()",
|
||||
);
|
||||
}
|
||||
result.configured = true;
|
||||
|
||||
const key = handler();
|
||||
pairs.push([ key, handler ]);
|
||||
pairs.push([key, handler]);
|
||||
return key;
|
||||
},
|
||||
invalidate<T>(handler: () => T): T {
|
||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
||||
if (!active) {
|
||||
throw new Error(
|
||||
"Cannot change caching after evaluation has completed.",
|
||||
);
|
||||
}
|
||||
if (result.never || result.forever) {
|
||||
throw new Error("Caching has already been configured with .never or .forever()");
|
||||
throw new Error(
|
||||
"Caching has already been configured with .never or .forever()",
|
||||
);
|
||||
}
|
||||
result.invalidate = true;
|
||||
result.configured = true;
|
||||
|
||||
const key = handler();
|
||||
pairs.push([ key, handler ]);
|
||||
pairs.push([key, handler]);
|
||||
return key;
|
||||
},
|
||||
}: CacheConfiguratorObj));
|
||||
}: CacheConfiguratorObj),
|
||||
);
|
||||
|
||||
return { cache, result, deactivate };
|
||||
}
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
// @flow
|
||||
|
||||
export function getEnv(defaultValue: string = "development"): string {
|
||||
return process.env.BABEL_ENV
|
||||
|| process.env.NODE_ENV
|
||||
|| defaultValue;
|
||||
return process.env.BABEL_ENV || process.env.NODE_ENV || defaultValue;
|
||||
}
|
||||
|
||||
@ -5,13 +5,13 @@ import manageOptions from "./option-manager";
|
||||
|
||||
export type ResolvedConfig = {
|
||||
options: Object,
|
||||
passes: Array<Array<[ Plugin, ?{} ]>>,
|
||||
passes: Array<Array<[Plugin, ?{}]>>,
|
||||
};
|
||||
|
||||
/**
|
||||
* Standard API for loading Babel configuration data. Not for public consumption.
|
||||
*/
|
||||
export default function loadConfig(opts: mixed): ResolvedConfig|null {
|
||||
export default function loadConfig(opts: mixed): ResolvedConfig | null {
|
||||
if (opts != null && typeof opts !== "object") {
|
||||
throw new Error("Babel options must be an object, null, or undefined");
|
||||
}
|
||||
|
||||
@ -41,13 +41,16 @@ export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
BABELRC_FILENAME,
|
||||
BABELRC_JS_FILENAME,
|
||||
PACKAGE_FILENAME,
|
||||
].reduce((previousConfig: ConfigFile|null, name) => {
|
||||
].reduce((previousConfig: ConfigFile | null, name) => {
|
||||
const filepath = path.join(loc, name);
|
||||
const config = readConfig(filepath);
|
||||
|
||||
if (config && previousConfig) {
|
||||
throw new Error(`Multiple configuration files found. Please remove one:\n- ${
|
||||
path.basename(previousConfig.filepath)}\n- ${name}\nfrom ${loc}`);
|
||||
throw new Error(
|
||||
`Multiple configuration files found. Please remove one:\n- ${path.basename(
|
||||
previousConfig.filepath,
|
||||
)}\n- ${name}\nfrom ${loc}`,
|
||||
);
|
||||
}
|
||||
|
||||
return config || previousConfig;
|
||||
@ -73,7 +76,9 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const conf = readConfig(filepath);
|
||||
if (!conf) throw new Error(`Config file ${filepath} contains no configuration data`);
|
||||
if (!conf) {
|
||||
throw new Error(`Config file ${filepath} contains no configuration data`);
|
||||
}
|
||||
|
||||
return conf;
|
||||
}
|
||||
@ -83,7 +88,9 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
* throw if there are parsing errors while loading a config.
|
||||
*/
|
||||
function readConfig(filepath) {
|
||||
return (path.extname(filepath) === ".js") ? readConfigJS(filepath) : readConfigFile(filepath);
|
||||
return path.extname(filepath) === ".js"
|
||||
? readConfigJS(filepath)
|
||||
: readConfigFile(filepath);
|
||||
}
|
||||
|
||||
const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
@ -96,7 +103,10 @@ const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
try {
|
||||
// $FlowIssue
|
||||
const configModule = (require(filepath): mixed);
|
||||
options = configModule && configModule.__esModule ? (configModule.default || undefined) : configModule;
|
||||
options =
|
||||
configModule && configModule.__esModule
|
||||
? configModule.default || undefined
|
||||
: configModule;
|
||||
} catch (err) {
|
||||
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
||||
throw err;
|
||||
@ -113,7 +123,9 @@ const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||
}
|
||||
|
||||
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
||||
throw new Error(`${filepath}: Configuration should be an exported JavaScript object.`);
|
||||
throw new Error(
|
||||
`${filepath}: Configuration should be an exported JavaScript object.`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -144,8 +156,12 @@ const readConfigFile = makeStaticFileCache((filepath, content) => {
|
||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||
}
|
||||
|
||||
if (typeof options !== "object") throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||
if (Array.isArray(options)) throw new Error(`${filepath}: Expected config object but found array`);
|
||||
if (typeof options !== "object") {
|
||||
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||
}
|
||||
if (Array.isArray(options)) {
|
||||
throw new Error(`${filepath}: Expected config object but found array`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
@ -157,8 +173,8 @@ const readConfigFile = makeStaticFileCache((filepath, content) => {
|
||||
const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
||||
const ignore = content
|
||||
.split("\n")
|
||||
.map((line) => line.replace(/#(.*?)$/, "").trim())
|
||||
.filter((line) => !!line);
|
||||
.map(line => line.replace(/#(.*?)$/, "").trim())
|
||||
.filter(line => !!line);
|
||||
|
||||
return {
|
||||
filepath,
|
||||
@ -167,7 +183,7 @@ const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
||||
};
|
||||
});
|
||||
|
||||
function makeStaticFileCache<T>(fn: (string, string) => T): (string) => T|null {
|
||||
function makeStaticFileCache<T>(fn: (string, string) => T): string => T | null {
|
||||
return makeStrongCache((filepath, cache) => {
|
||||
if (cache.invalidate(() => fileMtime(filepath)) === null) {
|
||||
cache.forever();
|
||||
@ -178,7 +194,7 @@ function makeStaticFileCache<T>(fn: (string, string) => T): (string) => T|null {
|
||||
});
|
||||
}
|
||||
|
||||
function fileMtime(filepath: string): number|null {
|
||||
function fileMtime(filepath: string): number | null {
|
||||
try {
|
||||
return +fs.statSync(filepath).mtime;
|
||||
} catch (e) {
|
||||
|
||||
@ -16,27 +16,47 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function resolvePlugin(name: string, dirname: string): string|null {
|
||||
export function resolvePlugin(name: string, dirname: string): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function resolvePreset(name: string, dirname: string): string|null {
|
||||
export function resolvePreset(name: string, dirname: string): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function loadPlugin(name: string, dirname: string): { filepath: string, value: mixed } {
|
||||
throw new Error(`Cannot load plugin ${name} relative to ${dirname} in a browser`);
|
||||
export function loadPlugin(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: mixed } {
|
||||
throw new Error(
|
||||
`Cannot load plugin ${name} relative to ${dirname} in a browser`,
|
||||
);
|
||||
}
|
||||
|
||||
export function loadPreset(name: string, dirname: string): { filepath: string, value: mixed } {
|
||||
throw new Error(`Cannot load preset ${name} relative to ${dirname} in a browser`);
|
||||
export function loadPreset(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: mixed } {
|
||||
throw new Error(
|
||||
`Cannot load preset ${name} relative to ${dirname} in a browser`,
|
||||
);
|
||||
}
|
||||
|
||||
export function loadParser(name: string, dirname: string): { filepath: string, value: Function } {
|
||||
throw new Error(`Cannot load parser ${name} relative to ${dirname} in a browser`);
|
||||
export function loadParser(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: Function } {
|
||||
throw new Error(
|
||||
`Cannot load parser ${name} relative to ${dirname} in a browser`,
|
||||
);
|
||||
}
|
||||
|
||||
export function loadGenerator(name: string, dirname: string): { filepath: string, value: Function } {
|
||||
throw new Error(`Cannot load generator ${name} relative to ${dirname} in a browser`);
|
||||
export function loadGenerator(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: Function } {
|
||||
throw new Error(
|
||||
`Cannot load generator ${name} relative to ${dirname} in a browser`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import typeof * as indexType from "./index";
|
||||
|
||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||
((({}: any) : $Exact<indexBrowserType>): $Exact<indexType>);
|
||||
((({}: any): $Exact<indexBrowserType>): $Exact<indexType>);
|
||||
|
||||
export * from "./configuration";
|
||||
export * from "./plugins";
|
||||
|
||||
@ -15,17 +15,22 @@ const BABEL_PRESET_ORG_RE = /^(@babel[/\/])(?!preset-|[^/\/]+[/\/])/;
|
||||
const OTHER_PLUGIN_ORG_RE = /^(@(?!babel[/\/])[^/\/]+[/\/])(?!babel-plugin-|[^/\/]+[/\/])/;
|
||||
const OTHER_PRESET_ORG_RE = /^(@(?!babel[/\/])[^/\/]+[/\/])(?!babel-preset-|[^/\/]+[/\/])/;
|
||||
|
||||
export function resolvePlugin(name: string, dirname: string): string|null {
|
||||
export function resolvePlugin(name: string, dirname: string): string | null {
|
||||
return resolveStandardizedName("plugin", name, dirname);
|
||||
}
|
||||
|
||||
export function resolvePreset(name: string, dirname: string): string|null {
|
||||
export function resolvePreset(name: string, dirname: string): string | null {
|
||||
return resolveStandardizedName("preset", name, dirname);
|
||||
}
|
||||
|
||||
export function loadPlugin(name: string, dirname: string): { filepath: string, value: mixed } {
|
||||
export function loadPlugin(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: mixed } {
|
||||
const filepath = resolvePlugin(name, dirname);
|
||||
if (!filepath) throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
||||
if (!filepath) {
|
||||
throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
@ -33,9 +38,14 @@ export function loadPlugin(name: string, dirname: string): { filepath: string, v
|
||||
};
|
||||
}
|
||||
|
||||
export function loadPreset(name: string, dirname: string): { filepath: string, value: mixed } {
|
||||
export function loadPreset(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: mixed } {
|
||||
const filepath = resolvePreset(name, dirname);
|
||||
if (!filepath) throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
||||
if (!filepath) {
|
||||
throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
||||
}
|
||||
|
||||
return {
|
||||
filepath,
|
||||
@ -43,16 +53,23 @@ export function loadPreset(name: string, dirname: string): { filepath: string, v
|
||||
};
|
||||
}
|
||||
|
||||
export function loadParser(name: string, dirname: string): { filepath: string, value: Function } {
|
||||
export function loadParser(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: Function } {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(`Parser ${name} relative to ${dirname} does not export an object`);
|
||||
throw new Error(
|
||||
`Parser ${name} relative to ${dirname} does not export an object`,
|
||||
);
|
||||
}
|
||||
if (typeof mod.parse !== "function") {
|
||||
throw new Error(`Parser ${name} relative to ${dirname} does not export a .parse function`);
|
||||
throw new Error(
|
||||
`Parser ${name} relative to ${dirname} does not export a .parse function`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -61,16 +78,23 @@ export function loadParser(name: string, dirname: string): { filepath: string, v
|
||||
};
|
||||
}
|
||||
|
||||
export function loadGenerator(name: string, dirname: string): { filepath: string, value: Function } {
|
||||
export function loadGenerator(
|
||||
name: string,
|
||||
dirname: string,
|
||||
): { filepath: string, value: Function } {
|
||||
const filepath = resolve.sync(name, { basedir: dirname });
|
||||
|
||||
const mod = requireModule(filepath);
|
||||
|
||||
if (!mod) {
|
||||
throw new Error(`Generator ${name} relative to ${dirname} does not export an object`);
|
||||
throw new Error(
|
||||
`Generator ${name} relative to ${dirname} does not export an object`,
|
||||
);
|
||||
}
|
||||
if (typeof mod.print !== "function") {
|
||||
throw new Error(`Generator ${name} relative to ${dirname} does not export a .print function`);
|
||||
throw new Error(
|
||||
`Generator ${name} relative to ${dirname} does not export a .print function`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -79,24 +103,39 @@ export function loadGenerator(name: string, dirname: string): { filepath: string
|
||||
};
|
||||
}
|
||||
|
||||
function standardizeName(type: "plugin"|"preset", name: string) {
|
||||
function standardizeName(type: "plugin" | "preset", name: string) {
|
||||
// Let absolute and relative paths through.
|
||||
if (path.isAbsolute(name)) return name;
|
||||
|
||||
const isPreset = type === "preset";
|
||||
|
||||
return name
|
||||
return (
|
||||
name
|
||||
// foo -> babel-preset-foo
|
||||
.replace(isPreset ? BABEL_PRESET_PREFIX_RE : BABEL_PLUGIN_PREFIX_RE, `babel-${type}-`)
|
||||
.replace(
|
||||
isPreset ? BABEL_PRESET_PREFIX_RE : BABEL_PLUGIN_PREFIX_RE,
|
||||
`babel-${type}-`,
|
||||
)
|
||||
// @babel/es2015 -> @babel/preset-es2015
|
||||
.replace(isPreset ? BABEL_PRESET_ORG_RE : BABEL_PLUGIN_ORG_RE, `$1${type}-`)
|
||||
.replace(
|
||||
isPreset ? BABEL_PRESET_ORG_RE : BABEL_PLUGIN_ORG_RE,
|
||||
`$1${type}-`,
|
||||
)
|
||||
// @foo/mypreset -> @foo/babel-preset-mypreset
|
||||
.replace(isPreset ? OTHER_PRESET_ORG_RE : OTHER_PLUGIN_ORG_RE, `$1babel-${type}-`)
|
||||
.replace(
|
||||
isPreset ? OTHER_PRESET_ORG_RE : OTHER_PLUGIN_ORG_RE,
|
||||
`$1babel-${type}-`,
|
||||
)
|
||||
// module:mypreset -> mypreset
|
||||
.replace(EXACT_RE, "");
|
||||
.replace(EXACT_RE, "")
|
||||
);
|
||||
}
|
||||
|
||||
function resolveStandardizedName(type: "plugin"|"preset", name: string, dirname: string = process.cwd()) {
|
||||
function resolveStandardizedName(
|
||||
type: "plugin" | "preset",
|
||||
name: string,
|
||||
dirname: string = process.cwd(),
|
||||
) {
|
||||
const standardizedName = standardizeName(type, name);
|
||||
|
||||
try {
|
||||
@ -109,7 +148,7 @@ function resolveStandardizedName(type: "plugin"|"preset", name: string, dirname:
|
||||
try {
|
||||
resolve.sync(name, { basedir: dirname });
|
||||
resolvedOriginal = true;
|
||||
} catch (e2) { }
|
||||
} catch (e2) {}
|
||||
|
||||
if (resolvedOriginal) {
|
||||
// eslint-disable-next-line max-len
|
||||
@ -119,9 +158,11 @@ function resolveStandardizedName(type: "plugin"|"preset", name: string, dirname:
|
||||
|
||||
let resolvedBabel = false;
|
||||
try {
|
||||
resolve.sync(standardizeName(type, "@babel/" + name), { basedir: dirname });
|
||||
resolve.sync(standardizeName(type, "@babel/" + name), {
|
||||
basedir: dirname,
|
||||
});
|
||||
resolvedBabel = true;
|
||||
} catch (e2) { }
|
||||
} catch (e2) {}
|
||||
|
||||
if (resolvedBabel) {
|
||||
// eslint-disable-next-line max-len
|
||||
@ -133,7 +174,7 @@ function resolveStandardizedName(type: "plugin"|"preset", name: string, dirname:
|
||||
try {
|
||||
resolve.sync(standardizeName(oppositeType, name), { basedir: dirname });
|
||||
resolvedOppositeType = true;
|
||||
} catch (e2) { }
|
||||
} catch (e2) {}
|
||||
|
||||
if (resolvedOppositeType) {
|
||||
// eslint-disable-next-line max-len
|
||||
|
||||
@ -11,14 +11,19 @@ import path from "path";
|
||||
import traverse from "babel-traverse";
|
||||
import clone from "lodash/clone";
|
||||
|
||||
import { loadPlugin, loadPreset, loadParser, loadGenerator } from "./loading/files";
|
||||
import {
|
||||
loadPlugin,
|
||||
loadPreset,
|
||||
loadParser,
|
||||
loadGenerator,
|
||||
} from "./loading/files";
|
||||
|
||||
type MergeOptions = {
|
||||
+type: "arguments"|"options"|"preset",
|
||||
+type: "arguments" | "options" | "preset",
|
||||
options: {},
|
||||
alias: string,
|
||||
loc: string,
|
||||
dirname: string
|
||||
dirname: string,
|
||||
};
|
||||
|
||||
const optionNames = new Set([
|
||||
@ -74,8 +79,8 @@ const ALLOWED_PLUGIN_KEYS = new Set([
|
||||
|
||||
export default function manageOptions(opts: {}): {
|
||||
options: Object,
|
||||
passes: Array<Array<[ Plugin, ?{} ]>>,
|
||||
}|null {
|
||||
passes: Array<Array<[Plugin, ?{}]>>,
|
||||
} | null {
|
||||
return new OptionManager().init(opts);
|
||||
}
|
||||
|
||||
@ -100,9 +105,12 @@ class OptionManager {
|
||||
mergeOptions(config: MergeOptions, pass?: Array<[Plugin, ?{}]>) {
|
||||
const result = loadConfig(config);
|
||||
|
||||
const plugins = result.plugins.map((descriptor) => loadPluginDescriptor(descriptor));
|
||||
const presets = result.presets.map((descriptor) => loadPresetDescriptor(descriptor));
|
||||
|
||||
const plugins = result.plugins.map(descriptor =>
|
||||
loadPluginDescriptor(descriptor),
|
||||
);
|
||||
const presets = result.presets.map(descriptor =>
|
||||
loadPresetDescriptor(descriptor),
|
||||
);
|
||||
|
||||
if (
|
||||
config.options.passPerPreset != null &&
|
||||
@ -148,7 +156,8 @@ 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;
|
||||
const filename =
|
||||
typeof opts.filename === "string" ? opts.filename : null;
|
||||
e.message = `[BABEL] ${filename || "unknown"}: ${e.message}`;
|
||||
}
|
||||
|
||||
@ -160,9 +169,10 @@ class OptionManager {
|
||||
// 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.
|
||||
opts.plugins = this.passes[0];
|
||||
opts.presets = this.passes.slice(1)
|
||||
.filter((plugins) => plugins.length > 0)
|
||||
.map((plugins) => ({ plugins }));
|
||||
opts.presets = this.passes
|
||||
.slice(1)
|
||||
.filter(plugins => plugins.length > 0)
|
||||
.map(plugins => ({ plugins }));
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMaps = true;
|
||||
@ -199,7 +209,7 @@ class OptionManager {
|
||||
}
|
||||
|
||||
type BasicDescriptor = {
|
||||
value: {}|Function,
|
||||
value: {} | Function,
|
||||
options: ?{},
|
||||
dirname: string,
|
||||
alias: string,
|
||||
@ -209,19 +219,28 @@ type BasicDescriptor = {
|
||||
/**
|
||||
* Load and validate the given config into a set of options, plugins, and presets.
|
||||
*/
|
||||
function loadConfig(config): {
|
||||
function loadConfig(
|
||||
config,
|
||||
): {
|
||||
options: {},
|
||||
plugins: Array<BasicDescriptor>,
|
||||
presets: Array<BasicDescriptor>,
|
||||
} {
|
||||
const options = normalizeOptions(config);
|
||||
|
||||
if (config.options.plugins != null && !Array.isArray(config.options.plugins)) {
|
||||
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) => {
|
||||
const { filepath, value, options } = normalizePair(plugin, loadPlugin, config.dirname);
|
||||
const { filepath, value, options } = normalizePair(
|
||||
plugin,
|
||||
loadPlugin,
|
||||
config.dirname,
|
||||
);
|
||||
|
||||
return {
|
||||
alias: filepath || `${config.loc}$${index}`,
|
||||
@ -232,12 +251,19 @@ function loadConfig(config): {
|
||||
};
|
||||
});
|
||||
|
||||
if (config.options.presets != null && !Array.isArray(config.options.presets)) {
|
||||
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);
|
||||
const { filepath, value, options } = normalizePair(
|
||||
preset,
|
||||
loadPreset,
|
||||
config.dirname,
|
||||
);
|
||||
|
||||
return {
|
||||
alias: filepath || `${config.loc}$${index}`,
|
||||
@ -255,7 +281,9 @@ function loadConfig(config): {
|
||||
* Load a generic plugin/preset from the given descriptor loaded from the config object.
|
||||
*/
|
||||
function loadDescriptor(descriptor, skipOptions) {
|
||||
if (typeof descriptor.value !== "function") return { value: descriptor.value, descriptor };
|
||||
if (typeof descriptor.value !== "function") {
|
||||
return { value: descriptor.value, descriptor };
|
||||
}
|
||||
|
||||
const { value, options } = descriptor;
|
||||
let item;
|
||||
@ -266,7 +294,9 @@ function loadDescriptor(descriptor, skipOptions) {
|
||||
item = value(context, options, { dirname: descriptor.dirname });
|
||||
}
|
||||
} catch (e) {
|
||||
if (descriptor.alias) e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`;
|
||||
if (descriptor.alias) {
|
||||
e.message += ` (While processing: ${JSON.stringify(descriptor.alias)})`;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
@ -282,26 +312,37 @@ function loadDescriptor(descriptor, skipOptions) {
|
||||
*/
|
||||
const PLUGIN_CACHE = new WeakMap();
|
||||
function loadPluginDescriptor(descriptor) {
|
||||
if (descriptor.value instanceof Plugin) return [ descriptor.value, descriptor.options ];
|
||||
if (descriptor.value instanceof Plugin) {
|
||||
return [descriptor.value, descriptor.options];
|
||||
}
|
||||
|
||||
let result = PLUGIN_CACHE.get(descriptor.value);
|
||||
if (!result) {
|
||||
result = instantiatePlugin(loadDescriptor(descriptor, true /* skipOptions */));
|
||||
result = instantiatePlugin(
|
||||
loadDescriptor(descriptor, true /* skipOptions */),
|
||||
);
|
||||
PLUGIN_CACHE.set(descriptor.value, result);
|
||||
}
|
||||
|
||||
return [ result, descriptor.options];
|
||||
return [result, descriptor.options];
|
||||
}
|
||||
|
||||
function instantiatePlugin({ value: pluginObj, descriptor }) {
|
||||
Object.keys(pluginObj).forEach((key) => {
|
||||
Object.keys(pluginObj).forEach(key => {
|
||||
if (!ALLOWED_PLUGIN_KEYS.has(key)) {
|
||||
throw new Error(messages.get("pluginInvalidProperty", descriptor.alias, key));
|
||||
throw new Error(
|
||||
messages.get("pluginInvalidProperty", descriptor.alias, key),
|
||||
);
|
||||
}
|
||||
});
|
||||
if (pluginObj.visitor && (pluginObj.visitor.enter || pluginObj.visitor.exit)) {
|
||||
throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. " +
|
||||
"Please target individual nodes.");
|
||||
if (
|
||||
pluginObj.visitor &&
|
||||
(pluginObj.visitor.enter || pluginObj.visitor.exit)
|
||||
) {
|
||||
throw new Error(
|
||||
"Plugins aren't allowed to specify catch-all enter/exit handlers. " +
|
||||
"Please target individual nodes.",
|
||||
);
|
||||
}
|
||||
|
||||
const plugin = Object.assign({}, pluginObj, {
|
||||
@ -325,8 +366,14 @@ function instantiatePlugin({ value: pluginObj, descriptor }) {
|
||||
|
||||
plugin.pre = chain(inherits.pre, plugin.pre);
|
||||
plugin.post = chain(inherits.post, plugin.post);
|
||||
plugin.manipulateOptions = chain(inherits.manipulateOptions, plugin.manipulateOptions);
|
||||
plugin.visitor = traverse.visitors.merge([inherits.visitor, plugin.visitor]);
|
||||
plugin.manipulateOptions = chain(
|
||||
inherits.manipulateOptions,
|
||||
plugin.manipulateOptions,
|
||||
);
|
||||
plugin.visitor = traverse.visitors.merge([
|
||||
inherits.visitor,
|
||||
plugin.visitor,
|
||||
]);
|
||||
}
|
||||
|
||||
return new Plugin(plugin, descriptor.alias);
|
||||
@ -371,10 +418,18 @@ function normalizeOptions(config) {
|
||||
}
|
||||
|
||||
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.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) {
|
||||
@ -390,7 +445,10 @@ function normalizeOptions(config) {
|
||||
// check for an unknown option
|
||||
if (!optionNames.has(key)) {
|
||||
if (removed[key]) {
|
||||
throw new ReferenceError(`Using removed Babel 5 option: ${alias}.${key} - ${removed[key].message}`);
|
||||
throw new ReferenceError(
|
||||
`Using removed Babel 5 option: ${alias}.${key} - ${removed[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.`;
|
||||
@ -402,12 +460,21 @@ function normalizeOptions(config) {
|
||||
|
||||
if (options.parserOpts && typeof options.parserOpts.parser === "string") {
|
||||
options.parserOpts = Object.assign({}, options.parserOpts);
|
||||
options.parserOpts.parser = loadParser(options.parserOpts.parser, config.dirname).value;
|
||||
options.parserOpts.parser = loadParser(
|
||||
options.parserOpts.parser,
|
||||
config.dirname,
|
||||
).value;
|
||||
}
|
||||
|
||||
if (options.generatorOpts && typeof options.generatorOpts.generator === "string") {
|
||||
if (
|
||||
options.generatorOpts &&
|
||||
typeof options.generatorOpts.generator === "string"
|
||||
) {
|
||||
options.generatorOpts = Object.assign({}, options.generatorOpts);
|
||||
options.generatorOpts.generator = loadGenerator(options.generatorOpts.generator, config.dirname).value;
|
||||
options.generatorOpts.generator = loadGenerator(
|
||||
options.generatorOpts.generator,
|
||||
config.dirname,
|
||||
).value;
|
||||
}
|
||||
|
||||
delete options.passPerPreset;
|
||||
@ -420,16 +487,22 @@ function normalizeOptions(config) {
|
||||
/**
|
||||
* Given a plugin/preset item, resolve it into a standard format.
|
||||
*/
|
||||
function normalizePair(pair: mixed, resolver, dirname): {
|
||||
filepath: string|null,
|
||||
value: {}|Function,
|
||||
function normalizePair(
|
||||
pair: mixed,
|
||||
resolver,
|
||||
dirname,
|
||||
): {
|
||||
filepath: string | null,
|
||||
value: {} | Function,
|
||||
options: ?{},
|
||||
} {
|
||||
let options;
|
||||
let value = pair;
|
||||
if (Array.isArray(pair)) {
|
||||
if (pair.length > 2) {
|
||||
throw new Error(`Unexpected extra options ${JSON.stringify(pair.slice(2))}.`);
|
||||
throw new Error(
|
||||
`Unexpected extra options ${JSON.stringify(pair.slice(2))}.`,
|
||||
);
|
||||
}
|
||||
|
||||
[value, options] = pair;
|
||||
@ -437,10 +510,7 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
||||
|
||||
let filepath = null;
|
||||
if (typeof value === "string") {
|
||||
({
|
||||
filepath,
|
||||
value,
|
||||
} = resolver(value, dirname));
|
||||
({ filepath, value } = resolver(value, dirname));
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
@ -456,11 +526,15 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
||||
}
|
||||
|
||||
if (typeof value !== "object" && typeof value !== "function") {
|
||||
throw new Error(`Unsupported format: ${typeof value}. Expected an object or a function.`);
|
||||
throw new Error(
|
||||
`Unsupported format: ${typeof value}. Expected an object or a function.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (options != null && typeof options !== "object") {
|
||||
throw new Error("Plugin/Preset options must be an object, null, or undefined");
|
||||
throw new Error(
|
||||
"Plugin/Preset options must be an object, null, or undefined",
|
||||
);
|
||||
}
|
||||
|
||||
return { filepath, value, options };
|
||||
|
||||
@ -5,8 +5,13 @@ export default class Plugin {
|
||||
if (plugin.name != null && typeof plugin.name !== "string") {
|
||||
throw new Error("Plugin .name must be a string, null, or undefined");
|
||||
}
|
||||
if (plugin.manipulateOptions != null && typeof plugin.manipulateOptions !== "function") {
|
||||
throw new Error("Plugin .manipulateOptions must be a function, null, or undefined");
|
||||
if (
|
||||
plugin.manipulateOptions != null &&
|
||||
typeof plugin.manipulateOptions !== "function"
|
||||
) {
|
||||
throw new Error(
|
||||
"Plugin .manipulateOptions must be a function, null, or undefined",
|
||||
);
|
||||
}
|
||||
if (plugin.post != null && typeof plugin.post !== "function") {
|
||||
throw new Error("Plugin .post must be a function, null, or undefined");
|
||||
|
||||
@ -2,52 +2,58 @@
|
||||
/* eslint max-len: "off" */
|
||||
|
||||
export default {
|
||||
"auxiliaryComment": {
|
||||
"message": "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
||||
auxiliaryComment: {
|
||||
message: "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
||||
},
|
||||
"blacklist": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
blacklist: {
|
||||
message: "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"breakConfig": {
|
||||
"message": "This is not a necessary option in Babel 6",
|
||||
breakConfig: {
|
||||
message: "This is not a necessary option in Babel 6",
|
||||
},
|
||||
"experimental": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
experimental: {
|
||||
message: "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"externalHelpers": {
|
||||
"message": "Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/",
|
||||
externalHelpers: {
|
||||
message:
|
||||
"Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/",
|
||||
},
|
||||
"extra": {
|
||||
"message": "",
|
||||
extra: {
|
||||
message: "",
|
||||
},
|
||||
"jsxPragma": {
|
||||
"message": "use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/",
|
||||
jsxPragma: {
|
||||
message:
|
||||
"use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/",
|
||||
},
|
||||
// "keepModuleIdExtensions": {
|
||||
// "message": ""
|
||||
// },
|
||||
"loose": {
|
||||
"message": "Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option.",
|
||||
loose: {
|
||||
message:
|
||||
"Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option.",
|
||||
},
|
||||
"metadataUsedHelpers": {
|
||||
"message": "Not required anymore as this is enabled by default",
|
||||
metadataUsedHelpers: {
|
||||
message: "Not required anymore as this is enabled by default",
|
||||
},
|
||||
"modules": {
|
||||
"message": "Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules",
|
||||
modules: {
|
||||
message:
|
||||
"Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules",
|
||||
},
|
||||
"nonStandard": {
|
||||
"message": "Use the `react-jsx` and `flow-strip-types` plugins to support JSX and Flow. Also check out the react preset http://babeljs.io/docs/plugins/preset-react/",
|
||||
nonStandard: {
|
||||
message:
|
||||
"Use the `react-jsx` and `flow-strip-types` plugins to support JSX and Flow. Also check out the react preset http://babeljs.io/docs/plugins/preset-react/",
|
||||
},
|
||||
"optional": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
optional: {
|
||||
message: "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
"sourceMapName": {
|
||||
"message": "Use the `sourceMapTarget` option",
|
||||
sourceMapName: {
|
||||
message: "Use the `sourceMapTarget` option",
|
||||
},
|
||||
"stage": {
|
||||
"message": "Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets",
|
||||
stage: {
|
||||
message:
|
||||
"Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets",
|
||||
},
|
||||
"whitelist": {
|
||||
"message": "Put the specific transforms you want in the `plugins` option",
|
||||
whitelist: {
|
||||
message: "Put the specific transforms you want in the `plugins` option",
|
||||
},
|
||||
};
|
||||
|
||||
@ -12,7 +12,7 @@ export template from "babel-template";
|
||||
|
||||
import loadConfig from "./config";
|
||||
|
||||
export function loadOptions(opts): Object|null {
|
||||
export function loadOptions(opts): Object | null {
|
||||
const config = loadConfig(opts);
|
||||
|
||||
return config ? config.options : null;
|
||||
@ -41,4 +41,10 @@ export {
|
||||
* Recommended set of compilable extensions. Not used in babel-core directly, but meant as
|
||||
* as an easy source for tooling making use of babel-core.
|
||||
*/
|
||||
export const DEFAULT_EXTENSIONS = Object.freeze([".js", ".jsx", ".es6", ".es", ".mjs"]);
|
||||
export const DEFAULT_EXTENSIONS = Object.freeze([
|
||||
".js",
|
||||
".jsx",
|
||||
".es6",
|
||||
".es",
|
||||
".mjs",
|
||||
]);
|
||||
|
||||
@ -20,17 +20,29 @@ const buildUmdWrapper = template(`
|
||||
|
||||
function buildGlobal(namespace, builder) {
|
||||
const body = [];
|
||||
const container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
const container = t.functionExpression(
|
||||
null,
|
||||
[t.identifier("global")],
|
||||
t.blockStatement(body),
|
||||
);
|
||||
const tree = t.program([
|
||||
t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]);
|
||||
t.expressionStatement(
|
||||
t.callExpression(container, [helpers.get("selfGlobal")]),
|
||||
),
|
||||
]);
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
body.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
namespace,
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace),
|
||||
t.objectExpression([]))
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(t.identifier("global"), namespace),
|
||||
t.objectExpression([]),
|
||||
),
|
||||
]));
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
builder(body);
|
||||
|
||||
@ -39,9 +51,11 @@ function buildGlobal(namespace, builder) {
|
||||
|
||||
function buildUmd(namespace, builder) {
|
||||
const body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
body.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.identifier("global")),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
|
||||
builder(body);
|
||||
|
||||
@ -51,7 +65,7 @@ function buildUmd(namespace, builder) {
|
||||
BROWSER_ARGUMENTS: t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(t.identifier("root"), namespace),
|
||||
t.objectExpression([])
|
||||
t.objectExpression([]),
|
||||
),
|
||||
COMMON_ARGUMENTS: t.identifier("exports"),
|
||||
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
||||
@ -63,31 +77,39 @@ function buildUmd(namespace, builder) {
|
||||
|
||||
function buildVar(namespace, builder) {
|
||||
const body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
body.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.objectExpression([])),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
builder(body);
|
||||
body.push(t.expressionStatement(namespace));
|
||||
return t.program(body);
|
||||
}
|
||||
|
||||
function buildHelpers(body, namespace, whitelist) {
|
||||
helpers.list.forEach(function (name) {
|
||||
helpers.list.forEach(function(name) {
|
||||
if (whitelist && whitelist.indexOf(name) < 0) return;
|
||||
|
||||
const key = t.identifier(name);
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(namespace, key), helpers.get(name))
|
||||
));
|
||||
body.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(namespace, key),
|
||||
helpers.get(name),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
export default function (
|
||||
export default function(
|
||||
whitelist?: Array<string>,
|
||||
outputType: "global" | "umd" | "var" = "global",
|
||||
) {
|
||||
const namespace = t.identifier("babelHelpers");
|
||||
|
||||
const builder = function (body) {
|
||||
const builder = function(body) {
|
||||
return buildHelpers(body, namespace, whitelist);
|
||||
};
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ export default class File extends Store {
|
||||
// passed babel-core's export object, which loads this file, and this 'loadConfig' loading plugins.
|
||||
INTERNAL_PLUGINS = loadConfig({
|
||||
babelrc: false,
|
||||
plugins: [ blockHoistPlugin ],
|
||||
plugins: [blockHoistPlugin],
|
||||
}).passes[0];
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ export default class File extends Store {
|
||||
};
|
||||
|
||||
for (const pluginPairs of passes) {
|
||||
for (const [ plugin ] of pluginPairs) {
|
||||
for (const [plugin] of pluginPairs) {
|
||||
if (plugin.manipulateOptions) {
|
||||
plugin.manipulateOptions(this.opts, this.parserOpts, this);
|
||||
}
|
||||
@ -150,7 +150,7 @@ export default class File extends Store {
|
||||
|
||||
if (opts.sourceRoot != null) {
|
||||
// remove sourceRoot from filename
|
||||
const sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
||||
const sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "/?");
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
@ -172,17 +172,25 @@ export default class File extends Store {
|
||||
|
||||
resolveModuleSource(source: string): string {
|
||||
const resolveModuleSource = this.opts.resolveModuleSource;
|
||||
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
|
||||
if (resolveModuleSource) {
|
||||
source = resolveModuleSource(source, this.opts.filename);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
addImport(source: string, imported: string, name?: string = imported): Object {
|
||||
addImport(
|
||||
source: string,
|
||||
imported: string,
|
||||
name?: string = imported,
|
||||
): Object {
|
||||
const alias = `${source}:${imported}`;
|
||||
let id = this.dynamicImportIds[alias];
|
||||
|
||||
if (!id) {
|
||||
source = this.resolveModuleSource(source);
|
||||
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(name);
|
||||
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(
|
||||
name,
|
||||
);
|
||||
|
||||
const specifiers = [];
|
||||
|
||||
@ -222,7 +230,9 @@ export default class File extends Store {
|
||||
}
|
||||
|
||||
const ref = getHelper(name);
|
||||
const uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
|
||||
const uid = (this.declarations[name] = this.scope.generateUidIdentifier(
|
||||
name,
|
||||
));
|
||||
|
||||
if (t.isFunctionExpression(ref) && !ref.id) {
|
||||
ref.body._compact = true;
|
||||
@ -257,7 +267,9 @@ export default class File extends Store {
|
||||
const declar = this.declarations[name];
|
||||
if (declar) return declar;
|
||||
|
||||
const uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject");
|
||||
const uid = (this.declarations[name] = this.scope.generateUidIdentifier(
|
||||
"templateObject",
|
||||
));
|
||||
|
||||
const helperId = this.addHelper(helperName);
|
||||
const init = t.callExpression(helperId, [strings, raw]);
|
||||
@ -270,7 +282,11 @@ export default class File extends Store {
|
||||
return uid;
|
||||
}
|
||||
|
||||
buildCodeFrameError(node: Object, msg: string, Error: typeof Error = SyntaxError): Error {
|
||||
buildCodeFrameError(
|
||||
node: Object,
|
||||
msg: string,
|
||||
Error: typeof Error = SyntaxError,
|
||||
): Error {
|
||||
const loc = node && (node.loc || node._loc);
|
||||
|
||||
const err = new Error(msg);
|
||||
@ -280,7 +296,8 @@ export default class File extends Store {
|
||||
} else {
|
||||
traverse(node, errorVisitor, this.scope, err);
|
||||
|
||||
err.message += " (This is an error on an internal node. Probably an internal error";
|
||||
err.message +=
|
||||
" (This is an error on an internal node. Probably an internal error";
|
||||
|
||||
if (err.loc) {
|
||||
err.message += ". Location has been estimated.";
|
||||
@ -308,7 +325,7 @@ export default class File extends Store {
|
||||
// single source file to a single output file.
|
||||
const source = outputMapConsumer.sources[0];
|
||||
|
||||
inputMapConsumer.eachMapping(function (mapping) {
|
||||
inputMapConsumer.eachMapping(function(mapping) {
|
||||
const generatedPosition = outputMapConsumer.generatedPositionFor({
|
||||
line: mapping.generatedLine,
|
||||
column: mapping.generatedColumn,
|
||||
@ -318,7 +335,10 @@ export default class File extends Store {
|
||||
mergedGenerator.addMapping({
|
||||
source: mapping.source,
|
||||
|
||||
original: mapping.source == null ? null : {
|
||||
original:
|
||||
mapping.source == null
|
||||
? null
|
||||
: {
|
||||
line: mapping.originalLine,
|
||||
column: mapping.originalColumn,
|
||||
},
|
||||
@ -385,15 +405,15 @@ export default class File extends Store {
|
||||
const passes = [];
|
||||
const visitors = [];
|
||||
|
||||
for (const [ plugin, pluginOpts ] of pluginPairs.concat(INTERNAL_PLUGINS)) {
|
||||
for (const [plugin, pluginOpts] of pluginPairs.concat(INTERNAL_PLUGINS)) {
|
||||
const pass = new PluginPass(this, plugin.key, pluginOpts);
|
||||
|
||||
passPairs.push([ plugin, pass ]);
|
||||
passPairs.push([plugin, pass]);
|
||||
passes.push(pass);
|
||||
visitors.push(plugin.visitor);
|
||||
}
|
||||
|
||||
for (const [ plugin, pass ] of passPairs) {
|
||||
for (const [plugin, pass] of passPairs) {
|
||||
const fn = plugin.pre;
|
||||
if (fn) fn.call(pass, this);
|
||||
}
|
||||
@ -401,16 +421,19 @@ export default class File extends Store {
|
||||
debug(this.opts, "Start transform traverse");
|
||||
|
||||
// merge all plugin visitors into a single visitor
|
||||
const visitor = traverse.visitors.merge(visitors, passes, this.opts.wrapPluginVisitorMethod);
|
||||
const visitor = traverse.visitors.merge(
|
||||
visitors,
|
||||
passes,
|
||||
this.opts.wrapPluginVisitorMethod,
|
||||
);
|
||||
traverse(this.ast, visitor, this.scope);
|
||||
|
||||
debug(this.opts, "End transform traverse");
|
||||
|
||||
for (const [ plugin, pass ] of passPairs) {
|
||||
for (const [plugin, pass] of passPairs) {
|
||||
const fn = plugin.post;
|
||||
if (fn) fn.call(pass, this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this.generate();
|
||||
@ -428,7 +451,7 @@ export default class File extends Store {
|
||||
err._babel = true;
|
||||
}
|
||||
|
||||
let message = err.message = `${this.opts.filename}: ${err.message}`;
|
||||
let message = (err.message = `${this.opts.filename}: ${err.message}`);
|
||||
|
||||
const loc = err.loc;
|
||||
if (loc) {
|
||||
@ -530,8 +553,11 @@ export default class File extends Store {
|
||||
|
||||
debug(this.opts, "Generation start");
|
||||
|
||||
const _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts,
|
||||
this.code);
|
||||
const _result = gen(
|
||||
ast,
|
||||
opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts,
|
||||
this.code,
|
||||
);
|
||||
result.code = _result.code;
|
||||
result.map = _result.map;
|
||||
|
||||
|
||||
@ -5,7 +5,11 @@ import * as t from "babel-types";
|
||||
import File from "./file";
|
||||
import loadConfig from "../config";
|
||||
|
||||
export function analyse(code: string, opts: Object = {}, visitor?: Object): ?BabelFileMetadata {
|
||||
export function analyse(
|
||||
code: string,
|
||||
opts: Object = {},
|
||||
visitor?: Object,
|
||||
): ?BabelFileMetadata {
|
||||
opts.code = false;
|
||||
if (visitor) {
|
||||
opts.plugins = opts.plugins || [];
|
||||
@ -19,14 +23,18 @@ export function transform(code: string, opts?: Object): BabelFileResult {
|
||||
if (config === null) return null;
|
||||
|
||||
const file = new File(config);
|
||||
return file.wrap(code, function () {
|
||||
return file.wrap(code, function() {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file.transform();
|
||||
});
|
||||
}
|
||||
|
||||
export function transformFromAst(ast: Object, code: string, opts: Object): BabelFileResult {
|
||||
export function transformFromAst(
|
||||
ast: Object,
|
||||
code: string,
|
||||
opts: Object,
|
||||
): BabelFileResult {
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
|
||||
@ -37,14 +45,18 @@ export function transformFromAst(ast: Object, code: string, opts: Object): Babel
|
||||
}
|
||||
|
||||
const file = new File(config);
|
||||
return file.wrap(code, function () {
|
||||
return file.wrap(code, function() {
|
||||
file.addCode(code);
|
||||
file.addAst(ast);
|
||||
return file.transform();
|
||||
});
|
||||
}
|
||||
|
||||
export function transformFile(filename: string, opts?: Object, callback: Function) {
|
||||
export function transformFile(
|
||||
filename: string,
|
||||
opts?: Object,
|
||||
callback: Function,
|
||||
) {
|
||||
if (typeof opts === "function") {
|
||||
callback = opts;
|
||||
opts = {};
|
||||
@ -54,13 +66,13 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return callback(null, null);
|
||||
|
||||
fs.readFile(filename, function (err, code) {
|
||||
fs.readFile(filename, function(err, code) {
|
||||
let result;
|
||||
|
||||
if (!err) {
|
||||
try {
|
||||
const file = new File(config);
|
||||
result = file.wrap(code, function () {
|
||||
result = file.wrap(code, function() {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file.transform();
|
||||
@ -78,7 +90,10 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
|
||||
});
|
||||
}
|
||||
|
||||
export function transformFileSync(filename: string, opts?: Object = {}): string {
|
||||
export function transformFileSync(
|
||||
filename: string,
|
||||
opts?: Object = {},
|
||||
): string {
|
||||
opts.filename = filename;
|
||||
const config = loadConfig(opts);
|
||||
if (config === null) return null;
|
||||
@ -86,7 +101,7 @@ export function transformFileSync(filename: string, opts?: Object = {}): string
|
||||
const code = fs.readFileSync(filename, "utf8");
|
||||
const file = new File(config);
|
||||
|
||||
return file.wrap(code, function () {
|
||||
return file.wrap(code, function() {
|
||||
file.addCode(code);
|
||||
file.parseCode(code);
|
||||
return file.transform();
|
||||
|
||||
@ -17,7 +17,7 @@ function assertNotIgnored(result) {
|
||||
// shim
|
||||
function transformAsync(code, opts) {
|
||||
return {
|
||||
then: function (resolve) {
|
||||
then: function(resolve) {
|
||||
resolve(babel.transform(code, opts));
|
||||
},
|
||||
};
|
||||
@ -55,11 +55,14 @@ describe("parser and generator options", function() {
|
||||
it("experimental syntax", function() {
|
||||
const experimental = "var a: number = 1;";
|
||||
|
||||
assert.deepEqual(newTransform(experimental).ast, babel.transform(experimental, {
|
||||
assert.deepEqual(
|
||||
newTransform(experimental).ast,
|
||||
babel.transform(experimental, {
|
||||
parserOpts: {
|
||||
plugins: ["flow"],
|
||||
},
|
||||
}).ast);
|
||||
}).ast,
|
||||
);
|
||||
assert.equal(newTransform(experimental).code, experimental);
|
||||
|
||||
function newTransformWithPlugins(string) {
|
||||
@ -74,126 +77,158 @@ describe("parser and generator options", function() {
|
||||
});
|
||||
}
|
||||
|
||||
assert.deepEqual(newTransformWithPlugins(experimental).ast, babel.transform(experimental, {
|
||||
assert.deepEqual(
|
||||
newTransformWithPlugins(experimental).ast,
|
||||
babel.transform(experimental, {
|
||||
parserOpts: {
|
||||
plugins: ["flow"],
|
||||
},
|
||||
}).ast);
|
||||
}).ast,
|
||||
);
|
||||
assert.equal(newTransformWithPlugins(experimental).code, experimental);
|
||||
});
|
||||
|
||||
it("other options", function() {
|
||||
const experimental = "if (true) {\n import a from 'a';\n}";
|
||||
|
||||
assert.notEqual(newTransform(experimental).ast, babel.transform(experimental, {
|
||||
assert.notEqual(
|
||||
newTransform(experimental).ast,
|
||||
babel.transform(experimental, {
|
||||
parserOpts: {
|
||||
allowImportExportEverywhere: true,
|
||||
},
|
||||
}).ast);
|
||||
}).ast,
|
||||
);
|
||||
assert.equal(newTransform(experimental).code, experimental);
|
||||
});
|
||||
});
|
||||
|
||||
describe("api", function () {
|
||||
it("analyze", function () {
|
||||
describe("api", function() {
|
||||
it("analyze", function() {
|
||||
assert.equal(babel.analyse("foobar;").marked.length, 0);
|
||||
|
||||
assert.equal(babel.analyse("foobar;", {
|
||||
plugins: [new Plugin({
|
||||
assert.equal(
|
||||
babel.analyse("foobar;", {
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
Program: function (path) {
|
||||
Program: function(path) {
|
||||
path.mark("category", "foobar");
|
||||
},
|
||||
},
|
||||
})],
|
||||
}).marked[0].message, "foobar");
|
||||
}),
|
||||
],
|
||||
}).marked[0].message,
|
||||
"foobar",
|
||||
);
|
||||
|
||||
assert.equal(babel.analyse("foobar;", {}, {
|
||||
Program: function (path) {
|
||||
assert.equal(
|
||||
babel.analyse(
|
||||
"foobar;",
|
||||
{},
|
||||
{
|
||||
Program: function(path) {
|
||||
path.mark("category", "foobar");
|
||||
},
|
||||
}).marked[0].message, "foobar");
|
||||
});
|
||||
|
||||
it("exposes the resolvePlugin method", function() {
|
||||
assert.throws(() => babel.resolvePlugin("nonexistent-plugin"),
|
||||
/Cannot find module 'babel-plugin-nonexistent-plugin'/);
|
||||
});
|
||||
|
||||
it("exposes the resolvePreset method", function() {
|
||||
assert.throws(() => babel.resolvePreset("nonexistent-preset"),
|
||||
/Cannot find module 'babel-preset-nonexistent-preset'/);
|
||||
});
|
||||
|
||||
it("transformFile", function (done) {
|
||||
babel.transformFile(__dirname + "/fixtures/api/file.js", {
|
||||
babelrc: false,
|
||||
}, function (err, res) {
|
||||
if (err) return done(err);
|
||||
assert.equal(res.code, "foo();");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("transformFileSync", function () {
|
||||
assert.equal(babel.transformFileSync(__dirname + "/fixtures/api/file.js", {
|
||||
babelrc: false,
|
||||
}).code, "foo();");
|
||||
});
|
||||
|
||||
it("options throw on falsy true", function () {
|
||||
return assert.throws(
|
||||
function () {
|
||||
babel.transform("", {
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
||||
});
|
||||
},
|
||||
/Error: \[BABEL\] unknown: Unexpected falsy value: false/
|
||||
).marked[0].message,
|
||||
"foobar",
|
||||
);
|
||||
});
|
||||
|
||||
it("options merge backwards", function () {
|
||||
it("exposes the resolvePlugin method", function() {
|
||||
assert.throws(
|
||||
() => babel.resolvePlugin("nonexistent-plugin"),
|
||||
/Cannot find module 'babel-plugin-nonexistent-plugin'/,
|
||||
);
|
||||
});
|
||||
|
||||
it("exposes the resolvePreset method", function() {
|
||||
assert.throws(
|
||||
() => babel.resolvePreset("nonexistent-preset"),
|
||||
/Cannot find module 'babel-preset-nonexistent-preset'/,
|
||||
);
|
||||
});
|
||||
|
||||
it("transformFile", function(done) {
|
||||
babel.transformFile(
|
||||
__dirname + "/fixtures/api/file.js",
|
||||
{
|
||||
babelrc: false,
|
||||
},
|
||||
function(err, res) {
|
||||
if (err) return done(err);
|
||||
assert.equal(res.code, "foo();");
|
||||
done();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("transformFileSync", function() {
|
||||
assert.equal(
|
||||
babel.transformFileSync(__dirname + "/fixtures/api/file.js", {
|
||||
babelrc: false,
|
||||
}).code,
|
||||
"foo();",
|
||||
);
|
||||
});
|
||||
|
||||
it("options throw on falsy true", function() {
|
||||
return assert.throws(function() {
|
||||
babel.transform("", {
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
||||
});
|
||||
}, /Error: \[BABEL\] unknown: Unexpected falsy value: false/);
|
||||
});
|
||||
|
||||
it("options merge backwards", function() {
|
||||
return transformAsync("", {
|
||||
presets: [__dirname + "/../../babel-preset-es2015"],
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx"],
|
||||
}).then(function (result) {
|
||||
assert.ok(result.options.plugins[0][0].manipulateOptions.toString().indexOf("jsx") >= 0);
|
||||
}).then(function(result) {
|
||||
assert.ok(
|
||||
result.options.plugins[0][0].manipulateOptions
|
||||
.toString()
|
||||
.indexOf("jsx") >= 0,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("option wrapPluginVisitorMethod", function () {
|
||||
it("option wrapPluginVisitorMethod", function() {
|
||||
let calledRaw = 0;
|
||||
let calledIntercept = 0;
|
||||
|
||||
babel.transform("function foo() { bar(foobar); }", {
|
||||
wrapPluginVisitorMethod: function (pluginAlias, visitorType, callback) {
|
||||
wrapPluginVisitorMethod: function(pluginAlias, visitorType, callback) {
|
||||
if (pluginAlias !== "foobar") {
|
||||
return callback;
|
||||
}
|
||||
|
||||
assert.equal(visitorType, "enter");
|
||||
|
||||
return function () {
|
||||
return function() {
|
||||
calledIntercept++;
|
||||
return callback.apply(this, arguments);
|
||||
};
|
||||
},
|
||||
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
name: "foobar",
|
||||
visitor: {
|
||||
"Program|Identifier": function () {
|
||||
"Program|Identifier": function() {
|
||||
calledRaw++;
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
assert.equal(calledRaw, 4);
|
||||
assert.equal(calledIntercept, 4);
|
||||
});
|
||||
|
||||
it("pass per preset", function () {
|
||||
it("pass per preset", function() {
|
||||
let aliasBaseType = null;
|
||||
|
||||
function execTest(passPerPreset) {
|
||||
@ -201,13 +236,15 @@ describe("api", function () {
|
||||
passPerPreset: passPerPreset,
|
||||
presets: [
|
||||
// First preset with our plugin, "before"
|
||||
function () {
|
||||
function() {
|
||||
return {
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
Function: function (path) {
|
||||
const alias = path.scope.getProgramParent().path.get("body")[0].node;
|
||||
Function: function(path) {
|
||||
const alias = path.scope
|
||||
.getProgramParent()
|
||||
.path.get("body")[0].node;
|
||||
if (!babel.types.isTypeAlias(alias)) return;
|
||||
|
||||
// In case of `passPerPreset` being `false`, the
|
||||
@ -230,11 +267,12 @@ describe("api", function () {
|
||||
require(__dirname + "/../../babel-preset-es2015"),
|
||||
|
||||
// Third preset for Flow.
|
||||
function () {
|
||||
function() {
|
||||
return {
|
||||
plugins: [
|
||||
require(__dirname + "/../../babel-plugin-syntax-flow"),
|
||||
require(__dirname + "/../../babel-plugin-transform-flow-strip-types"),
|
||||
require(__dirname +
|
||||
"/../../babel-plugin-transform-flow-strip-types"),
|
||||
],
|
||||
};
|
||||
},
|
||||
@ -248,13 +286,16 @@ describe("api", function () {
|
||||
|
||||
assert.equal(aliasBaseType, "NumberTypeAnnotation");
|
||||
|
||||
assert.deepEqual([
|
||||
"\"use strict\";",
|
||||
assert.deepEqual(
|
||||
[
|
||||
'"use strict";',
|
||||
"",
|
||||
"var x = function x(y) {",
|
||||
" return y;",
|
||||
"};",
|
||||
].join("\n"), result.code);
|
||||
].join("\n"),
|
||||
result.code,
|
||||
);
|
||||
|
||||
// 2. passPerPreset: false
|
||||
|
||||
@ -264,14 +305,16 @@ describe("api", function () {
|
||||
|
||||
assert.equal(aliasBaseType, null);
|
||||
|
||||
assert.deepEqual([
|
||||
"\"use strict\";",
|
||||
assert.deepEqual(
|
||||
[
|
||||
'"use strict";',
|
||||
"",
|
||||
"var x = function x(y) {",
|
||||
" return y;",
|
||||
"};",
|
||||
].join("\n"), result.code);
|
||||
|
||||
].join("\n"),
|
||||
result.code,
|
||||
);
|
||||
});
|
||||
|
||||
it("complex plugin and preset ordering", function() {
|
||||
@ -279,7 +322,10 @@ describe("api", function () {
|
||||
return {
|
||||
visitor: {
|
||||
Program(path) {
|
||||
path.pushContainer("body", babel.types.expressionStatement(babel.types.identifier(str)));
|
||||
path.pushContainer(
|
||||
"body",
|
||||
babel.types.expressionStatement(babel.types.identifier(str)),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -290,32 +336,31 @@ describe("api", function () {
|
||||
}
|
||||
|
||||
const result = babel.transform("", {
|
||||
filename: path.join(__dirname, "fixtures", "config", "complex-plugin-config", "file.js"),
|
||||
presets: [
|
||||
pushPreset("argone"),
|
||||
pushPreset("argtwo"),
|
||||
],
|
||||
filename: path.join(
|
||||
__dirname,
|
||||
"fixtures",
|
||||
"config",
|
||||
"complex-plugin-config",
|
||||
"file.js",
|
||||
),
|
||||
presets: [pushPreset("argone"), pushPreset("argtwo")],
|
||||
env: {
|
||||
development: {
|
||||
passPerPreset: true,
|
||||
presets: [
|
||||
pushPreset("argthree"),
|
||||
pushPreset("argfour"),
|
||||
],
|
||||
presets: [pushPreset("argthree"), pushPreset("argfour")],
|
||||
env: {
|
||||
development: {
|
||||
passPerPreset: true,
|
||||
presets: [
|
||||
pushPreset("argfive"),
|
||||
pushPreset("argsix"),
|
||||
],
|
||||
presets: [pushPreset("argfive"), pushPreset("argsix")],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(result.code, [
|
||||
assert.equal(
|
||||
result.code,
|
||||
[
|
||||
"argtwo;",
|
||||
"argone;",
|
||||
"eleven;",
|
||||
@ -342,13 +387,15 @@ describe("api", function () {
|
||||
"eight;",
|
||||
"nine;",
|
||||
"ten;",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("source map merging", function () {
|
||||
const result = babel.transform([
|
||||
it("source map merging", function() {
|
||||
const result = babel.transform(
|
||||
[
|
||||
/* eslint-disable max-len */
|
||||
"function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }",
|
||||
'function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }',
|
||||
"",
|
||||
"let Foo = function Foo() {",
|
||||
" _classCallCheck(this, Foo);",
|
||||
@ -356,222 +403,278 @@ describe("api", function () {
|
||||
"",
|
||||
"//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZG91dCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztJQUFNLEdBQUcsWUFBSCxHQUFHO3dCQUFILEdBQUciLCJmaWxlIjoidW5kZWZpbmVkIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRm9vIHt9XG4iXX0=",
|
||||
/* eslint-enable max-len */
|
||||
].join("\n"), {
|
||||
].join("\n"),
|
||||
{
|
||||
sourceMap: true,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
assert.deepEqual([
|
||||
assert.deepEqual(
|
||||
[
|
||||
"function _classCallCheck(instance, Constructor) {",
|
||||
" if (!(instance instanceof Constructor)) {",
|
||||
" throw new TypeError(\"Cannot call a class as a function\");",
|
||||
' throw new TypeError("Cannot call a class as a function");',
|
||||
" }",
|
||||
"}",
|
||||
"",
|
||||
"let Foo = function Foo() {",
|
||||
" _classCallCheck(this, Foo);",
|
||||
"};",
|
||||
].join("\n"), result.code);
|
||||
].join("\n"),
|
||||
result.code,
|
||||
);
|
||||
|
||||
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
|
||||
assert.deepEqual(consumer.originalPositionFor({
|
||||
assert.deepEqual(
|
||||
consumer.originalPositionFor({
|
||||
line: 7,
|
||||
column: 4,
|
||||
}), {
|
||||
}),
|
||||
{
|
||||
name: null,
|
||||
source: "stdout",
|
||||
line: 1,
|
||||
column: 6,
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("code option false", function () {
|
||||
return transformAsync("foo('bar');", { code: false }).then(function (result) {
|
||||
it("code option false", function() {
|
||||
return transformAsync("foo('bar');", { code: false }).then(function(
|
||||
result,
|
||||
) {
|
||||
assert.ok(!result.code);
|
||||
});
|
||||
});
|
||||
|
||||
it("ast option false", function () {
|
||||
return transformAsync("foo('bar');", { ast: false }).then(function (result) {
|
||||
it("ast option false", function() {
|
||||
return transformAsync("foo('bar');", { ast: false }).then(function(result) {
|
||||
assert.ok(!result.ast);
|
||||
});
|
||||
});
|
||||
|
||||
it("auxiliaryComment option", function () {
|
||||
it("auxiliaryComment option", function() {
|
||||
return transformAsync("class Foo {}", {
|
||||
auxiliaryCommentBefore: "before",
|
||||
auxiliaryCommentAfter: "after",
|
||||
plugins: [function (babel) {
|
||||
plugins: [
|
||||
function(babel) {
|
||||
const t = babel.types;
|
||||
return {
|
||||
visitor: {
|
||||
Program: function (path) {
|
||||
path.unshiftContainer("body", t.expressionStatement(t.identifier("start")));
|
||||
path.pushContainer("body", t.expressionStatement(t.identifier("end")));
|
||||
Program: function(path) {
|
||||
path.unshiftContainer(
|
||||
"body",
|
||||
t.expressionStatement(t.identifier("start")),
|
||||
);
|
||||
path.pushContainer(
|
||||
"body",
|
||||
t.expressionStatement(t.identifier("end")),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
}],
|
||||
}).then(function (result) {
|
||||
assert.equal(result.code,
|
||||
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/");
|
||||
},
|
||||
],
|
||||
}).then(function(result) {
|
||||
assert.equal(
|
||||
result.code,
|
||||
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("modules metadata", function () {
|
||||
it("modules metadata", function() {
|
||||
return Promise.all([
|
||||
// eslint-disable-next-line max-len
|
||||
transformAsync("import { externalName as localName } from \"external\";").then(function (result) {
|
||||
transformAsync(
|
||||
'import { externalName as localName } from "external";',
|
||||
).then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||
source: "external",
|
||||
imported: ["externalName"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "named",
|
||||
imported: "externalName",
|
||||
local: "localName",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("import * as localName2 from \"external\";").then(function (result) {
|
||||
transformAsync('import * as localName2 from "external";').then(function(
|
||||
result,
|
||||
) {
|
||||
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||
source: "external",
|
||||
imported: ["*"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "namespace",
|
||||
local: "localName2",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("import localName3 from \"external\";").then(function (result) {
|
||||
transformAsync('import localName3 from "external";').then(function(
|
||||
result,
|
||||
) {
|
||||
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||
source: "external",
|
||||
imported: ["default"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "named",
|
||||
imported: "default",
|
||||
local: "localName3",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("import localName from \"./array\";", {
|
||||
transformAsync('import localName from "./array";', {
|
||||
resolveModuleSource: function() {
|
||||
return "override-source";
|
||||
},
|
||||
}).then(function (result) {
|
||||
}).then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.imports, [
|
||||
{
|
||||
source: "override-source",
|
||||
imported: ["default"],
|
||||
specifiers: [
|
||||
{
|
||||
"kind": "named",
|
||||
"imported": "default",
|
||||
"local": "localName",
|
||||
kind: "named",
|
||||
imported: "default",
|
||||
local: "localName",
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
}),
|
||||
|
||||
transformAsync("export * as externalName1 from \"external\";", {
|
||||
transformAsync('export * as externalName1 from "external";', {
|
||||
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
||||
}).then(function (result) {
|
||||
}).then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["externalName1"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "external-namespace",
|
||||
exported: "externalName1",
|
||||
source: "external",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export externalName2 from \"external\";", {
|
||||
transformAsync('export externalName2 from "external";', {
|
||||
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
||||
}).then(function (result) {
|
||||
}).then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["externalName2"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "external",
|
||||
local: "externalName2",
|
||||
exported: "externalName2",
|
||||
source: "external",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export function namedFunction() {}").then(function (result) {
|
||||
transformAsync("export function namedFunction() {}").then(function(
|
||||
result,
|
||||
) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["namedFunction"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "local",
|
||||
local: "namedFunction",
|
||||
exported: "namedFunction",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export var foo = \"bar\";").then(function (result) {
|
||||
transformAsync('export var foo = "bar";').then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
"exported": ["foo"],
|
||||
specifiers: [{
|
||||
exported: ["foo"],
|
||||
specifiers: [
|
||||
{
|
||||
kind: "local",
|
||||
local: "foo",
|
||||
exported: "foo",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export { localName as externalName3 };").then(function (result) {
|
||||
transformAsync("export { localName as externalName3 };").then(function(
|
||||
result,
|
||||
) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["externalName3"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "local",
|
||||
local: "localName",
|
||||
exported: "externalName3",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export { externalName4 } from \"external\";").then(function (result) {
|
||||
transformAsync('export { externalName4 } from "external";').then(function(
|
||||
result,
|
||||
) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["externalName4"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "external",
|
||||
local: "externalName4",
|
||||
exported: "externalName4",
|
||||
source: "external",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export * from \"external\";").then(function (result) {
|
||||
transformAsync('export * from "external";').then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: [],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "external-all",
|
||||
source: "external",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
|
||||
transformAsync("export default function defaultFunction() {}").then(function (result) {
|
||||
transformAsync(
|
||||
"export default function defaultFunction() {}",
|
||||
).then(function(result) {
|
||||
assert.deepEqual(result.metadata.modules.exports, {
|
||||
exported: ["defaultFunction"],
|
||||
specifiers: [{
|
||||
specifiers: [
|
||||
{
|
||||
kind: "local",
|
||||
local: "defaultFunction",
|
||||
exported: "default",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("ignore option", function () {
|
||||
it("ignore option", function() {
|
||||
return Promise.all([
|
||||
transformAsync("", {
|
||||
ignore: ["/foo"],
|
||||
@ -610,7 +713,7 @@ describe("api", function () {
|
||||
]);
|
||||
});
|
||||
|
||||
it("only option", function () {
|
||||
it("only option", function() {
|
||||
return Promise.all([
|
||||
transformAsync("", {
|
||||
only: ["/foo"],
|
||||
@ -649,23 +752,23 @@ describe("api", function () {
|
||||
]);
|
||||
});
|
||||
|
||||
describe("env option", function () {
|
||||
describe("env option", function() {
|
||||
const oldBabelEnv = process.env.BABEL_ENV;
|
||||
const oldNodeEnv = process.env.NODE_ENV;
|
||||
|
||||
setup(function () {
|
||||
setup(function() {
|
||||
// Tests need to run with the default and specific values for these. They
|
||||
// need to be cleared for each test.
|
||||
delete process.env.BABEL_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
});
|
||||
|
||||
suiteTeardown(function () {
|
||||
suiteTeardown(function() {
|
||||
process.env.BABEL_ENV = oldBabelEnv;
|
||||
process.env.NODE_ENV = oldNodeEnv;
|
||||
});
|
||||
|
||||
it("default", function () {
|
||||
it("default", function() {
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
development: { code: false },
|
||||
@ -675,7 +778,7 @@ describe("api", function () {
|
||||
assert.equal(result.code, undefined);
|
||||
});
|
||||
|
||||
it("BABEL_ENV", function () {
|
||||
it("BABEL_ENV", function() {
|
||||
process.env.BABEL_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
@ -685,7 +788,7 @@ describe("api", function () {
|
||||
assert.equal(result.code, undefined);
|
||||
});
|
||||
|
||||
it("NODE_ENV", function () {
|
||||
it("NODE_ENV", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
const result = babel.transform("foo;", {
|
||||
env: {
|
||||
@ -696,41 +799,43 @@ describe("api", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("resolveModuleSource option", function () {
|
||||
it("resolveModuleSource option", function() {
|
||||
/* eslint-disable max-len */
|
||||
const actual = "import foo from \"foo-import-default\";\nimport \"foo-import-bare\";\nexport { foo } from \"foo-export-named\";";
|
||||
const expected = "import foo from \"resolved/foo-import-default\";\nimport \"resolved/foo-import-bare\";\nexport { foo } from \"resolved/foo-export-named\";";
|
||||
const actual =
|
||||
'import foo from "foo-import-default";\nimport "foo-import-bare";\nexport { foo } from "foo-export-named";';
|
||||
const expected =
|
||||
'import foo from "resolved/foo-import-default";\nimport "resolved/foo-import-bare";\nexport { foo } from "resolved/foo-export-named";';
|
||||
/* eslint-enable max-len */
|
||||
|
||||
return transformAsync(actual, {
|
||||
resolveModuleSource: function (originalSource) {
|
||||
resolveModuleSource: function(originalSource) {
|
||||
return "resolved/" + originalSource;
|
||||
},
|
||||
}).then(function (result) {
|
||||
}).then(function(result) {
|
||||
assert.equal(result.code.trim(), expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildExternalHelpers", function () {
|
||||
it("all", function () {
|
||||
describe("buildExternalHelpers", function() {
|
||||
it("all", function() {
|
||||
const script = buildExternalHelpers();
|
||||
assert.ok(script.indexOf("classCallCheck") >= -1);
|
||||
assert.ok(script.indexOf("inherits") >= 0);
|
||||
});
|
||||
|
||||
it("whitelist", function () {
|
||||
it("whitelist", function() {
|
||||
const script = buildExternalHelpers(["inherits"]);
|
||||
assert.ok(script.indexOf("classCallCheck") === -1);
|
||||
assert.ok(script.indexOf("inherits") >= 0);
|
||||
});
|
||||
|
||||
it("empty whitelist", function () {
|
||||
it("empty whitelist", function() {
|
||||
const script = buildExternalHelpers([]);
|
||||
assert.ok(script.indexOf("classCallCheck") === -1);
|
||||
assert.ok(script.indexOf("inherits") === -1);
|
||||
});
|
||||
|
||||
it("underscored", function () {
|
||||
it("underscored", function() {
|
||||
const script = buildExternalHelpers(["typeof"]);
|
||||
assert.ok(script.indexOf("typeof") >= 0);
|
||||
});
|
||||
|
||||
@ -5,7 +5,9 @@ import vm from "vm";
|
||||
|
||||
describe("browserify", function() {
|
||||
it("babel/register may be used without breaking browserify", function(done) {
|
||||
const bundler = browserify(path.join(__dirname, "fixtures/browserify/register.js"));
|
||||
const bundler = browserify(
|
||||
path.join(__dirname, "fixtures/browserify/register.js"),
|
||||
);
|
||||
|
||||
bundler.bundle(function(err, bundle) {
|
||||
if (err) return done(err);
|
||||
|
||||
@ -27,7 +27,6 @@ describe("caching API", () => {
|
||||
return { arg, count: count++ };
|
||||
});
|
||||
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", count: 0 });
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
@ -210,48 +209,97 @@ describe("caching API", () => {
|
||||
return { arg, val, val2, count: count++ };
|
||||
});
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", val: "default", val2: "another", count: 0 });
|
||||
assert.deepEqual(fn("one"), {
|
||||
arg: "one",
|
||||
val: "default",
|
||||
val2: "another",
|
||||
count: 0,
|
||||
});
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
assert.deepEqual(fn("two"), { arg: "two", val: "default", val2: "another", count: 1 });
|
||||
assert.deepEqual(fn("two"), {
|
||||
arg: "two",
|
||||
val: "default",
|
||||
val2: "another",
|
||||
count: 1,
|
||||
});
|
||||
assert.equal(fn("two"), fn("two"));
|
||||
|
||||
other = "new";
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", val: "new", val2: "another", count: 2 });
|
||||
assert.deepEqual(fn("one"), {
|
||||
arg: "one",
|
||||
val: "new",
|
||||
val2: "another",
|
||||
count: 2,
|
||||
});
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
assert.deepEqual(fn("two"), { arg: "two", val: "new", val2: "another", count: 3 });
|
||||
assert.deepEqual(fn("two"), {
|
||||
arg: "two",
|
||||
val: "new",
|
||||
val2: "another",
|
||||
count: 3,
|
||||
});
|
||||
assert.equal(fn("two"), fn("two"));
|
||||
|
||||
other = "default";
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", val: "default", val2: "another", count: 4 });
|
||||
assert.deepEqual(fn("one"), {
|
||||
arg: "one",
|
||||
val: "default",
|
||||
val2: "another",
|
||||
count: 4,
|
||||
});
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
assert.deepEqual(fn("two"), { arg: "two", val: "default", val2: "another", count: 5 });
|
||||
assert.deepEqual(fn("two"), {
|
||||
arg: "two",
|
||||
val: "default",
|
||||
val2: "another",
|
||||
count: 5,
|
||||
});
|
||||
assert.equal(fn("two"), fn("two"));
|
||||
|
||||
other = "new";
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", val: "new", val2: "another", count: 6 });
|
||||
assert.deepEqual(fn("one"), {
|
||||
arg: "one",
|
||||
val: "new",
|
||||
val2: "another",
|
||||
count: 6,
|
||||
});
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
assert.deepEqual(fn("two"), { arg: "two", val: "new", val2: "another", count: 7 });
|
||||
assert.deepEqual(fn("two"), {
|
||||
arg: "two",
|
||||
val: "new",
|
||||
val2: "another",
|
||||
count: 7,
|
||||
});
|
||||
assert.equal(fn("two"), fn("two"));
|
||||
|
||||
another = "second";
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", val: "new", val2: "second", count: 8 });
|
||||
assert.deepEqual(fn("one"), {
|
||||
arg: "one",
|
||||
val: "new",
|
||||
val2: "second",
|
||||
count: 8,
|
||||
});
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
|
||||
assert.deepEqual(fn("two"), { arg: "two", val: "new", val2: "second", count: 9 });
|
||||
assert.deepEqual(fn("two"), {
|
||||
arg: "two",
|
||||
val: "new",
|
||||
val2: "second",
|
||||
count: 9,
|
||||
});
|
||||
assert.equal(fn("two"), fn("two"));
|
||||
|
||||
});
|
||||
|
||||
it("should throw if caching is never configured and not defaulting", () => {
|
||||
const fn = makeStrongCache(() => { }, false /* autoPermacache */);
|
||||
const fn = makeStrongCache(() => {}, false /* autoPermacache */);
|
||||
|
||||
assert.throws(() => fn(), /Error: Caching was left unconfigured./);
|
||||
});
|
||||
@ -259,7 +307,7 @@ describe("caching API", () => {
|
||||
it("should auto-permacache by default", () => {
|
||||
let count = 0;
|
||||
|
||||
const fn = makeStrongCache((arg) => ({ arg, count: count++ }));
|
||||
const fn = makeStrongCache(arg => ({ arg, count: count++ }));
|
||||
|
||||
assert.deepEqual(fn("one"), { arg: "one", count: 0 });
|
||||
assert.equal(fn("one"), fn("one"));
|
||||
@ -333,7 +381,10 @@ describe("caching API", () => {
|
||||
it("should throw if you configure .forever after exiting", () => {
|
||||
const fn = makeStrongCache((arg, cache) => cache);
|
||||
|
||||
assert.throws(() => fn().forever(), /Cannot change caching after evaluation/);
|
||||
assert.throws(
|
||||
() => fn().forever(),
|
||||
/Cannot change caching after evaluation/,
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw if you configure .never after exiting", () => {
|
||||
@ -345,12 +396,18 @@ describe("caching API", () => {
|
||||
it("should throw if you configure .using after exiting", () => {
|
||||
const fn = makeStrongCache((arg, cache) => cache);
|
||||
|
||||
assert.throws(() => fn().using(() => null), /Cannot change caching after evaluation/);
|
||||
assert.throws(
|
||||
() => fn().using(() => null),
|
||||
/Cannot change caching after evaluation/,
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw if you configure .invalidate after exiting", () => {
|
||||
const fn = makeStrongCache((arg, cache) => cache);
|
||||
|
||||
assert.throws(() => fn().invalidate(() => null), /Cannot change caching after evaluation/);
|
||||
assert.throws(
|
||||
() => fn().invalidate(() => null),
|
||||
/Cannot change caching after evaluation/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -4,7 +4,7 @@ import buildConfigChain from "../lib/config/build-config-chain";
|
||||
|
||||
function fixture() {
|
||||
const args = [__dirname, "fixtures", "config"];
|
||||
for (let i = 0; i < arguments.length; i ++) {
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
return path.join.apply(path, args);
|
||||
@ -14,11 +14,11 @@ function base() {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
describe("buildConfigChain", function () {
|
||||
describe("buildConfigChain", function() {
|
||||
let oldBabelEnv;
|
||||
let oldNodeEnv;
|
||||
|
||||
beforeEach(function () {
|
||||
beforeEach(function() {
|
||||
oldBabelEnv = process.env.BABEL_ENV;
|
||||
oldNodeEnv = process.env.NODE_ENV;
|
||||
|
||||
@ -26,7 +26,7 @@ describe("buildConfigChain", function () {
|
||||
delete process.env.NODE_ENV;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
afterEach(function() {
|
||||
process.env.BABEL_ENV = oldBabelEnv;
|
||||
process.env.NODE_ENV = oldNodeEnv;
|
||||
});
|
||||
@ -52,7 +52,7 @@ describe("buildConfigChain", function () {
|
||||
});
|
||||
});
|
||||
|
||||
it("dir1", function () {
|
||||
it("dir1", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir1", "src.js"),
|
||||
});
|
||||
@ -61,9 +61,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"extended",
|
||||
],
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
@ -72,9 +70,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"root",
|
||||
],
|
||||
plugins: ["root"],
|
||||
},
|
||||
alias: fixture(".babelrc"),
|
||||
loc: fixture(".babelrc"),
|
||||
@ -83,9 +79,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -105,7 +99,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("dir2", function () {
|
||||
it("dir2", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir2", "src.js"),
|
||||
});
|
||||
@ -114,9 +108,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -125,9 +117,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"dir2",
|
||||
],
|
||||
plugins: ["dir2"],
|
||||
},
|
||||
alias: fixture("dir2", ".babelrc"),
|
||||
loc: fixture("dir2", ".babelrc"),
|
||||
@ -147,7 +137,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("dir3", function () {
|
||||
it("dir3", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("dir3", "src.js"),
|
||||
});
|
||||
@ -156,9 +146,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"extended",
|
||||
],
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
@ -167,9 +155,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"root",
|
||||
],
|
||||
plugins: ["root"],
|
||||
},
|
||||
alias: fixture(".babelrc"),
|
||||
loc: fixture(".babelrc"),
|
||||
@ -178,9 +164,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -200,7 +184,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("env - base", function () {
|
||||
it("env - base", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("env", "src.js"),
|
||||
});
|
||||
@ -209,9 +193,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -220,9 +202,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"env-base",
|
||||
],
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
@ -242,7 +222,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("env - foo", function () {
|
||||
it("env - foo", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
|
||||
const chain = buildConfigChain({
|
||||
@ -253,9 +233,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -264,9 +242,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"env-base",
|
||||
],
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
@ -275,9 +251,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"env-foo",
|
||||
],
|
||||
plugins: ["env-foo"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc.env.foo"),
|
||||
loc: fixture("env", ".babelrc.env.foo"),
|
||||
@ -297,7 +271,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("env - bar", function () {
|
||||
it("env - bar", function() {
|
||||
process.env.NODE_ENV = "foo"; // overridden
|
||||
process.env.NODE_ENV = "bar";
|
||||
|
||||
@ -309,9 +283,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -320,9 +292,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"env-base",
|
||||
],
|
||||
plugins: ["env-base"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc"),
|
||||
loc: fixture("env", ".babelrc"),
|
||||
@ -331,9 +301,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"env-bar",
|
||||
],
|
||||
plugins: ["env-bar"],
|
||||
},
|
||||
alias: fixture("env", ".babelrc.env.bar"),
|
||||
loc: fixture("env", ".babelrc.env.bar"),
|
||||
@ -353,8 +321,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
|
||||
it("env - foo", function () {
|
||||
it("env - foo", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
|
||||
const chain = buildConfigChain({
|
||||
@ -394,7 +361,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-config", function () {
|
||||
it("js-config", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config", "src.js"),
|
||||
});
|
||||
@ -403,9 +370,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -414,10 +379,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config", ".babelrc.js"),
|
||||
loc: fixture("js-config", ".babelrc.js"),
|
||||
@ -437,7 +399,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-config-function", function () {
|
||||
it("js-config-function", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-function", "src.js"),
|
||||
});
|
||||
@ -446,9 +408,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -477,7 +437,7 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-config-default - should read transpiled export default", function () {
|
||||
it("js-config-default - should read transpiled export default", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
});
|
||||
@ -486,9 +446,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -497,10 +455,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config-default", ".babelrc.js"),
|
||||
loc: fixture("js-config-default", ".babelrc.js"),
|
||||
@ -519,7 +474,7 @@ describe("buildConfigChain", function () {
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
it("js-config-extended", function () {
|
||||
it("js-config-extended", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
});
|
||||
@ -528,9 +483,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -539,9 +492,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"extended",
|
||||
],
|
||||
plugins: ["extended"],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
@ -550,10 +501,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
plugins: ["foo", "bar"],
|
||||
},
|
||||
alias: fixture("js-config-extended", ".babelrc.js"),
|
||||
loc: fixture("js-config-extended", ".babelrc.js"),
|
||||
@ -573,8 +521,10 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("json-pkg-config-no-babel - should not throw if" +
|
||||
" package.json doesn't contain a `babel` field", function () {
|
||||
it(
|
||||
"json-pkg-config-no-babel - should not throw if" +
|
||||
" package.json doesn't contain a `babel` field",
|
||||
function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
});
|
||||
@ -583,9 +533,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -594,9 +542,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
plugins: [
|
||||
"json",
|
||||
],
|
||||
plugins: ["json"],
|
||||
},
|
||||
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
loc: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
@ -614,9 +560,10 @@ describe("buildConfigChain", function () {
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("should not ignore file matching negated file pattern", function () {
|
||||
it("should not ignore file matching negated file pattern", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("ignore-negate", "src.js"),
|
||||
});
|
||||
@ -625,9 +572,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -636,10 +581,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"*",
|
||||
"!src.js",
|
||||
],
|
||||
ignore: ["*", "!src.js"],
|
||||
},
|
||||
alias: fixture("ignore-negate", ".babelrc"),
|
||||
loc: fixture("ignore-negate", ".babelrc"),
|
||||
@ -665,7 +607,7 @@ describe("buildConfigChain", function () {
|
||||
assert.equal(chain2, null);
|
||||
});
|
||||
|
||||
it("should not ignore file matching negated folder pattern", function () {
|
||||
it("should not ignore file matching negated folder pattern", function() {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("ignore-negate-folder", "folder", "src.js"),
|
||||
});
|
||||
@ -674,9 +616,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -685,10 +625,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"*",
|
||||
"!folder",
|
||||
],
|
||||
ignore: ["*", "!folder"],
|
||||
},
|
||||
alias: fixture("ignore-negate-folder", ".babelrc"),
|
||||
loc: fixture("ignore-negate-folder", ".babelrc"),
|
||||
@ -714,83 +651,71 @@ describe("buildConfigChain", function () {
|
||||
assert.equal(chain2, null);
|
||||
});
|
||||
|
||||
it("js-json-config - should throw an error if both a .babelrc" +
|
||||
" and a .babelrc.js are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it(
|
||||
"js-json-config - should throw an error if both a .babelrc" +
|
||||
" and a .babelrc.js are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-json-config", "src.js"),
|
||||
});
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*\.babelrc\.js/);
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*\.babelrc\.js/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-pkg-config - should throw an error if both a .babelrc.js" +
|
||||
" and a package.json with a babel field are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it(
|
||||
"js-pkg-config - should throw an error if both a .babelrc.js" +
|
||||
" and a package.json with a babel field are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-pkg-config", "src.js"),
|
||||
});
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc\.js(.|\n)*package\.json/);
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc\.js(.|\n)*package\.json/
|
||||
);
|
||||
});
|
||||
|
||||
it("json-pkg-config - should throw an error if both a .babelrc" +
|
||||
" and a package.json with a babel field are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it(
|
||||
"json-pkg-config - should throw an error if both a .babelrc" +
|
||||
" and a package.json with a babel field are present",
|
||||
function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-pkg-config", "src.js"),
|
||||
});
|
||||
}, /Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*package\.json/);
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*package\.json/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-config-error", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it("js-config-error", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while loading config/
|
||||
);
|
||||
}, /Error while loading config/);
|
||||
});
|
||||
|
||||
it("js-config-error2", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it("js-config-error2", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error2", "src.js"),
|
||||
});
|
||||
},
|
||||
/Configuration should be an exported JavaScript object/
|
||||
);
|
||||
}, /Configuration should be an exported JavaScript object/);
|
||||
});
|
||||
|
||||
it("js-config-error3", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it("js-config-error3", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error3", "src.js"),
|
||||
});
|
||||
},
|
||||
/Configuration should be an exported JavaScript object/
|
||||
);
|
||||
}, /Configuration should be an exported JavaScript object/);
|
||||
});
|
||||
|
||||
it("json-config-error", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
it("json-config-error", function() {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while parsing config/
|
||||
);
|
||||
}, /Error while parsing config/);
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,20 +2,23 @@ import traverse from "babel-traverse";
|
||||
import assert from "assert";
|
||||
import { parse } from "babylon";
|
||||
|
||||
describe("evaluation", function () {
|
||||
describe("evaluation", function() {
|
||||
function addTest(code, type, value, notConfident) {
|
||||
it(type + ": " + code, function () {
|
||||
it(type + ": " + code, function() {
|
||||
const visitor = {};
|
||||
|
||||
visitor[type] = function (path) {
|
||||
visitor[type] = function(path) {
|
||||
const evaluate = path.evaluate();
|
||||
assert.equal(evaluate.confident, !notConfident);
|
||||
assert.deepEqual(evaluate.value, value);
|
||||
};
|
||||
|
||||
traverse(parse(code, {
|
||||
traverse(
|
||||
parse(code, {
|
||||
plugins: ["*"],
|
||||
}), visitor);
|
||||
}),
|
||||
visitor,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -56,14 +59,39 @@ describe("evaluation", function () {
|
||||
addTest("'abc' === 'xyz' || 1 === 1", "LogicalExpression", true);
|
||||
addTest("'abc' === 'xyz' || 1 === 10", "LogicalExpression", false);
|
||||
addTest("'abc' === 'abc' || config.flag === 1", "LogicalExpression", true);
|
||||
addTest("obj.a === 'abc' || config.flag === 1", "LogicalExpression", undefined, true);
|
||||
addTest(
|
||||
"obj.a === 'abc' || config.flag === 1",
|
||||
"LogicalExpression",
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
addTest("'abc' !== 'abc' && config.flag === 1", "LogicalExpression", false);
|
||||
addTest("obj.a === 'abc' && 1 === 1", "LogicalExpression", undefined, true);
|
||||
addTest("'abc' === 'abc' && (1 === 1 || config.flag)", "LogicalExpression", true);
|
||||
addTest("'abc' === 'xyz' || (1 === 1 && config.flag)", "LogicalExpression", undefined, true);
|
||||
addTest("'abc' === 'xyz' || (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
|
||||
addTest("'abc' === 'abc' && (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
|
||||
addTest(
|
||||
"'abc' === 'abc' && (1 === 1 || config.flag)",
|
||||
"LogicalExpression",
|
||||
true,
|
||||
);
|
||||
addTest(
|
||||
"'abc' === 'xyz' || (1 === 1 && config.flag)",
|
||||
"LogicalExpression",
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
addTest(
|
||||
"'abc' === 'xyz' || (1 === 1 && 'four' === 'four')",
|
||||
"LogicalExpression",
|
||||
true,
|
||||
);
|
||||
addTest(
|
||||
"'abc' === 'abc' && (1 === 1 && 'four' === 'four')",
|
||||
"LogicalExpression",
|
||||
true,
|
||||
);
|
||||
addTest("({})", "ObjectExpression", {});
|
||||
addTest("({a: '1'})", "ObjectExpression", { a: "1" });
|
||||
addTest("({['a' + 'b']: 10 * 20, 'z': [1, 2, 3]})", "ObjectExpression", { ab: 200, z: [1, 2, 3] });
|
||||
addTest("({['a' + 'b']: 10 * 20, 'z': [1, 2, 3]})", "ObjectExpression", {
|
||||
ab: 200,
|
||||
z: [1, 2, 3],
|
||||
});
|
||||
});
|
||||
|
||||
@ -6,55 +6,51 @@ describe("option-manager", () => {
|
||||
it("throws for babel 5 plugin", () => {
|
||||
return assert.throws(() => {
|
||||
manageOptions({
|
||||
plugins: [
|
||||
({ Plugin }) => new Plugin("object-assign", {}),
|
||||
],
|
||||
plugins: [({ Plugin }) => new Plugin("object-assign", {})],
|
||||
});
|
||||
}, /Babel 5 plugin is being run with Babel 6/);
|
||||
});
|
||||
|
||||
describe("mergeOptions", () => {
|
||||
it("throws for removed babel 5 options", () => {
|
||||
return assert.throws(
|
||||
() => {
|
||||
return assert.throws(() => {
|
||||
manageOptions({
|
||||
"randomOption": true,
|
||||
randomOption: true,
|
||||
});
|
||||
},
|
||||
/Unknown option: base.randomOption/
|
||||
);
|
||||
}, /Unknown option: base.randomOption/);
|
||||
});
|
||||
|
||||
it("throws for removed babel 5 options", () => {
|
||||
return assert.throws(
|
||||
() => {
|
||||
manageOptions({
|
||||
"auxiliaryComment": true,
|
||||
"blacklist": true,
|
||||
auxiliaryComment: true,
|
||||
blacklist: true,
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line max-len
|
||||
/Using removed Babel 5 option: base.auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/
|
||||
/Using removed Babel 5 option: base.auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/,
|
||||
);
|
||||
});
|
||||
|
||||
it("throws for resolved but erroring preset", () => {
|
||||
return assert.throws(
|
||||
() => {
|
||||
return assert.throws(() => {
|
||||
manageOptions({
|
||||
"presets": [path.join(__dirname, "fixtures/option-manager/not-a-preset")],
|
||||
presets: [
|
||||
path.join(__dirname, "fixtures/option-manager/not-a-preset"),
|
||||
],
|
||||
});
|
||||
},
|
||||
/While processing: .*option-manager(?:\/|\\\\)not-a-preset\.js/
|
||||
);
|
||||
}, /While processing: .*option-manager(?:\/|\\\\)not-a-preset\.js/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("presets", function () {
|
||||
describe("presets", function() {
|
||||
function presetTest(name) {
|
||||
it(name, function () {
|
||||
it(name, function() {
|
||||
const { options, passes } = manageOptions({
|
||||
"presets": [path.join(__dirname, "fixtures/option-manager/presets", name)],
|
||||
presets: [
|
||||
path.join(__dirname, "fixtures/option-manager/presets", name),
|
||||
],
|
||||
});
|
||||
|
||||
assert.equal(true, Array.isArray(options.plugins));
|
||||
@ -65,10 +61,16 @@ describe("option-manager", () => {
|
||||
}
|
||||
|
||||
function presetThrowsTest(name, msg) {
|
||||
it(name, function () {
|
||||
assert.throws(() => manageOptions({
|
||||
"presets": [path.join(__dirname, "fixtures/option-manager/presets", name)],
|
||||
}), msg);
|
||||
it(name, function() {
|
||||
assert.throws(
|
||||
() =>
|
||||
manageOptions({
|
||||
presets: [
|
||||
path.join(__dirname, "fixtures/option-manager/presets", name),
|
||||
],
|
||||
}),
|
||||
msg,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -77,7 +79,10 @@ describe("option-manager", () => {
|
||||
presetTest("es2015_default_function");
|
||||
presetTest("es2015_default_object");
|
||||
|
||||
presetThrowsTest("es2015_named", /Must export a default export when using ES6 modules/);
|
||||
presetThrowsTest(
|
||||
"es2015_named",
|
||||
/Must export a default export when using ES6 modules/,
|
||||
);
|
||||
presetThrowsTest("es2015_invalid", /Unsupported format: string/);
|
||||
presetThrowsTest("es5_invalid", /Unsupported format: string/);
|
||||
});
|
||||
|
||||
@ -2,152 +2,172 @@ import { transform } from "../lib/index";
|
||||
import Plugin from "../lib/config/plugin";
|
||||
import chai from "chai";
|
||||
|
||||
describe("traversal path", function () {
|
||||
it("replaceWithSourceString", function () {
|
||||
describe("traversal path", function() {
|
||||
it("replaceWithSourceString", function() {
|
||||
const expectCode = "function foo() {}";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
FunctionDeclaration: function (path) {
|
||||
FunctionDeclaration: function(path) {
|
||||
path.replaceWithSourceString("console.whatever()");
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("console.whatever();");
|
||||
});
|
||||
|
||||
it("replaceWith (arrow expression body to block statement body)", function () {
|
||||
it("replaceWith (arrow expression body to block statement body)", function() {
|
||||
const expectCode = "var fn = () => true;";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ArrowFunctionExpression: function (path) {
|
||||
ArrowFunctionExpression: function(path) {
|
||||
path.get("body").replaceWith({
|
||||
type: "BlockStatement",
|
||||
body: [{
|
||||
body: [
|
||||
{
|
||||
type: "ReturnStatement",
|
||||
argument: {
|
||||
type: "BooleanLiteral",
|
||||
value: true,
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("var fn = () => {\n return true;\n};");
|
||||
});
|
||||
|
||||
it("replaceWith (arrow block statement body to expression body)", function () {
|
||||
it("replaceWith (arrow block statement body to expression body)", function() {
|
||||
const expectCode = "var fn = () => { return true; }";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ArrowFunctionExpression: function (path) {
|
||||
ArrowFunctionExpression: function(path) {
|
||||
path.get("body").replaceWith({
|
||||
type: "BooleanLiteral",
|
||||
value: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("var fn = () => true;");
|
||||
});
|
||||
|
||||
it("replaceWith (for-in left expression to variable declaration)", function () {
|
||||
it("replaceWith (for-in left expression to variable declaration)", function() {
|
||||
const expectCode = "for (KEY in right);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForInStatement: function (path) {
|
||||
ForInStatement: function(path) {
|
||||
path.get("left").replaceWith({
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
declarations: [{
|
||||
declarations: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
name: "KEY",
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (var KEY in right);");
|
||||
});
|
||||
|
||||
it("replaceWith (for-in left variable declaration to expression)", function () {
|
||||
it("replaceWith (for-in left variable declaration to expression)", function() {
|
||||
const expectCode = "for (var KEY in right);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForInStatement: function (path) {
|
||||
ForInStatement: function(path) {
|
||||
path.get("left").replaceWith({
|
||||
type: "Identifier",
|
||||
name: "KEY",
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (KEY in right);");
|
||||
});
|
||||
|
||||
it("replaceWith (for-loop left expression to variable declaration)", function () {
|
||||
it("replaceWith (for-loop left expression to variable declaration)", function() {
|
||||
const expectCode = "for (KEY;;);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForStatement: function (path) {
|
||||
ForStatement: function(path) {
|
||||
path.get("init").replaceWith({
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
declarations: [{
|
||||
declarations: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
name: "KEY",
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (var KEY;;);");
|
||||
});
|
||||
|
||||
it("replaceWith (for-loop left variable declaration to expression)", function () {
|
||||
it("replaceWith (for-loop left variable declaration to expression)", function() {
|
||||
const expectCode = "for (var KEY;;);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForStatement: function (path) {
|
||||
ForStatement: function(path) {
|
||||
path.get("init").replaceWith({
|
||||
type: "Identifier",
|
||||
name: "KEY",
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (KEY;;);");
|
||||
|
||||
@ -2,7 +2,7 @@ import assert from "assert";
|
||||
import * as babel from "../lib/index";
|
||||
import path from "path";
|
||||
|
||||
describe("addon resolution", function () {
|
||||
describe("addon resolution", function() {
|
||||
const base = path.join(__dirname, "fixtures", "resolution");
|
||||
|
||||
beforeEach(function() {
|
||||
@ -20,9 +20,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"module:preset",
|
||||
],
|
||||
presets: ["module:preset"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -32,9 +30,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"module:plugin",
|
||||
],
|
||||
plugins: ["module:plugin"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -44,9 +40,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"mod",
|
||||
],
|
||||
presets: ["mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -56,9 +50,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"mod",
|
||||
],
|
||||
plugins: ["mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -68,9 +60,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"babel-preset-mod",
|
||||
],
|
||||
presets: ["babel-preset-mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -80,9 +70,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"babel-plugin-mod",
|
||||
],
|
||||
plugins: ["babel-plugin-mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -92,9 +80,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@babel/foo",
|
||||
],
|
||||
presets: ["@babel/foo"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -104,9 +90,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@babel/foo",
|
||||
],
|
||||
plugins: ["@babel/foo"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -116,9 +100,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@babel/preset-foo",
|
||||
],
|
||||
presets: ["@babel/preset-foo"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -128,9 +110,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@babel/plugin-foo",
|
||||
],
|
||||
plugins: ["@babel/plugin-foo"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -140,9 +120,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@foo/mod",
|
||||
],
|
||||
presets: ["@foo/mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -152,9 +130,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@foo/mod",
|
||||
],
|
||||
plugins: ["@foo/mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -164,9 +140,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@foo/babel-preset-mod",
|
||||
],
|
||||
presets: ["@foo/babel-preset-mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -176,9 +150,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@foo/babel-plugin-mod",
|
||||
],
|
||||
plugins: ["@foo/babel-plugin-mod"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -188,9 +160,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"./dir/preset.js",
|
||||
],
|
||||
presets: ["./dir/preset.js"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -200,9 +170,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"./dir/plugin.js",
|
||||
],
|
||||
plugins: ["./dir/plugin.js"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -212,9 +180,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"mod/preset",
|
||||
],
|
||||
presets: ["mod/preset"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -224,9 +190,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"mod/plugin",
|
||||
],
|
||||
plugins: ["mod/plugin"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -236,9 +200,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@foo/mod/preset",
|
||||
],
|
||||
presets: ["@foo/mod/preset"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -248,9 +210,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@foo/mod/plugin",
|
||||
],
|
||||
plugins: ["@foo/mod/plugin"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -260,9 +220,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"@babel/mod/preset",
|
||||
],
|
||||
presets: ["@babel/mod/preset"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -272,9 +230,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"@babel/mod/plugin",
|
||||
],
|
||||
plugins: ["@babel/mod/plugin"],
|
||||
});
|
||||
});
|
||||
|
||||
@ -285,9 +241,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"foo",
|
||||
],
|
||||
presets: ["foo"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-preset-foo'.*\n- If you want to resolve "foo", use "module:foo"/);
|
||||
@ -300,9 +254,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"foo",
|
||||
],
|
||||
plugins: ["foo"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-plugin-foo'.*\n- If you want to resolve "foo", use "module:foo"/);
|
||||
@ -315,9 +267,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"foo",
|
||||
],
|
||||
presets: ["foo"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-preset-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
||||
@ -330,9 +280,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"foo",
|
||||
],
|
||||
plugins: ["foo"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-plugin-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
||||
@ -345,9 +293,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"testplugin",
|
||||
],
|
||||
presets: ["testplugin"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-preset-testplugin'.*\n- Did you accidentally pass a preset as a plugin\?/);
|
||||
@ -360,9 +306,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"testpreset",
|
||||
],
|
||||
plugins: ["testpreset"],
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
}, /Cannot find module 'babel-plugin-testpreset'.*\n- Did you accidentally pass a plugin as a preset\?/);
|
||||
@ -375,9 +319,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
presets: [
|
||||
"foo",
|
||||
],
|
||||
presets: ["foo"],
|
||||
});
|
||||
}, /Cannot find module 'babel-preset-foo'/);
|
||||
});
|
||||
@ -389,9 +331,7 @@ describe("addon resolution", function () {
|
||||
babel.transform("", {
|
||||
filename: "filename.js",
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
"foo",
|
||||
],
|
||||
plugins: ["foo"],
|
||||
});
|
||||
}, /Cannot find module 'babel-plugin-foo'/);
|
||||
});
|
||||
|
||||
@ -54,7 +54,7 @@ export default class Buffer {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
return this.map = map.get();
|
||||
return (this.map = map.get());
|
||||
},
|
||||
set(value) {
|
||||
Object.defineProperty(this, "map", { value, writable: true });
|
||||
@ -81,7 +81,11 @@ export default class Buffer {
|
||||
|
||||
queue(str: string): void {
|
||||
// Drop trailing spaces when a newline is inserted.
|
||||
if (str === "\n") while (this._queue.length > 0 && SPACES_RE.test(this._queue[0][0])) this._queue.shift();
|
||||
if (str === "\n") {
|
||||
while (this._queue.length > 0 && SPACES_RE.test(this._queue[0][0])) {
|
||||
this._queue.shift();
|
||||
}
|
||||
}
|
||||
|
||||
const { line, column, filename, identifierName } = this._sourcePosition;
|
||||
this._queue.unshift([str, line, column, identifierName, filename]);
|
||||
@ -89,13 +93,26 @@ export default class Buffer {
|
||||
|
||||
_flush(): void {
|
||||
let item;
|
||||
while (item = this._queue.pop()) this._append(...item);
|
||||
while ((item = this._queue.pop())) this._append(...item);
|
||||
}
|
||||
|
||||
_append(str: string, line: number, column: number, identifierName: ?string, filename: ?string): void {
|
||||
_append(
|
||||
str: string,
|
||||
line: number,
|
||||
column: number,
|
||||
identifierName: ?string,
|
||||
filename: ?string,
|
||||
): void {
|
||||
// If there the line is ending, adding a new mapping marker is redundant
|
||||
if (this._map && str[0] !== "\n") {
|
||||
this._map.mark(this._position.line, this._position.column, line, column, identifierName, filename);
|
||||
this._map.mark(
|
||||
this._position.line,
|
||||
this._position.column,
|
||||
line,
|
||||
column,
|
||||
identifierName,
|
||||
filename,
|
||||
);
|
||||
}
|
||||
|
||||
this._buf.push(str);
|
||||
@ -112,11 +129,15 @@ export default class Buffer {
|
||||
}
|
||||
|
||||
removeTrailingNewline(): void {
|
||||
if (this._queue.length > 0 && this._queue[0][0] === "\n") this._queue.shift();
|
||||
if (this._queue.length > 0 && this._queue[0][0] === "\n") {
|
||||
this._queue.shift();
|
||||
}
|
||||
}
|
||||
|
||||
removeLastSemicolon(): void {
|
||||
if (this._queue.length > 0 && this._queue[0][0] === ";") this._queue.shift();
|
||||
if (this._queue.length > 0 && this._queue[0][0] === ";") {
|
||||
this._queue.shift();
|
||||
}
|
||||
}
|
||||
|
||||
endsWith(suffix: string): boolean {
|
||||
@ -133,7 +154,8 @@ export default class Buffer {
|
||||
return last === suffix;
|
||||
}
|
||||
|
||||
const end = this._last + this._queue.reduce((acc, item) => item[0] + acc, "");
|
||||
const end =
|
||||
this._last + this._queue.reduce((acc, item) => item[0] + acc, "");
|
||||
if (suffix.length <= end.length) {
|
||||
return end.slice(-suffix.length) === suffix;
|
||||
}
|
||||
@ -157,10 +179,10 @@ export default class Buffer {
|
||||
|
||||
const pos = loc ? loc[prop] : null;
|
||||
|
||||
this._sourcePosition.identifierName = loc && loc.identifierName || null;
|
||||
this._sourcePosition.identifierName = (loc && loc.identifierName) || null;
|
||||
this._sourcePosition.line = pos ? pos.line : null;
|
||||
this._sourcePosition.column = pos ? pos.column : null;
|
||||
this._sourcePosition.filename = loc && loc.filename || null;
|
||||
this._sourcePosition.filename = (loc && loc.filename) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,7 +212,9 @@ export default class Buffer {
|
||||
const extra = this._queue.reduce((acc, item) => item[0] + acc, "");
|
||||
const lastIndex = extra.lastIndexOf("\n");
|
||||
|
||||
return lastIndex === -1 ? this._position.column + extra.length : (extra.length - 1 - lastIndex);
|
||||
return lastIndex === -1
|
||||
? this._position.column + extra.length
|
||||
: extra.length - 1 - lastIndex;
|
||||
}
|
||||
|
||||
getCurrentLine(): number {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import * as t from "babel-types";
|
||||
import * as n from "../node";
|
||||
|
||||
|
||||
export function UnaryExpression(node: Object) {
|
||||
if (node.operator === "void" || node.operator === "delete" || node.operator === "typeof") {
|
||||
if (
|
||||
node.operator === "void" ||
|
||||
node.operator === "delete" ||
|
||||
node.operator === "typeof"
|
||||
) {
|
||||
this.word(node.operator);
|
||||
this.space();
|
||||
} else {
|
||||
@ -51,12 +54,16 @@ export function NewExpression(node: Object, parent: Object) {
|
||||
this.word("new");
|
||||
this.space();
|
||||
this.print(node.callee, node);
|
||||
if (this.format.minified &&
|
||||
if (
|
||||
this.format.minified &&
|
||||
node.arguments.length === 0 &&
|
||||
!node.optional &&
|
||||
!t.isCallExpression(parent, { callee: node }) &&
|
||||
!t.isMemberExpression(parent) &&
|
||||
!t.isNewExpression(parent)) return;
|
||||
!t.isNewExpression(parent)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.optional) {
|
||||
this.token("?.");
|
||||
@ -123,7 +130,7 @@ export function Import() {
|
||||
}
|
||||
|
||||
function buildYieldAwait(keyword: string) {
|
||||
return function (node: Object) {
|
||||
return function(node: Object) {
|
||||
this.word(keyword);
|
||||
|
||||
if (node.delegate) {
|
||||
@ -164,7 +171,9 @@ export function AssignmentPattern(node: Object) {
|
||||
export function AssignmentExpression(node: Object, parent: Object) {
|
||||
// Somewhere inside a for statement `init` node but doesn't usually
|
||||
// needs a paren except for `in` expressions: `for (a in b ? a : b;;)`
|
||||
const parens = this.inForStatementInitCounter && node.operator === "in" &&
|
||||
const parens =
|
||||
this.inForStatementInitCounter &&
|
||||
node.operator === "in" &&
|
||||
!n.needsParens(node, parent);
|
||||
|
||||
if (parens) {
|
||||
|
||||
@ -159,7 +159,10 @@ export function FunctionTypeAnnotation(node: Object, parent: Object) {
|
||||
this.token(")");
|
||||
|
||||
// this node type is overloaded, not sure why but it makes it EXTREMELY annoying
|
||||
if (parent.type === "ObjectTypeCallProperty" || parent.type === "DeclareFunction") {
|
||||
if (
|
||||
parent.type === "ObjectTypeCallProperty" ||
|
||||
parent.type === "DeclareFunction"
|
||||
) {
|
||||
this.token(":");
|
||||
} else {
|
||||
this.space();
|
||||
@ -183,7 +186,10 @@ export function InterfaceExtends(node: Object) {
|
||||
this.print(node.typeParameters, node);
|
||||
}
|
||||
|
||||
export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation };
|
||||
export {
|
||||
InterfaceExtends as ClassImplements,
|
||||
InterfaceExtends as GenericTypeAnnotation,
|
||||
};
|
||||
|
||||
export function _interfaceish(node: Object) {
|
||||
this.print(node.id, node);
|
||||
|
||||
@ -4,7 +4,7 @@ export function _params(node: Object) {
|
||||
this.print(node.typeParameters, node);
|
||||
this.token("(");
|
||||
this.printList(node.params, node, {
|
||||
iterator: (node) => {
|
||||
iterator: node => {
|
||||
if (node.optional) this.token("?");
|
||||
this.print(node.typeAnnotation, node);
|
||||
},
|
||||
@ -79,7 +79,11 @@ export function ArrowFunctionExpression(node: Object) {
|
||||
|
||||
const firstParam = node.params[0];
|
||||
|
||||
if (node.params.length === 1 && t.isIdentifier(firstParam) && !hasTypes(node, firstParam)) {
|
||||
if (
|
||||
node.params.length === 1 &&
|
||||
t.isIdentifier(firstParam) &&
|
||||
!hasTypes(node, firstParam)
|
||||
) {
|
||||
this.print(firstParam, node);
|
||||
} else {
|
||||
this._params(node);
|
||||
@ -93,6 +97,11 @@ export function ArrowFunctionExpression(node: Object) {
|
||||
}
|
||||
|
||||
function hasTypes(node, param) {
|
||||
return node.typeParameters || node.returnType || param.typeAnnotation || param.optional ||
|
||||
param.trailingComments;
|
||||
return (
|
||||
node.typeParameters ||
|
||||
node.returnType ||
|
||||
param.typeAnnotation ||
|
||||
param.optional ||
|
||||
param.trailingComments
|
||||
);
|
||||
}
|
||||
|
||||
@ -91,7 +91,10 @@ function ExportDeclaration(node: Object) {
|
||||
let hasSpecial = false;
|
||||
while (true) {
|
||||
const first = specifiers[0];
|
||||
if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) {
|
||||
if (
|
||||
t.isExportDefaultSpecifier(first) ||
|
||||
t.isExportNamespaceSpecifier(first)
|
||||
) {
|
||||
hasSpecial = true;
|
||||
this.print(specifiers.shift(), node);
|
||||
if (specifiers.length) {
|
||||
@ -138,7 +141,10 @@ export function ImportDeclaration(node: Object) {
|
||||
// print "special" specifiers first
|
||||
while (true) {
|
||||
const first = specifiers[0];
|
||||
if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) {
|
||||
if (
|
||||
t.isImportDefaultSpecifier(first) ||
|
||||
t.isImportNamespaceSpecifier(first)
|
||||
) {
|
||||
this.print(specifiers.shift(), node);
|
||||
if (specifiers.length) {
|
||||
this.token(",");
|
||||
|
||||
@ -17,7 +17,8 @@ export function IfStatement(node: Object) {
|
||||
this.token(")");
|
||||
this.space();
|
||||
|
||||
const needsBlock = node.alternate && t.isIfStatement(getLastStatement(node.consequent));
|
||||
const needsBlock =
|
||||
node.alternate && t.isIfStatement(getLastStatement(node.consequent));
|
||||
if (needsBlock) {
|
||||
this.token("{");
|
||||
this.newline();
|
||||
@ -80,8 +81,8 @@ export function WhileStatement(node: Object) {
|
||||
this.printBlock(node);
|
||||
}
|
||||
|
||||
const buildForXStatement = function (op) {
|
||||
return function (node: Object) {
|
||||
const buildForXStatement = function(op) {
|
||||
return function(node: Object) {
|
||||
this.word("for");
|
||||
this.space();
|
||||
if (op === "of" && node.await) {
|
||||
@ -116,7 +117,7 @@ export function DoWhileStatement(node: Object) {
|
||||
}
|
||||
|
||||
function buildLabelStatement(prefix, key = "label") {
|
||||
return function (node: Object) {
|
||||
return function(node: Object) {
|
||||
this.word(prefix);
|
||||
|
||||
const label = node[key];
|
||||
@ -261,7 +262,10 @@ export function VariableDeclaration(node: Object, parent: Object) {
|
||||
|
||||
let separator;
|
||||
if (hasInits) {
|
||||
separator = node.kind === "const" ? constDeclarationIndent : variableDeclarationIndent;
|
||||
separator =
|
||||
node.kind === "const"
|
||||
? constDeclarationIndent
|
||||
: variableDeclarationIndent;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@ -10,9 +10,7 @@ export function RestElement(node: Object) {
|
||||
this.print(node.argument, node);
|
||||
}
|
||||
|
||||
export {
|
||||
RestElement as SpreadElement,
|
||||
};
|
||||
export { RestElement as SpreadElement };
|
||||
|
||||
export function ObjectExpression(node: Object) {
|
||||
const props = node.properties;
|
||||
@ -45,8 +43,11 @@ export function ObjectProperty(node: Object) {
|
||||
this.token("]");
|
||||
} else {
|
||||
// print `({ foo: foo = 5 } = {})` as `({ foo = 5 } = {});`
|
||||
if (t.isAssignmentPattern(node.value) && t.isIdentifier(node.key) &&
|
||||
node.key.name === node.value.left.name) {
|
||||
if (
|
||||
t.isAssignmentPattern(node.value) &&
|
||||
t.isIdentifier(node.key) &&
|
||||
node.key.name === node.value.left.name
|
||||
) {
|
||||
this.print(node.value, node);
|
||||
return;
|
||||
}
|
||||
@ -54,10 +55,12 @@ export function ObjectProperty(node: Object) {
|
||||
this.print(node.key, node);
|
||||
|
||||
// shorthand!
|
||||
if (node.shorthand &&
|
||||
if (
|
||||
node.shorthand &&
|
||||
(t.isIdentifier(node.key) &&
|
||||
t.isIdentifier(node.value) &&
|
||||
node.key.name === node.value.name)) {
|
||||
node.key.name === node.value.name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,9 +61,13 @@ function normalizeOptions(code, opts): Format {
|
||||
if (format.minified) {
|
||||
format.compact = true;
|
||||
|
||||
format.shouldPrintComment = format.shouldPrintComment || (() => format.comments);
|
||||
format.shouldPrintComment =
|
||||
format.shouldPrintComment || (() => format.comments);
|
||||
} else {
|
||||
format.shouldPrintComment = format.shouldPrintComment || ((value) => format.comments ||
|
||||
format.shouldPrintComment =
|
||||
format.shouldPrintComment ||
|
||||
(value =>
|
||||
format.comments ||
|
||||
(value.indexOf("@license") >= 0 || value.indexOf("@preserve") >= 0));
|
||||
}
|
||||
|
||||
@ -71,7 +75,9 @@ function normalizeOptions(code, opts): Format {
|
||||
format.compact = code.length > 500_000; // 500KB
|
||||
|
||||
if (format.compact) {
|
||||
console.error("[BABEL] " + messages.get("codeGeneratorDeopt", opts.filename, "500KB"));
|
||||
console.error(
|
||||
"[BABEL] " + messages.get("codeGeneratorDeopt", opts.filename, "500KB"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +103,7 @@ export class CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
export default function (ast: Object, opts: Object, code: string): Object {
|
||||
export default function(ast: Object, opts: Object, code: string): Object {
|
||||
const gen = new Generator(ast, opts, code);
|
||||
return gen.generate();
|
||||
}
|
||||
|
||||
@ -7,15 +7,16 @@ function expandAliases(obj) {
|
||||
|
||||
function add(type, func) {
|
||||
const fn = newObj[type];
|
||||
newObj[type] = fn ? function(node, parent, stack) {
|
||||
newObj[type] = fn
|
||||
? function(node, parent, stack) {
|
||||
const result = fn(node, parent, stack);
|
||||
|
||||
return result == null ? func(node, parent, stack) : result;
|
||||
} : func;
|
||||
}
|
||||
: func;
|
||||
}
|
||||
|
||||
for (const type of Object.keys(obj)) {
|
||||
|
||||
const aliases = t.FLIPPED_ALIAS_KEYS[type];
|
||||
if (aliases) {
|
||||
for (const alias of aliases) {
|
||||
@ -46,8 +47,10 @@ function isOrHasCallExpression(node) {
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(node)) {
|
||||
return isOrHasCallExpression(node.object) ||
|
||||
(!node.computed && isOrHasCallExpression(node.property));
|
||||
return (
|
||||
isOrHasCallExpression(node.object) ||
|
||||
(!node.computed && isOrHasCallExpression(node.property))
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -38,11 +38,19 @@ export function UpdateExpression(node: Object, parent: Object): boolean {
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
}
|
||||
|
||||
export function ObjectExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
export function ObjectExpression(
|
||||
node: Object,
|
||||
parent: Object,
|
||||
printStack: Array<Object>,
|
||||
): boolean {
|
||||
return isFirstInStatement(printStack, { considerArrow: true });
|
||||
}
|
||||
|
||||
export function DoExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
export function DoExpression(
|
||||
node: Object,
|
||||
parent: Object,
|
||||
printStack: Array<Object>,
|
||||
): boolean {
|
||||
return isFirstInStatement(printStack);
|
||||
}
|
||||
|
||||
@ -55,7 +63,8 @@ export function Binary(node: Object, parent: Object): boolean {
|
||||
}
|
||||
|
||||
if (
|
||||
((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) ||
|
||||
((t.isCallExpression(parent) || t.isNewExpression(parent)) &&
|
||||
parent.callee === node) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
(t.isMemberExpression(parent) && parent.object === node) ||
|
||||
t.isAwaitExpression(parent)
|
||||
@ -72,7 +81,9 @@ export function Binary(node: Object, parent: Object): boolean {
|
||||
|
||||
if (
|
||||
// Logical expressions with the same precedence don't need parens.
|
||||
(parentPos === nodePos && parent.right === node && !t.isLogicalExpression(parent)) ||
|
||||
(parentPos === nodePos &&
|
||||
parent.right === node &&
|
||||
!t.isLogicalExpression(parent)) ||
|
||||
parentPos > nodePos
|
||||
) {
|
||||
return true;
|
||||
@ -85,11 +96,13 @@ export function Binary(node: Object, parent: Object): boolean {
|
||||
export function BinaryExpression(node: Object, parent: Object): boolean {
|
||||
// let i = (1 in []);
|
||||
// for ((1 in []);;);
|
||||
return node.operator === "in" && (t.isVariableDeclarator(parent) || t.isFor(parent));
|
||||
return (
|
||||
node.operator === "in" &&
|
||||
(t.isVariableDeclarator(parent) || t.isFor(parent))
|
||||
);
|
||||
}
|
||||
|
||||
export function SequenceExpression(node: Object, parent: Object): boolean {
|
||||
|
||||
if (
|
||||
// Although parentheses wouldn"t hurt around sequence
|
||||
// expressions in the head of for loops, traditional style
|
||||
@ -113,29 +126,40 @@ export function SequenceExpression(node: Object, parent: Object): boolean {
|
||||
}
|
||||
|
||||
export function YieldExpression(node: Object, parent: Object): boolean {
|
||||
return t.isBinary(parent) ||
|
||||
return (
|
||||
t.isBinary(parent) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
t.isCallExpression(parent) ||
|
||||
t.isMemberExpression(parent) ||
|
||||
t.isNewExpression(parent) ||
|
||||
(t.isConditionalExpression(parent) && node === parent.test);
|
||||
|
||||
(t.isConditionalExpression(parent) && node === parent.test)
|
||||
);
|
||||
}
|
||||
|
||||
export { YieldExpression as AwaitExpression };
|
||||
|
||||
export function ClassExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
export function ClassExpression(
|
||||
node: Object,
|
||||
parent: Object,
|
||||
printStack: Array<Object>,
|
||||
): boolean {
|
||||
return isFirstInStatement(printStack, { considerDefaultExports: true });
|
||||
}
|
||||
|
||||
export function UnaryLike(node: Object, parent: Object): boolean {
|
||||
return t.isMemberExpression(parent, { object: node }) ||
|
||||
return (
|
||||
t.isMemberExpression(parent, { object: node }) ||
|
||||
t.isCallExpression(parent, { callee: node }) ||
|
||||
t.isNewExpression(parent, { callee: node }) ||
|
||||
t.isBinaryExpression(parent, { operator: "**", left: node });
|
||||
t.isBinaryExpression(parent, { operator: "**", left: node })
|
||||
);
|
||||
}
|
||||
|
||||
export function FunctionExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
export function FunctionExpression(
|
||||
node: Object,
|
||||
parent: Object,
|
||||
printStack: Array<Object>,
|
||||
): boolean {
|
||||
return isFirstInStatement(printStack, { considerDefaultExports: true });
|
||||
}
|
||||
|
||||
@ -167,10 +191,10 @@ export function AssignmentExpression(node: Object): boolean {
|
||||
|
||||
// Walk up the print stack to deterimine if our node can come first
|
||||
// in statement.
|
||||
function isFirstInStatement(printStack: Array<Object>, {
|
||||
considerArrow = false,
|
||||
considerDefaultExports = false,
|
||||
} = {}): boolean {
|
||||
function isFirstInStatement(
|
||||
printStack: Array<Object>,
|
||||
{ considerArrow = false, considerDefaultExports = false } = {},
|
||||
): boolean {
|
||||
let i = printStack.length - 1;
|
||||
let node = printStack[i];
|
||||
i--;
|
||||
@ -179,8 +203,9 @@ function isFirstInStatement(printStack: Array<Object>, {
|
||||
if (
|
||||
t.isExpressionStatement(parent, { expression: node }) ||
|
||||
t.isTaggedTemplateExpression(parent) ||
|
||||
considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node }) ||
|
||||
considerArrow && t.isArrowFunctionExpression(parent, { body: node })
|
||||
(considerDefaultExports &&
|
||||
t.isExportDefaultDeclaration(parent, { declaration: node })) ||
|
||||
(considerArrow && t.isArrowFunctionExpression(parent, { body: node }))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import * as t from "babel-types";
|
||||
|
||||
type WhitespaceObject = {
|
||||
before?: boolean,
|
||||
after?: boolean
|
||||
after?: boolean,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -45,15 +45,22 @@ function isHelper(node) {
|
||||
} else if (t.isCallExpression(node)) {
|
||||
return isHelper(node.callee);
|
||||
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
|
||||
return (t.isIdentifier(node.left) && isHelper(node.left)) || isHelper(node.right);
|
||||
return (
|
||||
(t.isIdentifier(node.left) && isHelper(node.left)) || isHelper(node.right)
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isType(node) {
|
||||
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
|
||||
t.isIdentifier(node) || t.isMemberExpression(node);
|
||||
return (
|
||||
t.isLiteral(node) ||
|
||||
t.isObjectExpression(node) ||
|
||||
t.isArrayExpression(node) ||
|
||||
t.isIdentifier(node) ||
|
||||
t.isMemberExpression(node)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,7 +68,6 @@ function isType(node) {
|
||||
*/
|
||||
|
||||
export const nodes = {
|
||||
|
||||
/**
|
||||
* Test if AssignmentExpression needs whitespace.
|
||||
*/
|
||||
@ -164,9 +170,10 @@ export const nodes = {
|
||||
* Test if Property needs whitespace.
|
||||
*/
|
||||
|
||||
nodes.ObjectProperty =
|
||||
nodes.ObjectTypeProperty =
|
||||
nodes.ObjectMethod = function (node: Object, parent): ?WhitespaceObject {
|
||||
nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function(
|
||||
node: Object,
|
||||
parent,
|
||||
): ?WhitespaceObject {
|
||||
if (parent.properties[0] === node) {
|
||||
return {
|
||||
before: true,
|
||||
@ -179,7 +186,6 @@ nodes.ObjectMethod = function (node: Object, parent): ?WhitespaceObject {
|
||||
*/
|
||||
|
||||
export const list = {
|
||||
|
||||
/**
|
||||
* Return VariableDeclaration declarations init properties.
|
||||
*/
|
||||
@ -216,12 +222,12 @@ export const list = {
|
||||
["LabeledStatement", true],
|
||||
["SwitchStatement", true],
|
||||
["TryStatement", true],
|
||||
].forEach(function ([type, amounts]) {
|
||||
].forEach(function([type, amounts]) {
|
||||
if (typeof amounts === "boolean") {
|
||||
amounts = { after: amounts, before: amounts };
|
||||
}
|
||||
[type].concat(t.FLIPPED_ALIAS_KEYS[type] || []).forEach(function (type) {
|
||||
nodes[type] = function () {
|
||||
[type].concat(t.FLIPPED_ALIAS_KEYS[type] || []).forEach(function(type) {
|
||||
nodes[type] = function() {
|
||||
return amounts;
|
||||
};
|
||||
});
|
||||
|
||||
@ -14,21 +14,21 @@ const ZERO_DECIMAL_INTEGER = /\.0+$/;
|
||||
const NON_DECIMAL_LITERAL = /^0[box]/;
|
||||
|
||||
export type Format = {
|
||||
shouldPrintComment: (comment: string) => boolean;
|
||||
retainLines: boolean;
|
||||
retainFunctionParens: boolean;
|
||||
comments: boolean;
|
||||
auxiliaryCommentBefore: string;
|
||||
auxiliaryCommentAfter: string;
|
||||
compact: boolean | "auto";
|
||||
minified: boolean;
|
||||
quotes: "single" | "double";
|
||||
concise: boolean;
|
||||
shouldPrintComment: (comment: string) => boolean,
|
||||
retainLines: boolean,
|
||||
retainFunctionParens: boolean,
|
||||
comments: boolean,
|
||||
auxiliaryCommentBefore: string,
|
||||
auxiliaryCommentAfter: string,
|
||||
compact: boolean | "auto",
|
||||
minified: boolean,
|
||||
quotes: "single" | "double",
|
||||
concise: boolean,
|
||||
indent: {
|
||||
adjustMultilineComment: boolean;
|
||||
style: string;
|
||||
base: number;
|
||||
}
|
||||
adjustMultilineComment: boolean,
|
||||
style: string,
|
||||
base: number,
|
||||
},
|
||||
};
|
||||
|
||||
export default class Printer {
|
||||
@ -107,7 +107,10 @@ export default class Printer {
|
||||
space(force: boolean = false): void {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if ((this._buf.hasContent() && !this.endsWith(" ") && !this.endsWith("\n")) || force) {
|
||||
if (
|
||||
(this._buf.hasContent() && !this.endsWith(" ") && !this.endsWith("\n")) ||
|
||||
force
|
||||
) {
|
||||
this._space();
|
||||
}
|
||||
}
|
||||
@ -149,14 +152,14 @@ export default class Printer {
|
||||
token(str: string): void {
|
||||
// space is mandatory to avoid outputting <!--
|
||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
||||
if ((str === "--" && this.endsWith("!")) ||
|
||||
|
||||
if (
|
||||
(str === "--" && this.endsWith("!")) ||
|
||||
// Need spaces for operators of the same kind to avoid: `a+++b`
|
||||
(str[0] === "+" && this.endsWith("+")) ||
|
||||
(str[0] === "-" && this.endsWith("-")) ||
|
||||
|
||||
// Needs spaces to avoid changing '34' to '34.', which would still be a valid number.
|
||||
(str[0] === "." && this._endsWithInteger)) {
|
||||
(str[0] === "." && this._endsWithInteger)
|
||||
) {
|
||||
this._space();
|
||||
}
|
||||
|
||||
@ -294,9 +297,9 @@ export default class Printer {
|
||||
*/
|
||||
|
||||
startTerminatorless(): Object {
|
||||
return this._parenPushNewlineState = {
|
||||
return (this._parenPushNewlineState = {
|
||||
printed: false,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,7 +325,11 @@ export default class Printer {
|
||||
const printMethod = this[node.type];
|
||||
if (!printMethod) {
|
||||
// eslint-disable-next-line max-len
|
||||
throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
|
||||
throw new ReferenceError(
|
||||
`unknown node of type ${JSON.stringify(
|
||||
node.type,
|
||||
)} with constructor ${JSON.stringify(node && node.constructor.name)}`,
|
||||
);
|
||||
}
|
||||
|
||||
this._printStack.push(node);
|
||||
@ -335,7 +342,8 @@ export default class Printer {
|
||||
if (
|
||||
this.format.retainFunctionParens &&
|
||||
node.type === "FunctionExpression" &&
|
||||
node.extra && node.extra.parenthesized
|
||||
node.extra &&
|
||||
node.extra.parenthesized
|
||||
) {
|
||||
needsParens = true;
|
||||
}
|
||||
@ -343,7 +351,7 @@ export default class Printer {
|
||||
|
||||
this._printLeadingComments(node, parent);
|
||||
|
||||
const loc = (t.isProgram(node) || t.isFile(node)) ? null : node.loc;
|
||||
const loc = t.isProgram(node) || t.isFile(node) ? null : node.loc;
|
||||
this.withSource("start", loc, () => {
|
||||
this[node.type](node, parent);
|
||||
});
|
||||
@ -392,7 +400,12 @@ export default class Printer {
|
||||
|
||||
getPossibleRaw(node) {
|
||||
const extra = node.extra;
|
||||
if (extra && extra.raw != null && extra.rawValue != null && node.value === extra.rawValue) {
|
||||
if (
|
||||
extra &&
|
||||
extra.raw != null &&
|
||||
extra.rawValue != null &&
|
||||
node.value === extra.rawValue
|
||||
) {
|
||||
return extra.raw;
|
||||
}
|
||||
}
|
||||
@ -490,14 +503,24 @@ export default class Printer {
|
||||
// user node
|
||||
if (leading) {
|
||||
const comments = node.leadingComments;
|
||||
const comment = comments && find(comments, (comment) =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value));
|
||||
const comment =
|
||||
comments &&
|
||||
find(
|
||||
comments,
|
||||
comment =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||
);
|
||||
|
||||
lines = this._whitespace.getNewlinesBefore(comment || node);
|
||||
} else {
|
||||
const comments = node.trailingComments;
|
||||
const comment = comments && findLast(comments, (comment) =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value));
|
||||
const comment =
|
||||
comments &&
|
||||
findLast(
|
||||
comments,
|
||||
comment =>
|
||||
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||
);
|
||||
|
||||
lines = this._whitespace.getNewlinesAfter(comment || node);
|
||||
}
|
||||
@ -520,7 +543,9 @@ export default class Printer {
|
||||
_getComments(leading, node) {
|
||||
// Note, we use a boolean flag here instead of passing in the attribute name as it is faster
|
||||
// because this is called extremely frequently.
|
||||
return (node && (leading ? node.leadingComments : node.trailingComments)) || [];
|
||||
return (
|
||||
(node && (leading ? node.leadingComments : node.trailingComments)) || []
|
||||
);
|
||||
}
|
||||
|
||||
_printComment(comment) {
|
||||
@ -539,21 +564,32 @@ export default class Printer {
|
||||
}
|
||||
|
||||
// whitespace before
|
||||
this.newline(this._whitespace ? this._whitespace.getNewlinesBefore(comment) : 0);
|
||||
this.newline(
|
||||
this._whitespace ? this._whitespace.getNewlinesBefore(comment) : 0,
|
||||
);
|
||||
|
||||
if (!this.endsWith("[") && !this.endsWith("{")) this.space();
|
||||
|
||||
let val = comment.type === "CommentLine" ? `//${comment.value}\n` : `/*${comment.value}*/`;
|
||||
let val =
|
||||
comment.type === "CommentLine"
|
||||
? `//${comment.value}\n`
|
||||
: `/*${comment.value}*/`;
|
||||
|
||||
//
|
||||
if (comment.type === "CommentBlock" && this.format.indent.adjustMultilineComment) {
|
||||
if (
|
||||
comment.type === "CommentBlock" &&
|
||||
this.format.indent.adjustMultilineComment
|
||||
) {
|
||||
const offset = comment.loc && comment.loc.start.column;
|
||||
if (offset) {
|
||||
const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||
val = val.replace(newlineRegex, "\n");
|
||||
}
|
||||
|
||||
const indentSize = Math.max(this._getIndent().length, this._buf.getCurrentColumn());
|
||||
const indentSize = Math.max(
|
||||
this._getIndent().length,
|
||||
this._buf.getCurrentColumn(),
|
||||
);
|
||||
val = val.replace(/\n(?!$)/g, `\n${repeat(" ", indentSize)}`);
|
||||
}
|
||||
|
||||
@ -565,9 +601,11 @@ export default class Printer {
|
||||
});
|
||||
|
||||
// whitespace after
|
||||
this.newline((this._whitespace ? this._whitespace.getNewlinesAfter(comment) : 0) +
|
||||
this.newline(
|
||||
(this._whitespace ? this._whitespace.getNewlinesAfter(comment) : 0) +
|
||||
// Subtract one to account for the line force-added above.
|
||||
(comment.type === "CommentLine" ? -1 : 0));
|
||||
(comment.type === "CommentLine" ? -1 : 0),
|
||||
);
|
||||
}
|
||||
|
||||
_printComments(comments?: Array<Object>) {
|
||||
|
||||
@ -18,16 +18,16 @@ export default class SourceMap {
|
||||
|
||||
get() {
|
||||
if (!this._cachedMap) {
|
||||
const map = this._cachedMap = new sourceMap.SourceMapGenerator({
|
||||
const map = (this._cachedMap = new sourceMap.SourceMapGenerator({
|
||||
file: this._opts.sourceMapTarget,
|
||||
sourceRoot: this._opts.sourceRoot,
|
||||
});
|
||||
}));
|
||||
|
||||
const code = this._code;
|
||||
if (typeof code === "string") {
|
||||
map.setSourceContent(this._opts.sourceFileName, code);
|
||||
} else if (typeof code === "object") {
|
||||
Object.keys(code).forEach((sourceFileName) => {
|
||||
Object.keys(code).forEach(sourceFileName => {
|
||||
map.setSourceContent(sourceFileName, code[sourceFileName]);
|
||||
});
|
||||
}
|
||||
@ -60,8 +60,11 @@ export default class SourceMap {
|
||||
|
||||
// If this mapping points to the same source location as the last one, we can ignore it since
|
||||
// the previous one covers it.
|
||||
if (this._lastGenLine === generatedLine && this._lastSourceLine === line &&
|
||||
this._lastSourceColumn === column) {
|
||||
if (
|
||||
this._lastGenLine === generatedLine &&
|
||||
this._lastSourceLine === line &&
|
||||
this._lastSourceColumn === column
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,7 +83,10 @@ export default class SourceMap {
|
||||
column: generatedColumn,
|
||||
},
|
||||
source: line == null ? undefined : filename || this._opts.sourceFileName,
|
||||
original: line == null ? undefined : {
|
||||
original:
|
||||
line == null
|
||||
? undefined
|
||||
: {
|
||||
line: line,
|
||||
column: column,
|
||||
},
|
||||
|
||||
@ -17,7 +17,11 @@ export default class Whitespace {
|
||||
let endToken;
|
||||
const tokens = this.tokens;
|
||||
|
||||
let index = this._findToken((token) => token.start - node.start, 0, tokens.length);
|
||||
let index = this._findToken(
|
||||
token => token.start - node.start,
|
||||
0,
|
||||
tokens.length,
|
||||
);
|
||||
if (index >= 0) {
|
||||
while (index && node.start === tokens[index - 1].start) --index;
|
||||
startToken = tokens[index - 1];
|
||||
@ -36,7 +40,11 @@ export default class Whitespace {
|
||||
let endToken;
|
||||
const tokens = this.tokens;
|
||||
|
||||
let index = this._findToken((token) => token.end - node.end, 0, tokens.length);
|
||||
let index = this._findToken(
|
||||
token => token.end - node.end,
|
||||
0,
|
||||
tokens.length,
|
||||
);
|
||||
if (index >= 0) {
|
||||
while (index && node.end === tokens[index - 1].end) --index;
|
||||
startToken = tokens[index];
|
||||
|
||||
@ -9,125 +9,164 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import fixtures from "babel-helper-fixtures";
|
||||
|
||||
describe("generation", function () {
|
||||
it("completeness", function () {
|
||||
Object.keys(t.VISITOR_KEYS).forEach(function (type) {
|
||||
describe("generation", function() {
|
||||
it("completeness", function() {
|
||||
Object.keys(t.VISITOR_KEYS).forEach(function(type) {
|
||||
assert.ok(!!Printer.prototype[type], type + " should exist");
|
||||
});
|
||||
|
||||
Object.keys(Printer.prototype).forEach(function (type) {
|
||||
Object.keys(Printer.prototype).forEach(function(type) {
|
||||
if (!/[A-Z]/.test(type[0])) return;
|
||||
assert.ok(t.VISITOR_KEYS[type], type + " should not exist");
|
||||
});
|
||||
});
|
||||
|
||||
it("multiple sources", function () {
|
||||
it("multiple sources", function() {
|
||||
const sources = {
|
||||
"a.js": "function hi (msg) { console.log(msg); }\n",
|
||||
"b.js": "hi('hello');\n",
|
||||
};
|
||||
const parsed = Object.keys(sources).reduce(function (_parsed, filename) {
|
||||
_parsed[filename] = parse(sources[filename], { sourceFilename: filename });
|
||||
const parsed = Object.keys(sources).reduce(function(_parsed, filename) {
|
||||
_parsed[filename] = parse(sources[filename], {
|
||||
sourceFilename: filename,
|
||||
});
|
||||
return _parsed;
|
||||
}, {});
|
||||
|
||||
const combinedAst = {
|
||||
"type": "File",
|
||||
"program": {
|
||||
"type": "Program",
|
||||
"sourceType": "module",
|
||||
"body": [].concat(parsed["a.js"].program.body, parsed["b.js"].program.body),
|
||||
type: "File",
|
||||
program: {
|
||||
type: "Program",
|
||||
sourceType: "module",
|
||||
body: [].concat(
|
||||
parsed["a.js"].program.body,
|
||||
parsed["b.js"].program.body,
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
const generated = generate(combinedAst, { sourceMaps: true }, sources);
|
||||
|
||||
chai.expect(generated.map).to.deep.equal({
|
||||
chai.expect(generated.map).to.deep.equal(
|
||||
{
|
||||
version: 3,
|
||||
sources: [ "a.js", "b.js" ],
|
||||
mappings: "AAAA,SAASA,EAAT,CAAaC,GAAb,EAAkB;AAAEC,UAAQC,GAAR,CAAYF,GAAZ;AAAmB;;ACAvCD,GAAG,OAAH",
|
||||
names: [
|
||||
"hi",
|
||||
"msg",
|
||||
"console",
|
||||
"log",
|
||||
],
|
||||
sources: ["a.js", "b.js"],
|
||||
mappings:
|
||||
"AAAA,SAASA,EAAT,CAAaC,GAAb,EAAkB;AAAEC,UAAQC,GAAR,CAAYF,GAAZ;AAAmB;;ACAvCD,GAAG,OAAH",
|
||||
names: ["hi", "msg", "console", "log"],
|
||||
sourcesContent: [
|
||||
"function hi (msg) { console.log(msg); }\n",
|
||||
"hi('hello');\n",
|
||||
],
|
||||
}, "sourcemap was incorrectly generated");
|
||||
},
|
||||
"sourcemap was incorrectly generated",
|
||||
);
|
||||
|
||||
chai.expect(generated.rawMappings).to.deep.equal([
|
||||
{ name: undefined,
|
||||
chai.expect(generated.rawMappings).to.deep.equal(
|
||||
[
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 0 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: "hi",
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: "hi",
|
||||
generated: { line: 1, column: 9 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 9 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 9 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 11 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: "msg",
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: "msg",
|
||||
generated: { line: 1, column: 12 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 13 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 13 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 15 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 17 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 18 } },
|
||||
{ name: "console",
|
||||
original: { line: 1, column: 18 },
|
||||
},
|
||||
{
|
||||
name: "console",
|
||||
generated: { line: 2, column: 0 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 20 } },
|
||||
{ name: "log",
|
||||
original: { line: 1, column: 20 },
|
||||
},
|
||||
{
|
||||
name: "log",
|
||||
generated: { line: 2, column: 10 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 28 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 28 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 2, column: 13 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 20 } },
|
||||
{ name: "msg",
|
||||
original: { line: 1, column: 20 },
|
||||
},
|
||||
{
|
||||
name: "msg",
|
||||
generated: { line: 2, column: 14 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 32 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 32 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 2, column: 17 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 20 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 20 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 3, column: 0 },
|
||||
source: "a.js",
|
||||
original: { line: 1, column: 39 } },
|
||||
{ name: "hi",
|
||||
original: { line: 1, column: 39 },
|
||||
},
|
||||
{
|
||||
name: "hi",
|
||||
generated: { line: 5, column: 0 },
|
||||
source: "b.js",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 5, column: 3 },
|
||||
source: "b.js",
|
||||
original: { line: 1, column: 3 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 3 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 5, column: 10 },
|
||||
source: "b.js",
|
||||
original: { line: 1, column: 0 } },
|
||||
], "raw mappings were incorrectly generated");
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
],
|
||||
"raw mappings were incorrectly generated",
|
||||
);
|
||||
|
||||
chai.expect(generated.code).to.equal(
|
||||
chai
|
||||
.expect(generated.code)
|
||||
.to.equal(
|
||||
"function hi(msg) {\n console.log(msg);\n}\n\nhi('hello');",
|
||||
"code was incorrectly generated"
|
||||
"code was incorrectly generated",
|
||||
);
|
||||
});
|
||||
|
||||
it("identifierName", function () {
|
||||
it("identifierName", function() {
|
||||
const code = "function foo() { bar; }\n";
|
||||
|
||||
const ast = parse(code, { filename: "inline" }).program;
|
||||
@ -141,50 +180,74 @@ describe("generation", function () {
|
||||
id2.name += "2";
|
||||
id2.loc.identiferName = "bar";
|
||||
|
||||
const generated = generate(ast, {
|
||||
const generated = generate(
|
||||
ast,
|
||||
{
|
||||
filename: "inline",
|
||||
sourceFileName: "inline",
|
||||
sourceMaps: true,
|
||||
}, code);
|
||||
},
|
||||
code,
|
||||
);
|
||||
|
||||
chai.expect(generated.map).to.deep.equal({
|
||||
chai.expect(generated.map).to.deep.equal(
|
||||
{
|
||||
version: 3,
|
||||
sources: ["inline"],
|
||||
names: ["foo", "bar" ],
|
||||
names: ["foo", "bar"],
|
||||
mappings: "AAAA,SAASA,IAAT,GAAe;AAAEC;AAAM",
|
||||
sourcesContent: [ "function foo() { bar; }\n" ],
|
||||
}, "sourcemap was incorrectly generated");
|
||||
sourcesContent: ["function foo() { bar; }\n"],
|
||||
},
|
||||
"sourcemap was incorrectly generated",
|
||||
);
|
||||
|
||||
chai.expect(generated.rawMappings).to.deep.equal([
|
||||
{ name: undefined,
|
||||
chai.expect(generated.rawMappings).to.deep.equal(
|
||||
[
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 0 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: "foo",
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: "foo",
|
||||
generated: { line: 1, column: 9 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 9 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 9 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 13 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 0 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 0 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 1, column: 16 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 15 } },
|
||||
{ name: "bar",
|
||||
original: { line: 1, column: 15 },
|
||||
},
|
||||
{
|
||||
name: "bar",
|
||||
generated: { line: 2, column: 0 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 17 } },
|
||||
{ name: undefined,
|
||||
original: { line: 1, column: 17 },
|
||||
},
|
||||
{
|
||||
name: undefined,
|
||||
generated: { line: 3, column: 0 },
|
||||
source: "inline",
|
||||
original: { line: 1, column: 23 } },
|
||||
], "raw mappings were incorrectly generated");
|
||||
original: { line: 1, column: 23 },
|
||||
},
|
||||
],
|
||||
"raw mappings were incorrectly generated",
|
||||
);
|
||||
|
||||
chai.expect(generated.code).to.equal(
|
||||
chai
|
||||
.expect(generated.code)
|
||||
.to.equal(
|
||||
"function foo2() {\n bar2;\n}",
|
||||
"code was incorrectly generated"
|
||||
"code was incorrectly generated",
|
||||
);
|
||||
});
|
||||
|
||||
@ -199,17 +262,22 @@ describe("generation", function () {
|
||||
|
||||
chai.expect(generated.rawMappings).to.be.an("array");
|
||||
|
||||
chai.expect(generated).ownPropertyDescriptor("map").not.to.have.property("value");
|
||||
chai
|
||||
.expect(generated)
|
||||
.ownPropertyDescriptor("map")
|
||||
.not.to.have.property("value");
|
||||
|
||||
chai.expect(generated.map).to.be.an("object");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("programmatic generation", function() {
|
||||
it("numeric member expression", function() {
|
||||
// Should not generate `0.foo`
|
||||
const mem = t.memberExpression(t.numericLiteral(60702), t.identifier("foo"));
|
||||
const mem = t.memberExpression(
|
||||
t.numericLiteral(60702),
|
||||
t.identifier("foo"),
|
||||
);
|
||||
new Function(generate(mem).code);
|
||||
});
|
||||
|
||||
@ -220,10 +288,10 @@ describe("programmatic generation", function() {
|
||||
t.stringLiteral("while cond"),
|
||||
t.ifStatement(
|
||||
t.stringLiteral("nested"),
|
||||
t.expressionStatement(t.numericLiteral(1))
|
||||
)
|
||||
t.expressionStatement(t.numericLiteral(1)),
|
||||
),
|
||||
t.expressionStatement(t.stringLiteral("alt"))
|
||||
),
|
||||
t.expressionStatement(t.stringLiteral("alt")),
|
||||
);
|
||||
|
||||
const ast = parse(generate(ifStatement).code);
|
||||
@ -233,35 +301,22 @@ describe("programmatic generation", function() {
|
||||
it("prints directives in block with empty body", function() {
|
||||
const blockStatement = t.blockStatement(
|
||||
[],
|
||||
[t.directive(t.directiveLiteral("use strict"))]
|
||||
[t.directive(t.directiveLiteral("use strict"))],
|
||||
);
|
||||
|
||||
const output = generate(blockStatement).code;
|
||||
assert.equal(output, [
|
||||
"{",
|
||||
" \"use strict\";",
|
||||
"}",
|
||||
].join("\n"));
|
||||
assert.equal(output, ["{", ' "use strict";', "}"].join("\n"));
|
||||
});
|
||||
|
||||
it("flow object indentation", function() {
|
||||
const objectStatement = t.objectTypeAnnotation(
|
||||
[
|
||||
t.objectTypeProperty(
|
||||
t.identifier("bar"),
|
||||
t.stringTypeAnnotation()
|
||||
),
|
||||
],
|
||||
[t.objectTypeProperty(t.identifier("bar"), t.stringTypeAnnotation())],
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
|
||||
const output = generate(objectStatement).code;
|
||||
assert.equal(output, [
|
||||
"{",
|
||||
" bar: string,",
|
||||
"}",
|
||||
].join("\n"));
|
||||
assert.equal(output, ["{", " bar: string,", "}"].join("\n"));
|
||||
});
|
||||
|
||||
it("flow object indentation with empty leading ObjectTypeProperty", function() {
|
||||
@ -273,21 +328,17 @@ describe("programmatic generation", function() {
|
||||
t.anyTypeAnnotation(),
|
||||
t.identifier("Test"),
|
||||
),
|
||||
]
|
||||
],
|
||||
);
|
||||
|
||||
const output = generate(objectStatement).code;
|
||||
|
||||
assert.equal(output, [
|
||||
"{",
|
||||
" [key: any]: Test,",
|
||||
"}",
|
||||
].join("\n"));
|
||||
assert.equal(output, ["{", " [key: any]: Test,", "}"].join("\n"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("whitespace", function () {
|
||||
it("empty token list", function () {
|
||||
describe("whitespace", function() {
|
||||
it("empty token list", function() {
|
||||
const w = new Whitespace([]);
|
||||
assert.equal(w.getNewlinesBefore(t.stringLiteral("1")), 0);
|
||||
});
|
||||
@ -295,10 +346,13 @@ describe("whitespace", function () {
|
||||
|
||||
const suites = fixtures(`${__dirname}/fixtures`);
|
||||
|
||||
suites.forEach(function (testSuite) {
|
||||
describe("generation/" + testSuite.title, function () {
|
||||
testSuite.tests.forEach(function (task) {
|
||||
it(task.title, !task.disabled && function () {
|
||||
suites.forEach(function(testSuite) {
|
||||
describe("generation/" + testSuite.title, function() {
|
||||
testSuite.tests.forEach(function(task) {
|
||||
it(
|
||||
task.title,
|
||||
!task.disabled &&
|
||||
function() {
|
||||
const expect = task.expect;
|
||||
const actual = task.actual;
|
||||
const actualCode = actual.code;
|
||||
@ -326,16 +380,21 @@ suites.forEach(function (testSuite) {
|
||||
const result = generate(actualAst, task.options, actualCode);
|
||||
|
||||
if (
|
||||
!expect.code && result.code && fs.statSync(path.dirname(expect.loc)).isDirectory() &&
|
||||
!expect.code &&
|
||||
result.code &&
|
||||
fs.statSync(path.dirname(expect.loc)).isDirectory() &&
|
||||
!process.env.CI
|
||||
) {
|
||||
console.log(`New test file created: ${expect.loc}`);
|
||||
fs.writeFileSync(expect.loc, result.code);
|
||||
} else {
|
||||
chai.expect(result.code).to.be.equal(expect.code, actual.loc + " !== " + expect.loc);
|
||||
chai
|
||||
.expect(result.code)
|
||||
.to.be.equal(expect.code, actual.loc + " !== " + expect.loc);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import type { NodePath } from "babel-traverse";
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function bindifyDecorators(decorators: Array<NodePath>): Array<NodePath> {
|
||||
export default function bindifyDecorators(
|
||||
decorators: Array<NodePath>,
|
||||
): Array<NodePath> {
|
||||
for (const decoratorPath of decorators) {
|
||||
const decorator = decoratorPath.node;
|
||||
const expression = decorator.expression;
|
||||
@ -19,13 +21,15 @@ export default function bindifyDecorators(decorators: Array<NodePath>): Array<No
|
||||
ref = expression.object;
|
||||
}
|
||||
|
||||
nodes.push(t.callExpression(
|
||||
nodes.push(
|
||||
t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(ref, expression.property, expression.computed),
|
||||
t.identifier("bind")
|
||||
t.identifier("bind"),
|
||||
),
|
||||
[ref]
|
||||
));
|
||||
[ref],
|
||||
),
|
||||
);
|
||||
|
||||
if (nodes.length === 1) {
|
||||
decorator.expression = nodes[0];
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
import explode from "babel-helper-explode-assignable-expression";
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function (opts: {
|
||||
build: Function;
|
||||
operator: string;
|
||||
}): Object {
|
||||
export default function(opts: { build: Function, operator: string }): Object {
|
||||
const visitor = {};
|
||||
|
||||
function isAssignment(node) {
|
||||
@ -15,7 +12,7 @@ export default function (opts: {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
}
|
||||
|
||||
visitor.ExpressionStatement = function (path, file) {
|
||||
visitor.ExpressionStatement = function(path, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (path.isCompletionRecord()) return;
|
||||
|
||||
@ -25,24 +22,28 @@ export default function (opts: {
|
||||
const nodes = [];
|
||||
const exploded = explode(expr.left, nodes, file, path.scope, true);
|
||||
|
||||
nodes.push(t.expressionStatement(
|
||||
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right))
|
||||
));
|
||||
nodes.push(
|
||||
t.expressionStatement(
|
||||
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right)),
|
||||
),
|
||||
);
|
||||
|
||||
path.replaceWithMultiple(nodes);
|
||||
};
|
||||
|
||||
visitor.AssignmentExpression = function (path, file) {
|
||||
visitor.AssignmentExpression = function(path, file) {
|
||||
const { node, scope } = path;
|
||||
if (!isAssignment(node)) return;
|
||||
|
||||
const nodes = [];
|
||||
const exploded = explode(node.left, nodes, file, scope);
|
||||
nodes.push(buildAssignment(exploded.ref, opts.build(exploded.uid, node.right)));
|
||||
nodes.push(
|
||||
buildAssignment(exploded.ref, opts.build(exploded.uid, node.right)),
|
||||
);
|
||||
path.replaceWithMultiple(nodes);
|
||||
};
|
||||
|
||||
visitor.BinaryExpression = function (path) {
|
||||
visitor.BinaryExpression = function(path) {
|
||||
const { node } = path;
|
||||
if (node.operator === opts.operator) {
|
||||
path.replaceWith(opts.build(node.left, node.right));
|
||||
|
||||
@ -2,19 +2,21 @@ import esutils from "esutils";
|
||||
import * as t from "babel-types";
|
||||
|
||||
type ElementState = {
|
||||
tagExpr: Object; // tag node
|
||||
tagName: string; // raw string tag name
|
||||
args: Array<Object>; // array of call arguments
|
||||
call?: Object; // optional call property that can be set to override the call expression returned
|
||||
pre?: Function; // function called with (state: ElementState) before building attribs
|
||||
post?: Function; // function called with (state: ElementState) after building attribs
|
||||
tagExpr: Object, // tag node
|
||||
tagName: string, // raw string tag name
|
||||
args: Array<Object>, // array of call arguments
|
||||
call?: Object, // optional call property that can be set to override the call expression returned
|
||||
pre?: Function, // function called with (state: ElementState) before building attribs
|
||||
post?: Function, // function called with (state: ElementState) after building attribs
|
||||
};
|
||||
|
||||
export default function (opts) {
|
||||
export default function(opts) {
|
||||
const visitor = {};
|
||||
|
||||
visitor.JSXNamespacedName = function (path) {
|
||||
throw path.buildCodeFrameError("Namespace tags are not supported. ReactJSX is not XML.");
|
||||
visitor.JSXNamespacedName = function(path) {
|
||||
throw path.buildCodeFrameError(
|
||||
"Namespace tags are not supported. ReactJSX is not XML.",
|
||||
);
|
||||
};
|
||||
|
||||
visitor.JSXElement = {
|
||||
@ -45,7 +47,7 @@ export default function (opts) {
|
||||
} else if (t.isJSXMemberExpression(node)) {
|
||||
return t.memberExpression(
|
||||
convertJSXIdentifier(node.object, node),
|
||||
convertJSXIdentifier(node.property, node)
|
||||
convertJSXIdentifier(node.property, node),
|
||||
);
|
||||
}
|
||||
|
||||
@ -127,7 +129,6 @@ export default function (opts) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The logic for this is quite terse. It's because we need to
|
||||
* support spread elements. We loop over all attributes,
|
||||
@ -141,8 +142,10 @@ export default function (opts) {
|
||||
|
||||
const useBuiltIns = file.opts.useBuiltIns || false;
|
||||
if (typeof useBuiltIns !== "boolean") {
|
||||
throw new Error("transform-react-jsx currently only accepts a boolean option for " +
|
||||
"useBuiltIns (defaults to false)");
|
||||
throw new Error(
|
||||
"transform-react-jsx currently only accepts a boolean option for " +
|
||||
"useBuiltIns (defaults to false)",
|
||||
);
|
||||
}
|
||||
|
||||
while (attribs.length) {
|
||||
@ -166,9 +169,9 @@ export default function (opts) {
|
||||
objs.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
const helper = useBuiltIns ?
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("assign")) :
|
||||
file.addHelper("extends");
|
||||
const helper = useBuiltIns
|
||||
? t.memberExpression(t.identifier("Object"), t.identifier("assign"))
|
||||
: file.addHelper("extends");
|
||||
|
||||
// spread it
|
||||
attribs = t.callExpression(helper, objs);
|
||||
|
||||
@ -18,15 +18,21 @@ const visitor = {
|
||||
},
|
||||
};
|
||||
|
||||
export default function (path: NodePath, scope = path.scope) {
|
||||
export default function(path: NodePath, scope = path.scope) {
|
||||
const { node } = path;
|
||||
const container = t.functionExpression(null, [], node.body, node.generator, node.async);
|
||||
const container = t.functionExpression(
|
||||
null,
|
||||
[],
|
||||
node.body,
|
||||
node.generator,
|
||||
node.async,
|
||||
);
|
||||
|
||||
let callee = container;
|
||||
let args = [];
|
||||
|
||||
// todo: only hoist if necessary
|
||||
hoistVariables(path, (id) => scope.push({ id }));
|
||||
hoistVariables(path, id => scope.push({ id }));
|
||||
|
||||
const state = {
|
||||
foundThis: false,
|
||||
|
||||
@ -12,7 +12,13 @@ function toKind(node: Object) {
|
||||
return "value";
|
||||
}
|
||||
|
||||
export function push(mutatorMap: Object, node: Object, kind: string, file, scope?): Object {
|
||||
export function push(
|
||||
mutatorMap: Object,
|
||||
node: Object,
|
||||
kind: string,
|
||||
file,
|
||||
scope?,
|
||||
): Object {
|
||||
const alias = t.toKeyAlias(node);
|
||||
|
||||
//
|
||||
@ -33,9 +39,11 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
||||
}
|
||||
|
||||
if (node.decorators) {
|
||||
const decorators = map.decorators = map.decorators || t.arrayExpression([]);
|
||||
const decorators = (map.decorators =
|
||||
map.decorators || t.arrayExpression([]));
|
||||
decorators.elements = decorators.elements.concat(
|
||||
node.decorators.map((dec) => dec.expression).reverse());
|
||||
node.decorators.map(dec => dec.expression).reverse(),
|
||||
);
|
||||
}
|
||||
|
||||
if (map.value || map.initializer) {
|
||||
@ -45,14 +53,24 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
||||
let key, value;
|
||||
|
||||
// save the key so we can possibly do function name inferences
|
||||
if (t.isObjectProperty(node) || t.isObjectMethod(node) || t.isClassMethod(node)) {
|
||||
if (
|
||||
t.isObjectProperty(node) ||
|
||||
t.isObjectMethod(node) ||
|
||||
t.isClassMethod(node)
|
||||
) {
|
||||
key = t.toComputedKey(node, node.key);
|
||||
}
|
||||
|
||||
if (t.isObjectProperty(node) || t.isClassProperty(node)) {
|
||||
value = node.value;
|
||||
} else if (t.isObjectMethod(node) || t.isClassMethod(node)) {
|
||||
value = t.functionExpression(null, node.params, node.body, node.generator, node.async);
|
||||
value = t.functionExpression(
|
||||
null,
|
||||
node.params,
|
||||
node.body,
|
||||
node.generator,
|
||||
node.async,
|
||||
);
|
||||
value.returnType = node.returnType;
|
||||
}
|
||||
|
||||
@ -62,8 +80,12 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
||||
}
|
||||
|
||||
// infer function name
|
||||
if (scope && t.isStringLiteral(key) && (kind === "value" || kind === "initializer") &&
|
||||
t.isFunctionExpression(value)) {
|
||||
if (
|
||||
scope &&
|
||||
t.isStringLiteral(key) &&
|
||||
(kind === "value" || kind === "initializer") &&
|
||||
t.isFunctionExpression(value)
|
||||
) {
|
||||
value = nameFunction({ id: key, node: value, scope });
|
||||
}
|
||||
|
||||
@ -90,7 +112,9 @@ export function toComputedObjectFromClass(obj: Object): Object {
|
||||
for (let i = 0; i < obj.properties.length; i++) {
|
||||
const prop = obj.properties[i];
|
||||
const val = prop.value;
|
||||
val.properties.unshift(t.objectProperty(t.identifier("key"), t.toComputedKey(prop)));
|
||||
val.properties.unshift(
|
||||
t.objectProperty(t.identifier("key"), t.toComputedKey(prop)),
|
||||
);
|
||||
objExpr.elements.push(val);
|
||||
}
|
||||
|
||||
@ -100,13 +124,13 @@ export function toComputedObjectFromClass(obj: Object): Object {
|
||||
export function toClassObject(mutatorMap: Object): Object {
|
||||
const objExpr = t.objectExpression([]);
|
||||
|
||||
Object.keys(mutatorMap).forEach(function (mutatorMapKey) {
|
||||
Object.keys(mutatorMap).forEach(function(mutatorMapKey) {
|
||||
const map = mutatorMap[mutatorMapKey];
|
||||
const mapNode = t.objectExpression([]);
|
||||
|
||||
const propNode = t.objectProperty(map._key, mapNode, map._computed);
|
||||
|
||||
Object.keys(map).forEach(function (key) {
|
||||
Object.keys(map).forEach(function(key) {
|
||||
let node = map[key];
|
||||
if (key[0] === "_") return;
|
||||
|
||||
@ -127,7 +151,7 @@ export function toClassObject(mutatorMap: Object): Object {
|
||||
}
|
||||
|
||||
export function toDefineObject(mutatorMap: Object): Object {
|
||||
Object.keys(mutatorMap).forEach(function (key) {
|
||||
Object.keys(mutatorMap).forEach(function(key) {
|
||||
const map = mutatorMap[key];
|
||||
if (map.value) map.writable = t.booleanLiteral(true);
|
||||
map.configurable = t.booleanLiteral(true);
|
||||
|
||||
@ -20,7 +20,7 @@ function getObjRef(node, nodes, file, scope) {
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
ref = node.object;
|
||||
|
||||
if (t.isSuper(ref) || t.isIdentifier(ref) && scope.hasBinding(ref.name)) {
|
||||
if (t.isSuper(ref) || (t.isIdentifier(ref) && scope.hasBinding(ref.name))) {
|
||||
// the object reference that we need to save is locally declared
|
||||
// so as per the previous comment we can be 100% sure evaluating
|
||||
// it multiple times will be safe
|
||||
@ -32,9 +32,7 @@ function getObjRef(node, nodes, file, scope) {
|
||||
}
|
||||
|
||||
const temp = scope.generateUidIdentifierBasedOnNode(ref);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, ref),
|
||||
]));
|
||||
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, ref)]));
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -44,21 +42,19 @@ function getPropRef(node, nodes, file, scope) {
|
||||
if (t.isLiteral(key) && t.isPureish(key)) return key;
|
||||
|
||||
const temp = scope.generateUidIdentifierBasedOnNode(prop);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop),
|
||||
]));
|
||||
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, prop)]));
|
||||
return temp;
|
||||
}
|
||||
|
||||
export default function (
|
||||
export default function(
|
||||
node: Object,
|
||||
nodes: Array<Object>,
|
||||
file,
|
||||
scope: Scope,
|
||||
allowedSingleIdent?: boolean,
|
||||
): {
|
||||
uid: Object;
|
||||
ref: Object;
|
||||
uid: Object,
|
||||
ref: Object,
|
||||
} {
|
||||
let obj;
|
||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||
|
||||
@ -2,7 +2,7 @@ import bindifyDecorators from "babel-helper-bindify-decorators";
|
||||
import type { NodePath } from "babel-traverse";
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function (classPath) {
|
||||
export default function(classPath) {
|
||||
classPath.assertClass();
|
||||
|
||||
const memoisedExpressions = [];
|
||||
@ -44,6 +44,8 @@ export default function (classPath) {
|
||||
}
|
||||
|
||||
if (memoisedExpressions) {
|
||||
classPath.insertBefore(memoisedExpressions.map((expr) => t.expressionStatement(expr)));
|
||||
classPath.insertBefore(
|
||||
memoisedExpressions.map(expr => t.expressionStatement(expr)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,25 +15,25 @@ function humanize(val, noext) {
|
||||
}
|
||||
|
||||
type TestFile = {
|
||||
loc: string;
|
||||
code: string;
|
||||
filename: string;
|
||||
loc: string,
|
||||
code: string,
|
||||
filename: string,
|
||||
};
|
||||
|
||||
type Test = {
|
||||
title: string;
|
||||
disabled: boolean;
|
||||
options: Object;
|
||||
exec: TestFile;
|
||||
actual: TestFile;
|
||||
expected: TestFile;
|
||||
title: string,
|
||||
disabled: boolean,
|
||||
options: Object,
|
||||
exec: TestFile,
|
||||
actual: TestFile,
|
||||
expected: TestFile,
|
||||
};
|
||||
|
||||
type Suite = {
|
||||
options: Object;
|
||||
tests: Array<Test>;
|
||||
title: string;
|
||||
filename: string;
|
||||
options: Object,
|
||||
tests: Array<Test>,
|
||||
title: string,
|
||||
filename: string,
|
||||
};
|
||||
|
||||
function assertDirectory(loc) {
|
||||
@ -50,7 +50,9 @@ function shouldIgnore(name, blacklist?: Array<string>) {
|
||||
const ext = path.extname(name);
|
||||
const base = path.basename(name, ext);
|
||||
|
||||
return name[0] === "." || ext === ".md" || base === "LICENSE" || base === "options";
|
||||
return (
|
||||
name[0] === "." || ext === ".md" || base === "LICENSE" || base === "options"
|
||||
);
|
||||
}
|
||||
|
||||
export default function get(entryLoc): Array<Suite> {
|
||||
@ -133,7 +135,9 @@ export default function get(entryLoc): Array<Suite> {
|
||||
const minimumVersion = semver.clean(taskOpts.minNodeVersion);
|
||||
|
||||
if (minimumVersion == null) {
|
||||
throw new Error(`'minNodeVersion' has invalid semver format: ${taskOpts.minNodeVersion}`);
|
||||
throw new Error(
|
||||
`'minNodeVersion' has invalid semver format: ${taskOpts.minNodeVersion}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (semver.lt(nodeVersion, minimumVersion)) {
|
||||
|
||||
@ -56,7 +56,9 @@ function wrap(state, method, id, scope) {
|
||||
|
||||
// need to add a wrapper since we can't change the references
|
||||
let build = buildPropertyMethodAssignmentWrapper;
|
||||
if (method.generator) build = buildGeneratorPropertyMethodAssignmentWrapper;
|
||||
if (method.generator) {
|
||||
build = buildGeneratorPropertyMethodAssignmentWrapper;
|
||||
}
|
||||
const template = build({
|
||||
FUNCTION: method,
|
||||
FUNCTION_ID: id,
|
||||
@ -125,12 +127,15 @@ function visit(node, name, scope) {
|
||||
return state;
|
||||
}
|
||||
|
||||
export default function ({ node, parent, scope, id }) {
|
||||
export default function({ node, parent, scope, id }) {
|
||||
// has an `id` so we don't need to infer one
|
||||
if (node.id) return;
|
||||
|
||||
if ((t.isObjectProperty(parent) || t.isObjectMethod(parent, { kind: "method" })) &&
|
||||
(!parent.computed || t.isLiteral(parent.key))) {
|
||||
if (
|
||||
(t.isObjectProperty(parent) ||
|
||||
t.isObjectMethod(parent, { kind: "method" })) &&
|
||||
(!parent.computed || t.isLiteral(parent.key))
|
||||
) {
|
||||
// { foo() {} };
|
||||
id = parent.key;
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
@ -139,7 +144,11 @@ export default function ({ node, parent, scope, id }) {
|
||||
|
||||
if (t.isIdentifier(id)) {
|
||||
const binding = scope.parent.getBinding(id.name);
|
||||
if (binding && binding.constant && scope.getBinding(id.name) === binding) {
|
||||
if (
|
||||
binding &&
|
||||
binding.constant &&
|
||||
scope.getBinding(id.name) === binding
|
||||
) {
|
||||
// always going to reference this method
|
||||
node.id = id;
|
||||
node.id[t.NOT_LOCAL_BINDING] = true;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function (node): number {
|
||||
export default function(node): number {
|
||||
const params: Array<Object> = node.params;
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const param = params[i];
|
||||
|
||||
@ -21,9 +21,11 @@ const visitor = {
|
||||
firstId = declar.node.id;
|
||||
|
||||
if (declar.node.init) {
|
||||
nodes.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", declar.node.id, declar.node.init)
|
||||
));
|
||||
nodes.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression("=", declar.node.id, declar.node.init),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for (const name in declar.getBindingIdentifiers()) {
|
||||
@ -40,6 +42,6 @@ const visitor = {
|
||||
},
|
||||
};
|
||||
|
||||
export default function (path, emit: Function, kind: "var" | "let" = "var") {
|
||||
export default function(path, emit: Function, kind: "var" | "let" = "var") {
|
||||
path.traverse(visitor, { kind, emit });
|
||||
}
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function (callee, thisNode, args) {
|
||||
if (args.length === 1 && t.isSpreadElement(args[0]) &&
|
||||
t.isIdentifier(args[0].argument, { name: "arguments" })) {
|
||||
export default function(callee, thisNode, args) {
|
||||
if (
|
||||
args.length === 1 &&
|
||||
t.isSpreadElement(args[0]) &&
|
||||
t.isIdentifier(args[0].argument, { name: "arguments" })
|
||||
) {
|
||||
// eg. super(...arguments);
|
||||
return t.callExpression(
|
||||
t.memberExpression(callee, t.identifier("apply")),
|
||||
[thisNode, args[0].argument]
|
||||
);
|
||||
return t.callExpression(t.memberExpression(callee, t.identifier("apply")), [
|
||||
thisNode,
|
||||
args[0].argument,
|
||||
]);
|
||||
} else {
|
||||
return t.callExpression(
|
||||
t.memberExpression(callee, t.identifier("call")),
|
||||
[thisNode, ...args]
|
||||
);
|
||||
return t.callExpression(t.memberExpression(callee, t.identifier("call")), [
|
||||
thisNode,
|
||||
...args,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import testRunner from "babel-helper-transform-fixture-test-runner";
|
||||
import path from "path";
|
||||
|
||||
export default function (loc) {
|
||||
export default function(loc) {
|
||||
const name = path.basename(path.dirname(loc));
|
||||
testRunner(loc + "/fixtures", name);
|
||||
}
|
||||
|
||||
@ -48,13 +48,17 @@ const forAwaitVisitor = {
|
||||
const callee = path.node.callee;
|
||||
|
||||
// if no await wrapping is being applied, unwrap the call expression
|
||||
if (t.isIdentifier(callee) && callee.name === "AWAIT" && !replacements.AWAIT) {
|
||||
if (
|
||||
t.isIdentifier(callee) &&
|
||||
callee.name === "AWAIT" &&
|
||||
!replacements.AWAIT
|
||||
) {
|
||||
path.replaceWith(path.node.arguments[0]);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default function (path, helpers) {
|
||||
export default function(path, helpers) {
|
||||
const { node, scope, parent } = path;
|
||||
|
||||
const stepKey = scope.generateUidIdentifier("step");
|
||||
@ -64,7 +68,9 @@ export default function (path, helpers) {
|
||||
|
||||
if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
|
||||
// for await (i of test), for await ({ i } of test)
|
||||
declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue));
|
||||
declar = t.expressionStatement(
|
||||
t.assignmentExpression("=", left, stepValue),
|
||||
);
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
// for await (let i of test)
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
@ -76,7 +82,9 @@ export default function (path, helpers) {
|
||||
|
||||
traverse(template, forAwaitVisitor, null, {
|
||||
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
||||
ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
|
||||
ITERATOR_COMPLETION: scope.generateUidIdentifier(
|
||||
"iteratorNormalCompletion",
|
||||
),
|
||||
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
||||
ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
|
||||
GET_ITERATOR: helpers.getAsyncIterator,
|
||||
|
||||
@ -70,7 +70,6 @@ const awaitVisitor = {
|
||||
path.replaceWithMultiple(build.node);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
function classOrObjectMethod(path: NodePath, callId: Object) {
|
||||
@ -79,12 +78,16 @@ function classOrObjectMethod(path: NodePath, callId: Object) {
|
||||
|
||||
node.async = false;
|
||||
|
||||
const container = t.functionExpression(null, [], t.blockStatement(body.body), true);
|
||||
const container = t.functionExpression(
|
||||
null,
|
||||
[],
|
||||
t.blockStatement(body.body),
|
||||
true,
|
||||
);
|
||||
body.body = [
|
||||
t.returnStatement(t.callExpression(
|
||||
t.callExpression(callId, [container]),
|
||||
[]
|
||||
)),
|
||||
t.returnStatement(
|
||||
t.callExpression(t.callExpression(callId, [container]), []),
|
||||
),
|
||||
];
|
||||
|
||||
// Regardless of whether or not the wrapped function is a an async method
|
||||
@ -92,7 +95,9 @@ function classOrObjectMethod(path: NodePath, callId: Object) {
|
||||
node.generator = false;
|
||||
|
||||
// Unwrap the wrapper IIFE's environment so super and this and such still work.
|
||||
path.get("body.body.0.argument.callee.arguments.0").unwrapFunctionEnvironment();
|
||||
path
|
||||
.get("body.body.0.argument.callee.arguments.0")
|
||||
.unwrapFunctionEnvironment();
|
||||
}
|
||||
|
||||
function plainFunction(path: NodePath, callId: Object) {
|
||||
@ -121,25 +126,29 @@ function plainFunction(path: NodePath, callId: Object) {
|
||||
NAME: asyncFnId || null,
|
||||
REF: path.scope.generateUidIdentifier("ref"),
|
||||
FUNCTION: built,
|
||||
PARAMS: node.params.reduce((acc, param) => {
|
||||
acc.done = acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
|
||||
PARAMS: node.params.reduce(
|
||||
(acc, param) => {
|
||||
acc.done =
|
||||
acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
|
||||
|
||||
if (!acc.done) {
|
||||
acc.params.push(path.scope.generateUidIdentifier("x"));
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {
|
||||
},
|
||||
{
|
||||
params: [],
|
||||
done: false,
|
||||
}).params,
|
||||
},
|
||||
).params,
|
||||
}).expression;
|
||||
|
||||
if (isDeclaration) {
|
||||
const declar = t.variableDeclaration("let", [
|
||||
t.variableDeclarator(
|
||||
t.identifier(asyncFnId.name),
|
||||
t.callExpression(container, [])
|
||||
t.callExpression(container, []),
|
||||
),
|
||||
]);
|
||||
declar._blockHoist = true;
|
||||
@ -149,14 +158,12 @@ function plainFunction(path: NodePath, callId: Object) {
|
||||
// the identifier into an expressionStatement
|
||||
path.parentPath.insertBefore(declar);
|
||||
path.parentPath.replaceWith(
|
||||
t.exportNamedDeclaration(null,
|
||||
[
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(
|
||||
t.identifier(asyncFnId.name),
|
||||
t.identifier("default")
|
||||
t.identifier("default"),
|
||||
),
|
||||
]
|
||||
)
|
||||
]),
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -182,7 +189,7 @@ function plainFunction(path: NodePath, callId: Object) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function (path: NodePath, file: Object, helpers: Object) {
|
||||
export default function(path: NodePath, file: Object, helpers: Object) {
|
||||
if (!helpers) {
|
||||
// bc for 6.15 and earlier
|
||||
helpers = { wrapAsync: file };
|
||||
|
||||
@ -30,16 +30,19 @@ function isMemberExpressionSuper(node) {
|
||||
* CLASS.prototype.__proto__ || Object.getPrototypeOf(CLASS.prototype)
|
||||
*/
|
||||
function getPrototypeOfExpression(objectRef, isStatic) {
|
||||
const targetRef = isStatic ? objectRef : t.memberExpression(objectRef, t.identifier("prototype"));
|
||||
const targetRef = isStatic
|
||||
? objectRef
|
||||
: t.memberExpression(objectRef, t.identifier("prototype"));
|
||||
|
||||
return t.logicalExpression(
|
||||
"||",
|
||||
t.memberExpression(targetRef, t.identifier("__proto__")),
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
targetRef,
|
||||
]
|
||||
t.memberExpression(
|
||||
t.identifier("Object"),
|
||||
t.identifier("getPrototypeOf"),
|
||||
),
|
||||
[targetRef],
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -119,14 +122,14 @@ export default class ReplaceSupers {
|
||||
scope: Scope;
|
||||
file;
|
||||
opts: {
|
||||
forceSuperMemoisation: boolean;
|
||||
getObjetRef: Function;
|
||||
methodPath: NodePath;
|
||||
methodNode: Object;
|
||||
superRef: Object;
|
||||
isStatic: boolean;
|
||||
isLoose: boolean;
|
||||
file: any;
|
||||
forceSuperMemoisation: boolean,
|
||||
getObjetRef: Function,
|
||||
methodPath: NodePath,
|
||||
methodNode: Object,
|
||||
superRef: Object,
|
||||
isStatic: boolean,
|
||||
isLoose: boolean,
|
||||
file: any,
|
||||
};
|
||||
|
||||
getObjectRef() {
|
||||
@ -143,16 +146,17 @@ export default class ReplaceSupers {
|
||||
*
|
||||
*/
|
||||
|
||||
setSuperProperty(property: Object, value: Object, isComputed: boolean): Object {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("set"),
|
||||
[
|
||||
setSuperProperty(
|
||||
property: Object,
|
||||
value: Object,
|
||||
isComputed: boolean,
|
||||
): Object {
|
||||
return t.callExpression(this.file.addHelper("set"), [
|
||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
||||
isComputed ? property : t.stringLiteral(property.name),
|
||||
value,
|
||||
t.thisExpression(),
|
||||
]
|
||||
);
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,14 +169,11 @@ export default class ReplaceSupers {
|
||||
*/
|
||||
|
||||
getSuperProperty(property: Object, isComputed: boolean): Object {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("get"),
|
||||
[
|
||||
return t.callExpression(this.file.addHelper("get"), [
|
||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
||||
isComputed ? property : t.stringLiteral(property.name),
|
||||
t.thisExpression(),
|
||||
]
|
||||
);
|
||||
]);
|
||||
}
|
||||
|
||||
replace() {
|
||||
@ -214,16 +215,23 @@ export default class ReplaceSupers {
|
||||
specHandleAssignmentExpression(ref, path, node) {
|
||||
if (node.operator === "=") {
|
||||
// super.name = "val"; -> _set(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
||||
return this.setSuperProperty(node.left.property, node.right, node.left.computed);
|
||||
return this.setSuperProperty(
|
||||
node.left.property,
|
||||
node.right,
|
||||
node.left.computed,
|
||||
);
|
||||
} else {
|
||||
// super.age += 2; -> let _ref = super.age; super.age = _ref + 2;
|
||||
ref = ref || path.scope.generateUidIdentifier("ref");
|
||||
return [
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, node.left),
|
||||
]),
|
||||
t.expressionStatement(t.assignmentExpression("=", node.left,
|
||||
t.binaryExpression(node.operator.slice(0, -1), ref, node.right))),
|
||||
t.variableDeclaration("var", [t.variableDeclarator(ref, node.left)]),
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
node.left,
|
||||
t.binaryExpression(node.operator.slice(0, -1), ref, node.right),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -258,8 +266,15 @@ export default class ReplaceSupers {
|
||||
// _get(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
||||
property = node.property;
|
||||
computed = node.computed;
|
||||
} else if (t.isUpdateExpression(node) && isMemberExpressionSuper(node.argument)) {
|
||||
const binary = t.assignmentExpression(node.operator[0] + "=", node.argument, t.numericLiteral(1));
|
||||
} else if (
|
||||
t.isUpdateExpression(node) &&
|
||||
isMemberExpressionSuper(node.argument)
|
||||
) {
|
||||
const binary = t.assignmentExpression(
|
||||
node.operator[0] + "=",
|
||||
node.argument,
|
||||
t.numericLiteral(1),
|
||||
);
|
||||
if (node.prefix) {
|
||||
// ++super.foo;
|
||||
// to
|
||||
@ -270,9 +285,14 @@ export default class ReplaceSupers {
|
||||
// to
|
||||
// let _ref = super.foo; super.foo = _ref + 1;
|
||||
const ref = path.scope.generateUidIdentifier("ref");
|
||||
return this.specHandleAssignmentExpression(ref, path, binary).concat(t.expressionStatement(ref));
|
||||
return this.specHandleAssignmentExpression(ref, path, binary).concat(
|
||||
t.expressionStatement(ref),
|
||||
);
|
||||
}
|
||||
} else if (t.isAssignmentExpression(node) && isMemberExpressionSuper(node.left)) {
|
||||
} else if (
|
||||
t.isAssignmentExpression(node) &&
|
||||
isMemberExpressionSuper(node.left)
|
||||
) {
|
||||
return this.specHandleAssignmentExpression(null, path, node);
|
||||
}
|
||||
|
||||
|
||||
@ -4,13 +4,9 @@ export function assertNoOwnProperties(obj) {
|
||||
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
|
||||
}
|
||||
|
||||
export function assertHasOwnProperty() {
|
||||
export function assertHasOwnProperty() {}
|
||||
|
||||
}
|
||||
|
||||
export function assertLacksOwnProperty() {
|
||||
|
||||
}
|
||||
export function assertLacksOwnProperty() {}
|
||||
|
||||
export function multiline(arr) {
|
||||
return arr.join("\n");
|
||||
|
||||
@ -38,7 +38,9 @@ runCodeInTestContext(buildExternalHelpers());
|
||||
* This allows us to run our unittests
|
||||
*/
|
||||
function runModuleInTestContext(id: string, relativeFilename: string) {
|
||||
const filename = resolve.sync(id, { basedir: path.dirname(relativeFilename) });
|
||||
const filename = resolve.sync(id, {
|
||||
basedir: path.dirname(relativeFilename),
|
||||
});
|
||||
|
||||
// Expose Node-internal modules if the tests want them. Note, this will not execute inside
|
||||
// the context's global scope.
|
||||
@ -46,20 +48,22 @@ function runModuleInTestContext(id: string, relativeFilename: string) {
|
||||
|
||||
if (moduleCache[filename]) return moduleCache[filename].exports;
|
||||
|
||||
const module = moduleCache[filename] = {
|
||||
const module = (moduleCache[filename] = {
|
||||
id: filename,
|
||||
exports: {},
|
||||
};
|
||||
});
|
||||
const dirname = path.dirname(filename);
|
||||
const req = (id) => runModuleInTestContext(id, filename);
|
||||
const req = id => runModuleInTestContext(id, filename);
|
||||
|
||||
const src = fs.readFileSync(filename, "utf8");
|
||||
const code = `(function (exports, require, module, __filename, __dirname) {${src}\n});`;
|
||||
|
||||
vm.runInContext(code, testContext, {
|
||||
vm
|
||||
.runInContext(code, testContext, {
|
||||
filename,
|
||||
displayErrors: true,
|
||||
}).call(module.exports, module.exports, req, module, filename, dirname);
|
||||
})
|
||||
.call(module.exports, module.exports, req, module, filename, dirname);
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
@ -69,10 +73,13 @@ function runModuleInTestContext(id: string, relativeFilename: string) {
|
||||
*
|
||||
* Exposed for unit tests, not for use as an API.
|
||||
*/
|
||||
export function runCodeInTestContext(code: string, opts: {filename?: string} = {}) {
|
||||
export function runCodeInTestContext(
|
||||
code: string,
|
||||
opts: { filename?: string } = {},
|
||||
) {
|
||||
const filename = opts.filename || null;
|
||||
const dirname = filename ? path.dirname(filename) : null;
|
||||
const req = filename ? ((id) => runModuleInTestContext(id, filename)) : null;
|
||||
const req = filename ? id => runModuleInTestContext(id, filename) : null;
|
||||
|
||||
const module = {
|
||||
id: filename,
|
||||
@ -90,21 +97,21 @@ export function runCodeInTestContext(code: string, opts: {filename?: string} = {
|
||||
}
|
||||
|
||||
function wrapPackagesArray(type, names, optionsDir) {
|
||||
return (names || []).map(function (val) {
|
||||
return (names || []).map(function(val) {
|
||||
if (typeof val === "string") val = [val];
|
||||
|
||||
// relative path (outside of monorepo)
|
||||
if (val[0][0] === ".") {
|
||||
|
||||
if (!optionsDir) {
|
||||
throw new Error("Please provide an options.json in test dir when using a " +
|
||||
"relative plugin path.");
|
||||
throw new Error(
|
||||
"Please provide an options.json in test dir when using a " +
|
||||
"relative plugin path.",
|
||||
);
|
||||
}
|
||||
|
||||
val[0] = path.resolve(optionsDir, val[0]);
|
||||
}
|
||||
} else {
|
||||
// check node_modules/babel-x-y
|
||||
else {
|
||||
val[0] = __dirname + "/../../babel-" + type + "-" + val[0];
|
||||
}
|
||||
|
||||
@ -120,15 +127,25 @@ function run(task) {
|
||||
const optionsDir = task.optionsDir;
|
||||
|
||||
function getOpts(self) {
|
||||
const newOpts = merge({
|
||||
const newOpts = merge(
|
||||
{
|
||||
filename: self.loc,
|
||||
}, opts);
|
||||
},
|
||||
opts,
|
||||
);
|
||||
|
||||
newOpts.plugins = wrapPackagesArray("plugin", newOpts.plugins, optionsDir);
|
||||
newOpts.presets = wrapPackagesArray("preset", newOpts.presets, optionsDir).map(function (val) {
|
||||
newOpts.presets = wrapPackagesArray(
|
||||
"preset",
|
||||
newOpts.presets,
|
||||
optionsDir,
|
||||
).map(function(val) {
|
||||
if (val.length > 2) {
|
||||
throw new Error("Unexpected extra options " + JSON.stringify(val.slice(2)) +
|
||||
" passed to preset.");
|
||||
throw new Error(
|
||||
"Unexpected extra options " +
|
||||
JSON.stringify(val.slice(2)) +
|
||||
" passed to preset.",
|
||||
);
|
||||
}
|
||||
|
||||
return val;
|
||||
@ -160,14 +177,19 @@ function run(task) {
|
||||
if (!execCode || actualCode) {
|
||||
result = babel.transform(actualCode, getOpts(actual));
|
||||
if (
|
||||
!expect.code && result.code && !opts.throws && fs.statSync(path.dirname(expect.loc)).isDirectory() &&
|
||||
!expect.code &&
|
||||
result.code &&
|
||||
!opts.throws &&
|
||||
fs.statSync(path.dirname(expect.loc)).isDirectory() &&
|
||||
!process.env.CI
|
||||
) {
|
||||
console.log(`New test file created: ${expect.loc}`);
|
||||
fs.writeFileSync(expect.loc, result.code);
|
||||
} else {
|
||||
actualCode = result.code.trim();
|
||||
chai.expect(actualCode).to.be.equal(expectCode, actual.loc + " !== " + expect.loc);
|
||||
chai
|
||||
.expect(actualCode)
|
||||
.to.be.equal(expectCode, actual.loc + " !== " + expect.loc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,11 +200,13 @@ function run(task) {
|
||||
if (task.sourceMappings) {
|
||||
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
|
||||
task.sourceMappings.forEach(function (mapping) {
|
||||
task.sourceMappings.forEach(function(mapping) {
|
||||
const actual = mapping.original;
|
||||
|
||||
const expect = consumer.originalPositionFor(mapping.generated);
|
||||
chai.expect({ line: expect.line, column: expect.column }).to.deep.equal(actual);
|
||||
chai
|
||||
.expect({ line: expect.line, column: expect.column })
|
||||
.to.deep.equal(actual);
|
||||
});
|
||||
}
|
||||
|
||||
@ -191,7 +215,7 @@ function run(task) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function (
|
||||
export default function(
|
||||
fixturesLoc: string,
|
||||
name: string,
|
||||
suiteOpts = {},
|
||||
@ -203,12 +227,19 @@ export default function (
|
||||
for (const testSuite of suites) {
|
||||
if (includes(suiteOpts.ignoreSuites, testSuite.title)) continue;
|
||||
|
||||
describe(name + "/" + testSuite.title, function () {
|
||||
describe(name + "/" + testSuite.title, function() {
|
||||
for (const task of testSuite.tests) {
|
||||
if (includes(suiteOpts.ignoreTasks, task.title) ||
|
||||
includes(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)) continue;
|
||||
if (
|
||||
includes(suiteOpts.ignoreTasks, task.title) ||
|
||||
includes(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
it(task.title, !task.disabled && function () {
|
||||
it(
|
||||
task.title,
|
||||
!task.disabled &&
|
||||
function() {
|
||||
function runTask() {
|
||||
run(task);
|
||||
}
|
||||
@ -232,8 +263,10 @@ export default function (
|
||||
// the options object with useless options
|
||||
delete task.options.throws;
|
||||
|
||||
assert.throws(runTask, function (err) {
|
||||
return throwMsg === true || err.message.indexOf(throwMsg) >= 0;
|
||||
assert.throws(runTask, function(err) {
|
||||
return (
|
||||
throwMsg === true || err.message.indexOf(throwMsg) >= 0
|
||||
);
|
||||
});
|
||||
} else {
|
||||
if (task.exec.code) {
|
||||
@ -245,7 +278,8 @@ export default function (
|
||||
runTask();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -359,7 +359,6 @@ helpers.get = template(`
|
||||
});
|
||||
`);
|
||||
|
||||
|
||||
helpers.inherits = template(`
|
||||
(function (subClass, superClass) {
|
||||
if (typeof superClass !== "function" && superClass !== null) {
|
||||
@ -395,7 +394,6 @@ helpers.instanceof = template(`
|
||||
});
|
||||
`);
|
||||
|
||||
|
||||
helpers.interopRequireDefault = template(`
|
||||
(function (obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
|
||||
@ -8,7 +8,7 @@ export function get(name) {
|
||||
}
|
||||
|
||||
export const list = Object.keys(helpers)
|
||||
.map((name) => name.replace(/^_/, ""))
|
||||
.filter((name) => name !== "__esModule");
|
||||
.map(name => name.replace(/^_/, ""))
|
||||
.filter(name => name !== "__esModule");
|
||||
|
||||
export default get;
|
||||
|
||||
@ -8,38 +8,55 @@ import * as util from "util";
|
||||
*/
|
||||
|
||||
export const MESSAGES = {
|
||||
tailCallReassignmentDeopt: "Function reference has been reassigned, so it will probably be dereferenced, therefore we can't optimise this with confidence",
|
||||
tailCallReassignmentDeopt:
|
||||
"Function reference has been reassigned, so it will probably be dereferenced, therefore we can't optimise this with confidence",
|
||||
classesIllegalBareSuper: "Illegal use of bare super",
|
||||
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||
classesIllegalSuperCall:
|
||||
"Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
||||
settersNoRest: "Setters aren't allowed to have a rest",
|
||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemberExpression or Identifier",
|
||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
||||
expectedMemberExpressionOrIdentifier:
|
||||
"Expected type MemberExpression or Identifier",
|
||||
invalidParentForThisNode:
|
||||
"We don't know how to handle this node within the current parent - please open an issue",
|
||||
readOnly: "$1 is read-only",
|
||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||
didYouMean: "Did you mean $1?",
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
||||
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
||||
codeGeneratorDeopt:
|
||||
"Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
||||
missingTemplatesDirectory:
|
||||
"no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
||||
unsupportedOutputType: "Unsupported output type $1",
|
||||
illegalMethodName: "Illegal method name $1",
|
||||
lostTrackNodePath: "We lost track of this node's position, likely because the AST was directly manipulated",
|
||||
lostTrackNodePath:
|
||||
"We lost track of this node's position, likely because the AST was directly manipulated",
|
||||
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
modulesDuplicateDeclarations: "Duplicate module declarations with the same source but in different scopes",
|
||||
modulesDuplicateDeclarations:
|
||||
"Duplicate module declarations with the same source but in different scopes",
|
||||
|
||||
undeclaredVariable: "Reference to undeclared variable $1",
|
||||
undeclaredVariableType: "Referencing a type alias outside of a type annotation",
|
||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
||||
undeclaredVariableType:
|
||||
"Referencing a type alias outside of a type annotation",
|
||||
undeclaredVariableSuggestion:
|
||||
"Reference to undeclared variable $1 - did you mean $2?",
|
||||
|
||||
traverseNeedsParent: "You must pass a scope and parentPath unless traversing a Program/File. Instead of that you tried to traverse a $1 node without passing scope and parentPath.",
|
||||
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
|
||||
traverseNeedsParent:
|
||||
"You must pass a scope and parentPath unless traversing a Program/File. Instead of that you tried to traverse a $1 node without passing scope and parentPath.",
|
||||
traverseVerifyRootFunction:
|
||||
"You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
||||
traverseVerifyVisitorProperty:
|
||||
"You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
traverseVerifyNodeType:
|
||||
"You gave us a visitor for the node type $1 but it's not a valid type",
|
||||
|
||||
pluginNotObject: "Plugin $2 specified in $1 was expected to return an object when invoked but returned $3",
|
||||
pluginNotFunction: "Plugin $2 specified in $1 was expected to return a function but returned $3",
|
||||
pluginUnknown: "Unknown plugin $1 specified in $2 at $3, attempted to resolve relative to $4",
|
||||
pluginNotObject:
|
||||
"Plugin $2 specified in $1 was expected to return an object when invoked but returned $3",
|
||||
pluginNotFunction:
|
||||
"Plugin $2 specified in $1 was expected to return a function but returned $3",
|
||||
pluginUnknown:
|
||||
"Unknown plugin $1 specified in $2 at $3, attempted to resolve relative to $4",
|
||||
pluginInvalidProperty: "Plugin $1 provided an invalid property of $2",
|
||||
};
|
||||
|
||||
@ -55,7 +72,7 @@ export function get(key: string, ...args: Array<any>): string {
|
||||
args = parseArgs(args);
|
||||
|
||||
// replace $0 placeholders with args
|
||||
return msg.replace(/\$(\d+)/g, function (str, i) {
|
||||
return msg.replace(/\$(\d+)/g, function(str, i) {
|
||||
return args[i - 1];
|
||||
});
|
||||
}
|
||||
@ -65,7 +82,7 @@ export function get(key: string, ...args: Array<any>): string {
|
||||
*/
|
||||
|
||||
export function parseArgs(args: Array<any>): Array<string> {
|
||||
return args.map(function (val) {
|
||||
return args.map(function(val) {
|
||||
if (val != null && val.inspect) {
|
||||
return val.inspect();
|
||||
} else {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function ({ messages }) {
|
||||
export default function({ messages }) {
|
||||
return {
|
||||
visitor: {
|
||||
Scope({ scope }) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function ({ types: t }) {
|
||||
export default function({ types: t }) {
|
||||
return {
|
||||
pre(file) {
|
||||
file.set("helpersNamespace", t.identifier("babelHelpers"));
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("asyncFunctions");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("asyncGenerators");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("classProperties");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("decorators");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("doExpressions");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("dynamicImport");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("exponentiationOperator");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("exportExtensions");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("flow");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("functionBind");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("functionSent");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("jsx");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("numericSeparator");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("objectRestSpread");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("optionalChaining");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
manipulateOptions(opts, parserOpts) {
|
||||
parserOpts.plugins.push("trailingFunctionCommas");
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import asyncSyntaxPlugin from "babel-plugin-syntax-async-functions";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
inherits: asyncSyntaxPlugin,
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import remapAsyncToGenerator from "babel-helper-remap-async-to-generator";
|
||||
import syntaxAsyncGenerators from "babel-plugin-syntax-async-generators";
|
||||
|
||||
export default function ({ types: t }) {
|
||||
export default function({ types: t }) {
|
||||
const yieldStarVisitor = {
|
||||
Function(path) {
|
||||
path.skip();
|
||||
@ -12,7 +12,10 @@ export default function ({ types: t }) {
|
||||
const callee = state.addHelper("asyncGeneratorDelegate");
|
||||
node.argument = t.callExpression(callee, [
|
||||
t.callExpression(state.addHelper("asyncIterator"), [node.argument]),
|
||||
t.memberExpression(state.addHelper("asyncGenerator"), t.identifier("await")),
|
||||
t.memberExpression(
|
||||
state.addHelper("asyncGenerator"),
|
||||
t.identifier("await"),
|
||||
),
|
||||
]);
|
||||
},
|
||||
};
|
||||
@ -27,9 +30,13 @@ export default function ({ types: t }) {
|
||||
|
||||
remapAsyncToGenerator(path, state.file, {
|
||||
wrapAsync: t.memberExpression(
|
||||
state.addHelper("asyncGenerator"), t.identifier("wrap")),
|
||||
state.addHelper("asyncGenerator"),
|
||||
t.identifier("wrap"),
|
||||
),
|
||||
wrapAwait: t.memberExpression(
|
||||
state.addHelper("asyncGenerator"), t.identifier("await")),
|
||||
state.addHelper("asyncGenerator"),
|
||||
t.identifier("await"),
|
||||
),
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import remapAsyncToGenerator from "babel-helper-remap-async-to-generator";
|
||||
import syntaxAsyncFunctions from "babel-plugin-syntax-async-functions";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
inherits: syntaxAsyncFunctions,
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import remapAsyncToGenerator from "babel-helper-remap-async-to-generator";
|
||||
import syntaxAsyncFunctions from "babel-plugin-syntax-async-functions";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
inherits: syntaxAsyncFunctions,
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import nameFunction from "babel-helper-function-name";
|
||||
import template from "babel-template";
|
||||
import syntaxClassProperties from "babel-plugin-syntax-class-properties";
|
||||
|
||||
export default function ({ types: t }) {
|
||||
export default function({ types: t }) {
|
||||
const findBareSupers = {
|
||||
Super(path) {
|
||||
if (path.parentPath.isCallExpression({ callee: path.node })) {
|
||||
@ -29,14 +29,20 @@ export default function ({ types: t }) {
|
||||
});
|
||||
`);
|
||||
|
||||
const buildClassPropertySpec = (ref, { key, value, computed }) => buildObjectDefineProperty({
|
||||
const buildClassPropertySpec = (ref, { key, value, computed }) =>
|
||||
buildObjectDefineProperty({
|
||||
REF: ref,
|
||||
KEY: (t.isIdentifier(key) && !computed) ? t.stringLiteral(key.name) : key,
|
||||
KEY: t.isIdentifier(key) && !computed ? t.stringLiteral(key.name) : key,
|
||||
VALUE: value ? value : t.identifier("undefined"),
|
||||
});
|
||||
|
||||
const buildClassPropertyNonSpec = (ref, { key, value, computed }) => t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(ref, key, computed || t.isLiteral(key)), value)
|
||||
const buildClassPropertyNonSpec = (ref, { key, value, computed }) =>
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(ref, key, computed || t.isLiteral(key)),
|
||||
value,
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
@ -44,8 +50,9 @@ export default function ({ types: t }) {
|
||||
|
||||
visitor: {
|
||||
Class(path, state) {
|
||||
const buildClassProperty = state.opts.spec ? buildClassPropertySpec :
|
||||
buildClassPropertyNonSpec;
|
||||
const buildClassProperty = state.opts.spec
|
||||
? buildClassPropertySpec
|
||||
: buildClassPropertyNonSpec;
|
||||
const isDerived = !!path.node.superClass;
|
||||
let constructor;
|
||||
const props = [];
|
||||
@ -67,7 +74,8 @@ export default function ({ types: t }) {
|
||||
if (path.isClassExpression() || !path.node.id) {
|
||||
nameFunction(path);
|
||||
ref = path.scope.generateUidIdentifier("class");
|
||||
} else { // path.isClassDeclaration() && path.node.id
|
||||
} else {
|
||||
// path.isClassDeclaration() && path.node.id
|
||||
ref = path.node.id;
|
||||
}
|
||||
|
||||
@ -93,17 +101,20 @@ export default function ({ types: t }) {
|
||||
|
||||
if (instanceBody.length) {
|
||||
if (!constructor) {
|
||||
const newConstructor = t.classMethod("constructor", t.identifier("constructor"), [],
|
||||
t.blockStatement([]));
|
||||
const newConstructor = t.classMethod(
|
||||
"constructor",
|
||||
t.identifier("constructor"),
|
||||
[],
|
||||
t.blockStatement([]),
|
||||
);
|
||||
if (isDerived) {
|
||||
newConstructor.params = [t.restElement(t.identifier("args"))];
|
||||
newConstructor.body.body.push(
|
||||
t.returnStatement(
|
||||
t.callExpression(
|
||||
t.super(),
|
||||
[t.spreadElement(t.identifier("args"))]
|
||||
)
|
||||
)
|
||||
t.callExpression(t.super(), [
|
||||
t.spreadElement(t.identifier("args")),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
[constructor] = body.unshiftContainer("body", newConstructor);
|
||||
@ -120,19 +131,29 @@ export default function ({ types: t }) {
|
||||
}
|
||||
|
||||
if (collisionState.collision) {
|
||||
const initialisePropsRef = path.scope.generateUidIdentifier("initialiseProps");
|
||||
const initialisePropsRef = path.scope.generateUidIdentifier(
|
||||
"initialiseProps",
|
||||
);
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
nodes.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
initialisePropsRef,
|
||||
t.functionExpression(null, [], t.blockStatement(instanceBody))
|
||||
t.functionExpression(
|
||||
null,
|
||||
[],
|
||||
t.blockStatement(instanceBody),
|
||||
),
|
||||
]));
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
instanceBody = [
|
||||
t.expressionStatement(
|
||||
t.callExpression(t.memberExpression(initialisePropsRef, t.identifier("call")), [
|
||||
t.thisExpression()])
|
||||
t.callExpression(
|
||||
t.memberExpression(initialisePropsRef, t.identifier("call")),
|
||||
[t.thisExpression()],
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
@ -159,7 +180,8 @@ export default function ({ types: t }) {
|
||||
if (path.isClassExpression()) {
|
||||
path.scope.push({ id: ref });
|
||||
path.replaceWith(t.assignmentExpression("=", ref, path.node));
|
||||
} else { // path.isClassDeclaration()
|
||||
} else {
|
||||
// path.isClassDeclaration()
|
||||
if (!path.node.id) {
|
||||
path.node.id = ref;
|
||||
}
|
||||
@ -177,7 +199,7 @@ export default function ({ types: t }) {
|
||||
|
||||
const body = classExp.get("body");
|
||||
const members = body.get("body");
|
||||
if (members.some((member) => member.isClassProperty())) {
|
||||
if (members.some(member => member.isClassProperty())) {
|
||||
path.ensureBlock();
|
||||
}
|
||||
},
|
||||
|
||||
@ -15,7 +15,6 @@ const buildGetDescriptor = template(`
|
||||
Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
|
||||
`);
|
||||
|
||||
|
||||
const buildGetObjectInitializer = template(`
|
||||
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
|
||||
enumerable: true,
|
||||
@ -88,7 +87,9 @@ export default function({ types: t }) {
|
||||
*/
|
||||
function ensureApplyDecoratedDescriptorHelper(path, state) {
|
||||
if (!state.applyDecoratedDescriptor) {
|
||||
state.applyDecoratedDescriptor = path.scope.generateUidIdentifier("applyDecoratedDescriptor");
|
||||
state.applyDecoratedDescriptor = path.scope.generateUidIdentifier(
|
||||
"applyDecoratedDescriptor",
|
||||
);
|
||||
const helper = buildApplyDecoratedDescriptor({
|
||||
NAME: state.applyDecoratedDescriptor,
|
||||
});
|
||||
@ -103,7 +104,9 @@ export default function({ types: t }) {
|
||||
*/
|
||||
function ensureInitializerDefineProp(path, state) {
|
||||
if (!state.initializerDefineProp) {
|
||||
state.initializerDefineProp = path.scope.generateUidIdentifier("initDefineProp");
|
||||
state.initializerDefineProp = path.scope.generateUidIdentifier(
|
||||
"initDefineProp",
|
||||
);
|
||||
const helper = buildInitializerDefineProperty({
|
||||
NAME: state.initializerDefineProp,
|
||||
});
|
||||
@ -119,7 +122,9 @@ export default function({ types: t }) {
|
||||
*/
|
||||
function ensureInitializerWarning(path, state) {
|
||||
if (!state.initializerWarningHelper) {
|
||||
state.initializerWarningHelper = path.scope.generateUidIdentifier("initializerWarningHelper");
|
||||
state.initializerWarningHelper = path.scope.generateUidIdentifier(
|
||||
"initializerWarningHelper",
|
||||
);
|
||||
const helper = buildInitializerWarningHelper({
|
||||
NAME: state.initializerWarningHelper,
|
||||
});
|
||||
@ -135,20 +140,29 @@ export default function({ types: t }) {
|
||||
*/
|
||||
function applyEnsureOrdering(path) {
|
||||
// TODO: This should probably also hoist computed properties.
|
||||
const decorators = (
|
||||
path.isClass()
|
||||
const decorators = (path.isClass()
|
||||
? [path].concat(path.get("body.body"))
|
||||
: path.get("properties")
|
||||
).reduce((acc, prop) => acc.concat(prop.node.decorators || []), []);
|
||||
: path.get("properties")).reduce(
|
||||
(acc, prop) => acc.concat(prop.node.decorators || []),
|
||||
[],
|
||||
);
|
||||
|
||||
const identDecorators = decorators.filter((decorator) => !t.isIdentifier(decorator.expression));
|
||||
const identDecorators = decorators.filter(
|
||||
decorator => !t.isIdentifier(decorator.expression),
|
||||
);
|
||||
if (identDecorators.length === 0) return;
|
||||
|
||||
return t.sequenceExpression(identDecorators.map((decorator) => {
|
||||
return t.sequenceExpression(
|
||||
identDecorators
|
||||
.map(decorator => {
|
||||
const expression = decorator.expression;
|
||||
const id = decorator.expression = path.scope.generateDeclaredUidIdentifier("dec");
|
||||
const id = (decorator.expression = path.scope.generateDeclaredUidIdentifier(
|
||||
"dec",
|
||||
));
|
||||
return t.assignmentExpression("=", id, expression);
|
||||
}).concat([path.node]));
|
||||
})
|
||||
.concat([path.node]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +178,7 @@ export default function({ types: t }) {
|
||||
const name = classPath.scope.generateDeclaredUidIdentifier("class");
|
||||
|
||||
return decorators
|
||||
.map((dec) => dec.expression)
|
||||
.map(dec => dec.expression)
|
||||
.reverse()
|
||||
.reduce(function(acc, decorator) {
|
||||
return buildClassDecorator({
|
||||
@ -207,7 +221,9 @@ export default function({ types: t }) {
|
||||
* A helper to pull out property decorators into a sequence expression.
|
||||
*/
|
||||
function applyTargetDecorators(path, state, decoratedProps) {
|
||||
const name = path.scope.generateDeclaredUidIdentifier(path.isClass() ? "class" : "obj");
|
||||
const name = path.scope.generateDeclaredUidIdentifier(
|
||||
path.isClass() ? "class" : "obj",
|
||||
);
|
||||
|
||||
const exprs = decoratedProps.reduce(function(acc, node) {
|
||||
const decorators = node.decorators || [];
|
||||
@ -216,36 +232,58 @@ export default function({ types: t }) {
|
||||
if (decorators.length === 0) return acc;
|
||||
|
||||
if (node.computed) {
|
||||
throw path.buildCodeFrameError("Computed method/property decorators are not yet supported.");
|
||||
throw path.buildCodeFrameError(
|
||||
"Computed method/property decorators are not yet supported.",
|
||||
);
|
||||
}
|
||||
|
||||
const property = t.isLiteral(node.key) ? node.key : t.stringLiteral(node.key.name);
|
||||
const property = t.isLiteral(node.key)
|
||||
? node.key
|
||||
: t.stringLiteral(node.key.name);
|
||||
|
||||
const target = (path.isClass() && !node.static) ? buildClassPrototype({
|
||||
const target =
|
||||
path.isClass() && !node.static
|
||||
? buildClassPrototype({
|
||||
CLASS_REF: name,
|
||||
}).expression : name;
|
||||
}).expression
|
||||
: name;
|
||||
|
||||
if (t.isClassProperty(node, { static: false })) {
|
||||
const descriptor = path.scope.generateDeclaredUidIdentifier("descriptor");
|
||||
|
||||
const initializer = node.value ?
|
||||
t.functionExpression(null, [], t.blockStatement([t.returnStatement(node.value)])) :
|
||||
t.nullLiteral();
|
||||
node.value = t.callExpression(
|
||||
ensureInitializerWarning(path, state), [descriptor, t.thisExpression()]
|
||||
const descriptor = path.scope.generateDeclaredUidIdentifier(
|
||||
"descriptor",
|
||||
);
|
||||
|
||||
const initializer = node.value
|
||||
? t.functionExpression(
|
||||
null,
|
||||
[],
|
||||
t.blockStatement([t.returnStatement(node.value)]),
|
||||
)
|
||||
: t.nullLiteral();
|
||||
node.value = t.callExpression(ensureInitializerWarning(path, state), [
|
||||
descriptor,
|
||||
t.thisExpression(),
|
||||
]);
|
||||
|
||||
acc = acc.concat([
|
||||
t.assignmentExpression(
|
||||
"=", descriptor, t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
|
||||
"=",
|
||||
descriptor,
|
||||
t.callExpression(
|
||||
ensureApplyDecoratedDescriptorHelper(path, state),
|
||||
[
|
||||
target,
|
||||
property,
|
||||
t.arrayExpression(decorators.map((dec) => dec.expression)),
|
||||
t.arrayExpression(decorators.map(dec => dec.expression)),
|
||||
t.objectExpression([
|
||||
t.objectProperty(t.identifier("enumerable"), t.booleanLiteral(true)),
|
||||
t.objectProperty(
|
||||
t.identifier("enumerable"),
|
||||
t.booleanLiteral(true),
|
||||
),
|
||||
t.objectProperty(t.identifier("initializer"), initializer),
|
||||
]),
|
||||
])
|
||||
],
|
||||
),
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
@ -253,21 +291,20 @@ export default function({ types: t }) {
|
||||
t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
|
||||
target,
|
||||
property,
|
||||
t.arrayExpression(decorators.map((dec) => dec.expression)),
|
||||
(
|
||||
t.arrayExpression(decorators.map(dec => dec.expression)),
|
||||
t.isObjectProperty(node) ||
|
||||
t.isClassProperty(node, { static: true })) ?
|
||||
buildGetObjectInitializer({
|
||||
t.isClassProperty(node, { static: true })
|
||||
? buildGetObjectInitializer({
|
||||
TEMP: path.scope.generateDeclaredUidIdentifier("init"),
|
||||
TARGET: target,
|
||||
PROPERTY: property,
|
||||
}).expression : buildGetDescriptor({
|
||||
}).expression
|
||||
: buildGetDescriptor({
|
||||
TARGET: target,
|
||||
PROPERTY: property,
|
||||
}
|
||||
).expression,
|
||||
}).expression,
|
||||
target,
|
||||
])
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -289,35 +326,42 @@ export default function({ types: t }) {
|
||||
if (!path.get("declaration").isClassDeclaration()) return;
|
||||
|
||||
const { node } = path;
|
||||
const ref = node.declaration.id || path.scope.generateUidIdentifier("default");
|
||||
const ref =
|
||||
node.declaration.id || path.scope.generateUidIdentifier("default");
|
||||
node.declaration.id = ref;
|
||||
|
||||
// Split the class declaration and the export into two separate statements.
|
||||
path.replaceWith(node.declaration);
|
||||
path.insertAfter(t.exportNamedDeclaration(null, [t.exportSpecifier(ref, t.identifier("default"))]));
|
||||
path.insertAfter(
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(ref, t.identifier("default")),
|
||||
]),
|
||||
);
|
||||
},
|
||||
ClassDeclaration(path) {
|
||||
const { node } = path;
|
||||
|
||||
const ref = node.id || path.scope.generateUidIdentifier("class");
|
||||
|
||||
path.replaceWith(t.variableDeclaration("let", [
|
||||
path.replaceWith(
|
||||
t.variableDeclaration("let", [
|
||||
t.variableDeclarator(ref, t.toExpression(node)),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
},
|
||||
ClassExpression(path, state) {
|
||||
// Create a replacement for the class node if there is one. We do one pass to replace classes with
|
||||
// class decorators, and a second pass to process method decorators.
|
||||
const decoratedClass = (
|
||||
const decoratedClass =
|
||||
applyEnsureOrdering(path) ||
|
||||
applyClassDecorators(path, state) ||
|
||||
applyMethodDecorators(path, state)
|
||||
);
|
||||
applyMethodDecorators(path, state);
|
||||
|
||||
if (decoratedClass) path.replaceWith(decoratedClass);
|
||||
},
|
||||
ObjectExpression(path, state) {
|
||||
const decoratedObject = applyEnsureOrdering(path) || applyObjectDecorators(path, state);
|
||||
const decoratedObject =
|
||||
applyEnsureOrdering(path) || applyObjectDecorators(path, state);
|
||||
|
||||
if (decoratedObject) path.replaceWith(decoratedObject);
|
||||
},
|
||||
@ -328,14 +372,22 @@ export default function({ types: t }) {
|
||||
if (!path.get("left").isMemberExpression()) return;
|
||||
if (!path.get("left.property").isIdentifier()) return;
|
||||
if (!path.get("right").isCallExpression()) return;
|
||||
if (!path.get("right.callee").isIdentifier({ name: state.initializerWarningHelper.name })) return;
|
||||
if (
|
||||
!path
|
||||
.get("right.callee")
|
||||
.isIdentifier({ name: state.initializerWarningHelper.name })
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
path.replaceWith(t.callExpression(ensureInitializerDefineProp(path, state), [
|
||||
path.replaceWith(
|
||||
t.callExpression(ensureInitializerDefineProp(path, state), [
|
||||
path.get("left.object").node,
|
||||
t.stringLiteral(path.get("left.property").node.name),
|
||||
path.get("right.arguments")[0].node,
|
||||
path.get("right.arguments")[1].node,
|
||||
]));
|
||||
]),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import syntaxDoExpressions from "babel-plugin-syntax-do-expressions";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
inherits: syntaxDoExpressions,
|
||||
|
||||
|
||||
@ -2,10 +2,13 @@
|
||||
|
||||
import type NodePath from "babel-traverse";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
visitor: {
|
||||
ArrowFunctionExpression(path: NodePath<BabelNodeArrowFunctionExpression>, state: Object) {
|
||||
ArrowFunctionExpression(
|
||||
path: NodePath<BabelNodeArrowFunctionExpression>,
|
||||
state: Object,
|
||||
) {
|
||||
// In some conversion cases, it may have already been converted to a function while this callback
|
||||
// was queued up.
|
||||
if (!path.isArrowFunctionExpression()) return;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default function ({ types: t }) {
|
||||
export default function({ types: t }) {
|
||||
function statementList(key, path) {
|
||||
const paths: Array = path.get(key);
|
||||
|
||||
@ -24,7 +24,10 @@ export default function ({ types: t }) {
|
||||
visitor: {
|
||||
BlockStatement(path) {
|
||||
const { node, parent } = path;
|
||||
if (t.isFunction(parent, { body: node }) || t.isExportDeclaration(parent)) {
|
||||
if (
|
||||
t.isFunction(parent, { body: node }) ||
|
||||
t.isExportDeclaration(parent)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import values from "lodash/values";
|
||||
import extend from "lodash/extend";
|
||||
import template from "babel-template";
|
||||
|
||||
export default function () {
|
||||
export default function() {
|
||||
return {
|
||||
visitor: {
|
||||
VariableDeclaration(path, file) {
|
||||
@ -44,20 +44,38 @@ export default function () {
|
||||
Loop(path, file) {
|
||||
const { node, parent, scope } = path;
|
||||
t.ensureBlock(node);
|
||||
const blockScoping = new BlockScoping(path, path.get("body"), parent, scope, file);
|
||||
const blockScoping = new BlockScoping(
|
||||
path,
|
||||
path.get("body"),
|
||||
parent,
|
||||
scope,
|
||||
file,
|
||||
);
|
||||
const replace = blockScoping.run();
|
||||
if (replace) path.replaceWith(replace);
|
||||
},
|
||||
|
||||
CatchClause(path, file) {
|
||||
const { parent, scope } = path;
|
||||
const blockScoping = new BlockScoping(null, path.get("body"), parent, scope, file);
|
||||
const blockScoping = new BlockScoping(
|
||||
null,
|
||||
path.get("body"),
|
||||
parent,
|
||||
scope,
|
||||
file,
|
||||
);
|
||||
blockScoping.run();
|
||||
},
|
||||
|
||||
"BlockStatement|SwitchStatement|Program"(path, file) {
|
||||
if (!ignoreBlock(path)) {
|
||||
const blockScoping = new BlockScoping(null, path, path.parent, path.scope, file);
|
||||
const blockScoping = new BlockScoping(
|
||||
null,
|
||||
path,
|
||||
path.parent,
|
||||
path.scope,
|
||||
file,
|
||||
);
|
||||
blockScoping.run();
|
||||
}
|
||||
},
|
||||
@ -80,7 +98,13 @@ function isBlockScoped(node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function convertBlockScopedToVar(path, node, parent, scope, moveBindingsToParent = false) {
|
||||
function convertBlockScopedToVar(
|
||||
path,
|
||||
node,
|
||||
parent,
|
||||
scope,
|
||||
moveBindingsToParent = false,
|
||||
) {
|
||||
if (!node) {
|
||||
node = path.node;
|
||||
}
|
||||
@ -111,7 +135,8 @@ function isVar(node) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isBlockScoped(node);
|
||||
}
|
||||
|
||||
const letReferenceBlockVisitor = traverse.visitors.merge([{
|
||||
const letReferenceBlockVisitor = traverse.visitors.merge([
|
||||
{
|
||||
Loop: {
|
||||
enter(path, state) {
|
||||
state.loopDepth++;
|
||||
@ -129,9 +154,12 @@ const letReferenceBlockVisitor = traverse.visitors.merge([{
|
||||
}
|
||||
return path.skip();
|
||||
},
|
||||
}, tdzVisitor]);
|
||||
},
|
||||
tdzVisitor,
|
||||
]);
|
||||
|
||||
const letReferenceFunctionVisitor = traverse.visitors.merge([{
|
||||
const letReferenceFunctionVisitor = traverse.visitors.merge([
|
||||
{
|
||||
ReferencedIdentifier(path, state) {
|
||||
const ref = state.letReferences[path.node.name];
|
||||
|
||||
@ -145,7 +173,9 @@ const letReferenceFunctionVisitor = traverse.visitors.merge([{
|
||||
|
||||
state.closurify = true;
|
||||
},
|
||||
}, tdzVisitor]);
|
||||
},
|
||||
tdzVisitor,
|
||||
]);
|
||||
|
||||
const hoistVarDeclarationsVisitor = {
|
||||
enter(path, self) {
|
||||
@ -166,7 +196,9 @@ const hoistVarDeclarationsVisitor = {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node, parent)) {
|
||||
path.replaceWithMultiple(self.pushDeclar(node).map((expr) => t.expressionStatement(expr)));
|
||||
path.replaceWithMultiple(
|
||||
self.pushDeclar(node).map(expr => t.expressionStatement(expr)),
|
||||
);
|
||||
} else if (path.isFunction()) {
|
||||
return path.skip();
|
||||
}
|
||||
@ -184,7 +216,12 @@ const continuationVisitor = {
|
||||
if (path.isAssignmentExpression() || path.isUpdateExpression()) {
|
||||
const bindings = path.getBindingIdentifiers();
|
||||
for (const name in bindings) {
|
||||
if (state.outsideReferences[name] !== path.scope.getBindingIdentifier(name)) continue;
|
||||
if (
|
||||
state.outsideReferences[name] !==
|
||||
path.scope.getBindingIdentifier(name)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
state.reassignments[name] = true;
|
||||
}
|
||||
}
|
||||
@ -252,7 +289,10 @@ const loopVisitor = {
|
||||
if (path.isReturnStatement()) {
|
||||
state.hasReturn = true;
|
||||
replace = t.objectExpression([
|
||||
t.objectProperty(t.identifier("v"), node.argument || scope.buildUndefinedNode()),
|
||||
t.objectProperty(
|
||||
t.identifier("v"),
|
||||
node.argument || scope.buildUndefinedNode(),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -266,7 +306,13 @@ const loopVisitor = {
|
||||
};
|
||||
|
||||
class BlockScoping {
|
||||
constructor(loopPath?: NodePath, blockPath: NodePath, parent: Object, scope: Scope, file: File) {
|
||||
constructor(
|
||||
loopPath?: NodePath,
|
||||
blockPath: NodePath,
|
||||
parent: Object,
|
||||
scope: Scope,
|
||||
file: File,
|
||||
) {
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.file = file;
|
||||
@ -281,7 +327,8 @@ class BlockScoping {
|
||||
|
||||
if (loopPath) {
|
||||
this.loopParent = loopPath.parent;
|
||||
this.loopLabel = t.isLabeledStatement(this.loopParent) && this.loopParent.label;
|
||||
this.loopLabel =
|
||||
t.isLabeledStatement(this.loopParent) && this.loopParent.label;
|
||||
this.loopPath = loopPath;
|
||||
this.loop = loopPath.node;
|
||||
}
|
||||
@ -360,11 +407,13 @@ class BlockScoping {
|
||||
// The same identifier might have been bound separately in the block scope and
|
||||
// the enclosing scope (e.g. loop or catch statement), so we should handle both
|
||||
// individually
|
||||
if (scope.hasOwnBinding(key))
|
||||
{scope.rename(ref.name);}
|
||||
if (scope.hasOwnBinding(key)) {
|
||||
scope.rename(ref.name);
|
||||
}
|
||||
|
||||
if (this.blockPath.scope.hasOwnBinding(key))
|
||||
{this.blockPath.scope.rename(ref.name);}
|
||||
if (this.blockPath.scope.hasOwnBinding(key)) {
|
||||
this.blockPath.scope.rename(ref.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,7 +422,7 @@ class BlockScoping {
|
||||
if (this.file.opts.throwIfClosureRequired) {
|
||||
throw this.blockPath.buildCodeFrameError(
|
||||
"Compiling let/const in this block would add a closure " +
|
||||
"(throwIfClosureRequired)."
|
||||
"(throwIfClosureRequired).",
|
||||
);
|
||||
}
|
||||
const block = this.block;
|
||||
@ -385,7 +434,10 @@ class BlockScoping {
|
||||
for (const name in outsideRefs) {
|
||||
const id = outsideRefs[name];
|
||||
|
||||
if (this.scope.hasGlobal(id.name) || this.scope.parentHasBinding(id.name)) {
|
||||
if (
|
||||
this.scope.hasGlobal(id.name) ||
|
||||
this.scope.parentHasBinding(id.name)
|
||||
) {
|
||||
delete outsideRefs[id.name];
|
||||
delete this.letReferences[id.name];
|
||||
|
||||
@ -411,8 +463,11 @@ class BlockScoping {
|
||||
const isSwitch = this.blockPath.isSwitchStatement();
|
||||
|
||||
// build the closure that we're going to wrap the block with, possible wrapping switch(){}
|
||||
const fn = t.functionExpression(null, params,
|
||||
t.blockStatement(isSwitch ? [block] : block.body));
|
||||
const fn = t.functionExpression(
|
||||
null,
|
||||
params,
|
||||
t.blockStatement(isSwitch ? [block] : block.body),
|
||||
);
|
||||
|
||||
// continuation
|
||||
this.addContinuations(fn);
|
||||
@ -421,7 +476,12 @@ class BlockScoping {
|
||||
let basePath = ".callee";
|
||||
|
||||
// handle generators
|
||||
const hasYield = traverse.hasType(fn.body, this.scope, "YieldExpression", t.FUNCTION_TYPES);
|
||||
const hasYield = traverse.hasType(
|
||||
fn.body,
|
||||
this.scope,
|
||||
"YieldExpression",
|
||||
t.FUNCTION_TYPES,
|
||||
);
|
||||
if (hasYield) {
|
||||
fn.generator = true;
|
||||
call = t.yieldExpression(call, true);
|
||||
@ -429,7 +489,12 @@ class BlockScoping {
|
||||
}
|
||||
|
||||
// handlers async functions
|
||||
const hasAsync = traverse.hasType(fn.body, this.scope, "AwaitExpression", t.FUNCTION_TYPES);
|
||||
const hasAsync = traverse.hasType(
|
||||
fn.body,
|
||||
this.scope,
|
||||
"AwaitExpression",
|
||||
t.FUNCTION_TYPES,
|
||||
);
|
||||
if (hasAsync) {
|
||||
fn.async = true;
|
||||
call = t.awaitExpression(call);
|
||||
@ -441,9 +506,9 @@ class BlockScoping {
|
||||
if (this.has.hasReturn || this.has.hasBreakContinue) {
|
||||
const ret = this.scope.generateUidIdentifier("ret");
|
||||
|
||||
this.body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ret, call),
|
||||
]));
|
||||
this.body.push(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(ret, call)]),
|
||||
);
|
||||
placeholderPath = "declarations.0.init" + basePath;
|
||||
index = this.body.length - 1;
|
||||
|
||||
@ -471,9 +536,9 @@ class BlockScoping {
|
||||
let fnPath;
|
||||
if (this.loop) {
|
||||
const ref = this.scope.generateUidIdentifier("loop");
|
||||
const p = this.loopPath.insertBefore(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, fn),
|
||||
]));
|
||||
const p = this.loopPath.insertBefore(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(ref, fn)]),
|
||||
);
|
||||
|
||||
placeholder.replaceWith(ref);
|
||||
fnPath = p[0].get("declarations.0.init");
|
||||
@ -512,7 +577,9 @@ class BlockScoping {
|
||||
this.scope.rename(param.name, newParam.name, fn);
|
||||
|
||||
// assign outer reference as it's been modified internally and needs to be retained
|
||||
fn.body.body.push(t.expressionStatement(t.assignmentExpression("=", param, newParam)));
|
||||
fn.body.body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", param, newParam)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +598,11 @@ class BlockScoping {
|
||||
|
||||
const addDeclarationsFromChild = (path, node) => {
|
||||
node = node || path.node;
|
||||
if (t.isClassDeclaration(node) || t.isFunctionDeclaration(node) || isBlockScoped(node)) {
|
||||
if (
|
||||
t.isClassDeclaration(node) ||
|
||||
t.isFunctionDeclaration(node) ||
|
||||
isBlockScoped(node)
|
||||
) {
|
||||
if (isBlockScoped(node)) {
|
||||
convertBlockScopedToVar(path, node, block, this.scope);
|
||||
}
|
||||
@ -585,7 +656,7 @@ class BlockScoping {
|
||||
};
|
||||
|
||||
const loopOrFunctionParent = this.blockPath.find(
|
||||
(path) => path.isLoop() || path.isFunction()
|
||||
path => path.isLoop() || path.isFunction(),
|
||||
);
|
||||
if (loopOrFunctionParent && loopOrFunctionParent.isLoop()) {
|
||||
// There is a loop ancestor closer than the closest function, so we
|
||||
@ -686,18 +757,20 @@ class BlockScoping {
|
||||
|
||||
if (cases.length === 1) {
|
||||
const single = cases[0];
|
||||
body.push(t.ifStatement(
|
||||
body.push(
|
||||
t.ifStatement(
|
||||
t.binaryExpression("===", ret, single.test),
|
||||
single.consequent[0]
|
||||
));
|
||||
single.consequent[0],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
if (this.loop) {
|
||||
// https://github.com/babel/babel/issues/998
|
||||
for (let i = 0; i < cases.length; i++) {
|
||||
const caseConsequent = cases[i].consequent[0];
|
||||
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
|
||||
caseConsequent.label = this.loopLabel = this.loopLabel ||
|
||||
this.scope.generateUidIdentifier("loop");
|
||||
caseConsequent.label = this.loopLabel =
|
||||
this.loopLabel || this.scope.generateUidIdentifier("loop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,10 +13,11 @@ function getTDZStatus(refPath, bindingPath) {
|
||||
}
|
||||
|
||||
function buildTDZAssert(node, file) {
|
||||
return t.callExpression(
|
||||
file.addHelper("temporalRef"),
|
||||
[node, t.stringLiteral(node.name), file.addHelper("temporalUndefined")]
|
||||
);
|
||||
return t.callExpression(file.addHelper("temporalRef"), [
|
||||
node,
|
||||
t.stringLiteral(node.name),
|
||||
file.addHelper("temporalUndefined"),
|
||||
]);
|
||||
}
|
||||
|
||||
function isReference(node, scope, state) {
|
||||
@ -56,12 +57,18 @@ export const visitor = {
|
||||
path.replaceWith(assert);
|
||||
}
|
||||
} else if (status === "outside") {
|
||||
path.replaceWith(t.throwStatement(t.inherits(
|
||||
path.replaceWith(
|
||||
t.throwStatement(
|
||||
t.inherits(
|
||||
t.newExpression(t.identifier("ReferenceError"), [
|
||||
t.stringLiteral(`${node.name} is not defined - temporal dead zone`),
|
||||
t.stringLiteral(
|
||||
`${node.name} is not defined - temporal dead zone`,
|
||||
),
|
||||
]),
|
||||
node
|
||||
)));
|
||||
node,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import LooseTransformer from "./loose";
|
||||
import VanillaTransformer from "./vanilla";
|
||||
import nameFunction from "babel-helper-function-name";
|
||||
|
||||
export default function ({ types: t }) {
|
||||
export default function({ types: t }) {
|
||||
// todo: investigate traversal requeueing
|
||||
const VISITED = Symbol();
|
||||
|
||||
@ -12,15 +12,17 @@ export default function ({ types: t }) {
|
||||
if (!path.get("declaration").isClassDeclaration()) return;
|
||||
|
||||
const { node } = path;
|
||||
const ref = node.declaration.id || path.scope.generateUidIdentifier("class");
|
||||
const ref =
|
||||
node.declaration.id || path.scope.generateUidIdentifier("class");
|
||||
node.declaration.id = ref;
|
||||
|
||||
// Split the class declaration and the export into two separate statements.
|
||||
path.replaceWith(node.declaration);
|
||||
path.insertAfter(t.exportNamedDeclaration(
|
||||
null,
|
||||
[t.exportSpecifier(ref, t.identifier("default"))]
|
||||
));
|
||||
path.insertAfter(
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(ref, t.identifier("default")),
|
||||
]),
|
||||
);
|
||||
},
|
||||
|
||||
ClassDeclaration(path) {
|
||||
@ -28,9 +30,11 @@ export default function ({ types: t }) {
|
||||
|
||||
const ref = node.id || path.scope.generateUidIdentifier("class");
|
||||
|
||||
path.replaceWith(t.variableDeclaration("let", [
|
||||
path.replaceWith(
|
||||
t.variableDeclaration("let", [
|
||||
t.variableDeclarator(ref, t.toExpression(node)),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
},
|
||||
|
||||
ClassExpression(path, state) {
|
||||
@ -47,7 +51,10 @@ export default function ({ types: t }) {
|
||||
|
||||
path.replaceWith(new Constructor(path, state.file).run());
|
||||
|
||||
if (path.isCallExpression() && path.get("callee").isArrowFunctionExpression()) {
|
||||
if (
|
||||
path.isCallExpression() &&
|
||||
path.get("callee").isArrowFunctionExpression()
|
||||
) {
|
||||
path.get("callee").arrowFunctionToExpression();
|
||||
}
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user