Run prettier
This commit is contained in:
parent
93cc22dae1
commit
e4b35f680d
27
Gulpfile.js
27
Gulpfile.js
@ -22,26 +22,35 @@ function swapSrcWithLib(srcPath) {
|
||||
gulp.task("default", ["build"]);
|
||||
|
||||
gulp.task("build", function() {
|
||||
return gulp.src(scripts, { base: base })
|
||||
.pipe(plumber({
|
||||
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));
|
||||
});
|
||||
|
||||
|
||||
@ -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,16 +67,21 @@ 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")),
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -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);
|
||||
|
||||
@ -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,7 +83,9 @@ 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" });
|
||||
const proc = child_process.spawn(process.argv[0], args, {
|
||||
stdio: "inherit",
|
||||
});
|
||||
proc.on("exit", function(code, signal) {
|
||||
process.on("exit", function() {
|
||||
if (signal) {
|
||||
|
||||
@ -8,17 +8,25 @@ import * as util from "./util";
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -97,9 +103,18 @@ export default function (commander, filenames, opts) {
|
||||
});
|
||||
|
||||
process.stdin.on("end", function() {
|
||||
results.push(util.transform(commander.filename, code, defaults({
|
||||
results.push(
|
||||
util.transform(
|
||||
commander.filename,
|
||||
code,
|
||||
defaults(
|
||||
{
|
||||
sourceFileName: "stdin",
|
||||
}, opts)));
|
||||
},
|
||||
opts,
|
||||
),
|
||||
),
|
||||
);
|
||||
output();
|
||||
});
|
||||
};
|
||||
@ -126,13 +141,22 @@ export default function (commander, filenames, opts) {
|
||||
_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;
|
||||
|
||||
@ -143,22 +167,25 @@ export default function (commander, filenames, opts) {
|
||||
};
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -53,8 +53,13 @@ const assertTest = function (stdout, stderr, opts) {
|
||||
|
||||
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");
|
||||
}
|
||||
@ -85,16 +95,20 @@ const assertTest = function (stdout, stderr, opts) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -94,7 +94,7 @@ function highlight(defs: Object, text: string) {
|
||||
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;
|
||||
@ -170,7 +176,8 @@ export function codeFrameColumns (
|
||||
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);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -4,30 +4,24 @@ 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), [
|
||||
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"));
|
||||
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() {
|
||||
@ -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,7 +48,8 @@ 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() {
|
||||
@ -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,7 +76,8 @@ describe("babel-code-frame", function () {
|
||||
" 7 | */",
|
||||
" 8 | ",
|
||||
" 9 | function sum(a, b) {",
|
||||
].join("\n"));
|
||||
].join("\n"),
|
||||
);
|
||||
});
|
||||
|
||||
it("tabs", function() {
|
||||
@ -86,12 +86,15 @@ describe("babel-code-frame", function () {
|
||||
"\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() {
|
||||
@ -99,10 +102,10 @@ describe("babel-code-frame", function () {
|
||||
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() {
|
||||
@ -119,14 +122,17 @@ 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() {
|
||||
@ -143,13 +149,16 @@ 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() {
|
||||
@ -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 } }), [
|
||||
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"),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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,17 +34,19 @@ 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);
|
||||
|
||||
@ -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,18 +101,15 @@ 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]);
|
||||
@ -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,23 +150,44 @@ 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;
|
||||
|
||||
@ -170,9 +196,15 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
||||
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;
|
||||
@ -181,7 +213,8 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
||||
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;
|
||||
}
|
||||
|
||||
@ -46,8 +46,11 @@ export function findConfigs(dirname: string): Array<ConfigFile> {
|
||||
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();
|
||||
|
||||
@ -25,18 +25,38 @@ 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`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -23,9 +23,14 @@ 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 {
|
||||
@ -85,18 +109,33 @@ function standardizeName(type: "plugin"|"preset", name: string) {
|
||||
|
||||
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 {
|
||||
@ -119,7 +158,9 @@ 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) {}
|
||||
|
||||
|
||||
@ -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",
|
||||
options: {},
|
||||
alias: string,
|
||||
loc: string,
|
||||
dirname: string
|
||||
dirname: string,
|
||||
};
|
||||
|
||||
const optionNames = new Set([
|
||||
@ -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;
|
||||
@ -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,11 +312,15 @@ 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);
|
||||
}
|
||||
|
||||
@ -294,14 +328,21 @@ function loadPluginDescriptor(descriptor) {
|
||||
}
|
||||
|
||||
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,7 +487,11 @@ function normalizeOptions(config) {
|
||||
/**
|
||||
* Given a plugin/preset item, resolve it into a standard format.
|
||||
*/
|
||||
function normalizePair(pair: mixed, resolver, dirname): {
|
||||
function normalizePair(
|
||||
pair: mixed,
|
||||
resolver,
|
||||
dirname,
|
||||
): {
|
||||
filepath: string | null,
|
||||
value: {} | Function,
|
||||
options: ?{},
|
||||
@ -429,7 +500,9 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
||||
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",
|
||||
},
|
||||
};
|
||||
|
||||
@ -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,9 +77,11 @@ 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);
|
||||
@ -76,9 +92,15 @@ function buildHelpers(body, namespace, whitelist) {
|
||||
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(
|
||||
|
||||
@ -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.";
|
||||
@ -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,
|
||||
},
|
||||
@ -401,7 +421,11 @@ 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");
|
||||
@ -410,7 +434,6 @@ export default class File extends Store {
|
||||
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 || [];
|
||||
@ -26,7 +30,11 @@ export function transform(code: string, opts?: Object): BabelFileResult {
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -44,7 +52,11 @@ export function transformFromAst(ast: Object, code: string, opts: Object): Babel
|
||||
});
|
||||
}
|
||||
|
||||
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 = {};
|
||||
@ -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;
|
||||
|
||||
@ -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,22 +77,28 @@ 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);
|
||||
});
|
||||
});
|
||||
@ -98,58 +107,78 @@ 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) {
|
||||
path.mark("category", "foobar");
|
||||
},
|
||||
},
|
||||
})],
|
||||
}).marked[0].message, "foobar");
|
||||
}),
|
||||
],
|
||||
}).marked[0].message,
|
||||
"foobar",
|
||||
);
|
||||
|
||||
assert.equal(babel.analyse("foobar;", {}, {
|
||||
assert.equal(
|
||||
babel.analyse(
|
||||
"foobar;",
|
||||
{},
|
||||
{
|
||||
Program: function(path) {
|
||||
path.mark("category", "foobar");
|
||||
},
|
||||
}).marked[0].message, "foobar");
|
||||
},
|
||||
).marked[0].message,
|
||||
"foobar",
|
||||
);
|
||||
});
|
||||
|
||||
it("exposes the resolvePlugin method", function() {
|
||||
assert.throws(() => babel.resolvePlugin("nonexistent-plugin"),
|
||||
/Cannot find module 'babel-plugin-nonexistent-plugin'/);
|
||||
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'/);
|
||||
assert.throws(
|
||||
() => babel.resolvePreset("nonexistent-preset"),
|
||||
/Cannot find module 'babel-preset-nonexistent-preset'/,
|
||||
);
|
||||
});
|
||||
|
||||
it("transformFile", function(done) {
|
||||
babel.transformFile(__dirname + "/fixtures/api/file.js", {
|
||||
babel.transformFile(
|
||||
__dirname + "/fixtures/api/file.js",
|
||||
{
|
||||
babelrc: false,
|
||||
}, function (err, res) {
|
||||
},
|
||||
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", {
|
||||
assert.equal(
|
||||
babel.transformFileSync(__dirname + "/fixtures/api/file.js", {
|
||||
babelrc: false,
|
||||
}).code, "foo();");
|
||||
}).code,
|
||||
"foo();",
|
||||
);
|
||||
});
|
||||
|
||||
it("options throw on falsy true", function() {
|
||||
return assert.throws(
|
||||
function () {
|
||||
return assert.throws(function() {
|
||||
babel.transform("", {
|
||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
||||
});
|
||||
},
|
||||
/Error: \[BABEL\] unknown: Unexpected falsy value: false/
|
||||
);
|
||||
}, /Error: \[BABEL\] unknown: Unexpected falsy value: false/);
|
||||
});
|
||||
|
||||
it("options merge backwards", function() {
|
||||
@ -157,7 +186,11 @@ describe("api", function () {
|
||||
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);
|
||||
assert.ok(
|
||||
result.options.plugins[0][0].manipulateOptions
|
||||
.toString()
|
||||
.indexOf("jsx") >= 0,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -179,14 +212,16 @@ describe("api", function () {
|
||||
};
|
||||
},
|
||||
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
name: "foobar",
|
||||
visitor: {
|
||||
"Program|Identifier": function() {
|
||||
calledRaw++;
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
assert.equal(calledRaw, 4);
|
||||
@ -207,7 +242,9 @@ describe("api", function () {
|
||||
new Plugin({
|
||||
visitor: {
|
||||
Function: function(path) {
|
||||
const alias = path.scope.getProgramParent().path.get("body")[0].node;
|
||||
const alias = path.scope
|
||||
.getProgramParent()
|
||||
.path.get("body")[0].node;
|
||||
if (!babel.types.isTypeAlias(alias)) return;
|
||||
|
||||
// In case of `passPerPreset` being `false`, the
|
||||
@ -234,7 +271,8 @@ describe("api", 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([
|
||||
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,37 +403,47 @@ 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) {
|
||||
return transformAsync("foo('bar');", { code: false }).then(function(
|
||||
result,
|
||||
) {
|
||||
assert.ok(!result.code);
|
||||
});
|
||||
});
|
||||
@ -401,62 +458,84 @@ describe("api", 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")));
|
||||
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*/");
|
||||
assert.equal(
|
||||
result.code,
|
||||
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
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";
|
||||
},
|
||||
@ -467,105 +546,129 @@ describe("api", function () {
|
||||
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) {
|
||||
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) {
|
||||
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",
|
||||
}],
|
||||
},
|
||||
],
|
||||
});
|
||||
}),
|
||||
]);
|
||||
@ -698,8 +801,10 @@ describe("api", 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, {
|
||||
|
||||
@ -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,44 +209,93 @@ 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", () => {
|
||||
@ -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/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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"),
|
||||
@ -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"),
|
||||
@ -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"),
|
||||
@ -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"),
|
||||
@ -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"),
|
||||
@ -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,7 +321,6 @@ describe("buildConfigChain", function () {
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
|
||||
it("env - foo", function() {
|
||||
process.env.NODE_ENV = "foo";
|
||||
|
||||
@ -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"),
|
||||
@ -446,9 +408,7 @@ describe("buildConfigChain", function () {
|
||||
{
|
||||
type: "options",
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
ignore: ["root-ignore"],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
@ -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"),
|
||||
@ -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,7 +560,8 @@ describe("buildConfigChain", function () {
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it("should not ignore file matching negated file pattern", function() {
|
||||
const chain = buildConfigChain({
|
||||
@ -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"),
|
||||
@ -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(
|
||||
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(
|
||||
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(
|
||||
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 () {
|
||||
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 () {
|
||||
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 () {
|
||||
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 () {
|
||||
assert.throws(function() {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while parsing config/
|
||||
);
|
||||
}, /Error while parsing config/);
|
||||
});
|
||||
});
|
||||
|
||||
@ -13,9 +13,12 @@ describe("evaluation", function () {
|
||||
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,47 +6,41 @@ 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/);
|
||||
});
|
||||
});
|
||||
|
||||
@ -54,7 +48,9 @@ describe("option-manager", () => {
|
||||
function presetTest(name) {
|
||||
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));
|
||||
@ -66,9 +62,15 @@ describe("option-manager", () => {
|
||||
|
||||
function presetThrowsTest(name, msg) {
|
||||
it(name, function() {
|
||||
assert.throws(() => manageOptions({
|
||||
"presets": [path.join(__dirname, "fixtures/option-manager/presets", name)],
|
||||
}), msg);
|
||||
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/);
|
||||
});
|
||||
|
||||
@ -7,13 +7,15 @@ describe("traversal path", function () {
|
||||
const expectCode = "function foo() {}";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
FunctionDeclaration: function(path) {
|
||||
path.replaceWithSourceString("console.whatever()");
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("console.whatever();");
|
||||
@ -23,22 +25,26 @@ describe("traversal path", function () {
|
||||
const expectCode = "var fn = () => true;";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
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};");
|
||||
@ -48,7 +54,8 @@ describe("traversal path", function () {
|
||||
const expectCode = "var fn = () => { return true; }";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ArrowFunctionExpression: function(path) {
|
||||
path.get("body").replaceWith({
|
||||
@ -57,7 +64,8 @@ describe("traversal path", function () {
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("var fn = () => true;");
|
||||
@ -67,23 +75,27 @@ describe("traversal path", function () {
|
||||
const expectCode = "for (KEY in right);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
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);");
|
||||
@ -93,7 +105,8 @@ describe("traversal path", function () {
|
||||
const expectCode = "for (var KEY in right);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForInStatement: function(path) {
|
||||
path.get("left").replaceWith({
|
||||
@ -102,7 +115,8 @@ describe("traversal path", function () {
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (KEY in right);");
|
||||
@ -112,23 +126,27 @@ describe("traversal path", function () {
|
||||
const expectCode = "for (KEY;;);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
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;;);");
|
||||
@ -138,7 +156,8 @@ describe("traversal path", function () {
|
||||
const expectCode = "for (var KEY;;);";
|
||||
|
||||
const actualCode = transform(expectCode, {
|
||||
plugins: [new Plugin({
|
||||
plugins: [
|
||||
new Plugin({
|
||||
visitor: {
|
||||
ForStatement: function(path) {
|
||||
path.get("init").replaceWith({
|
||||
@ -147,7 +166,8 @@ describe("traversal path", function () {
|
||||
});
|
||||
},
|
||||
},
|
||||
})],
|
||||
}),
|
||||
],
|
||||
}).code;
|
||||
|
||||
chai.expect(actualCode).to.be.equal("for (KEY;;);");
|
||||
|
||||
@ -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("?.");
|
||||
@ -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();
|
||||
@ -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"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -27,103 +27,142 @@ describe("generation", function () {
|
||||
"b.js": "hi('hello');\n",
|
||||
};
|
||||
const parsed = Object.keys(sources).reduce(function(_parsed, filename) {
|
||||
_parsed[filename] = parse(sources[filename], { sourceFilename: 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",
|
||||
],
|
||||
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",
|
||||
);
|
||||
});
|
||||
|
||||
@ -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"],
|
||||
mappings: "AAAA,SAASA,IAAT,GAAe;AAAEC;AAAM",
|
||||
sourcesContent: ["function foo() { bar; }\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: "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,16 +328,12 @@ 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"));
|
||||
});
|
||||
});
|
||||
|
||||
@ -298,7 +349,10 @@ 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 () {
|
||||
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) {
|
||||
@ -25,9 +22,11 @@ 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);
|
||||
};
|
||||
@ -38,7 +37,9 @@ export default function (opts: {
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
@ -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) {
|
||||
const visitor = {};
|
||||
|
||||
visitor.JSXNamespacedName = function(path) {
|
||||
throw path.buildCodeFrameError("Namespace tags are not supported. ReactJSX is not XML.");
|
||||
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);
|
||||
|
||||
@ -20,13 +20,19 @@ const visitor = {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -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,9 +42,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -57,8 +53,8 @@ export default function (
|
||||
scope: Scope,
|
||||
allowedSingleIdent?: boolean,
|
||||
): {
|
||||
uid: Object;
|
||||
ref: Object;
|
||||
uid: Object,
|
||||
ref: Object,
|
||||
} {
|
||||
let obj;
|
||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||
|
||||
@ -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,
|
||||
@ -129,8 +131,11 @@ 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;
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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" })) {
|
||||
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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,11 @@ 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]);
|
||||
}
|
||||
},
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
@ -95,16 +102,16 @@ function wrapPackagesArray(type, names, optionsDir) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,7 +204,9 @@ function run(task) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@ -205,10 +229,17 @@ export default 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);
|
||||
}
|
||||
@ -233,7 +264,9 @@ export default function (
|
||||
delete task.options.throws;
|
||||
|
||||
assert.throws(runTask, function(err) {
|
||||
return throwMsg === true || err.message.indexOf(throwMsg) >= 0;
|
||||
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",
|
||||
};
|
||||
|
||||
|
||||
@ -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"),
|
||||
),
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@ -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,
|
||||
]));
|
||||
]),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -5,7 +5,10 @@ import type NodePath from "babel-traverse";
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import type { Scope } from "babel-traverse";
|
||||
import * as t from "babel-types";
|
||||
|
||||
export default function (decorators: Array<Object>, scope: Scope): Array<Object> {
|
||||
export default function(
|
||||
decorators: Array<Object>,
|
||||
scope: Scope,
|
||||
): Array<Object> {
|
||||
for (const decorator of decorators) {
|
||||
const expression = decorator.expression;
|
||||
if (!t.isMemberExpression(expression)) continue;
|
||||
@ -18,13 +21,15 @@ export default function (decorators: Array<Object>, scope: Scope): Array<Object>
|
||||
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];
|
||||
|
||||
@ -13,10 +13,22 @@ export default class LooseClassTransformer extends VanillaTransformer {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
let classRef = this.classRef;
|
||||
if (!node.static) classRef = t.memberExpression(classRef, t.identifier("prototype"));
|
||||
const methodName = t.memberExpression(classRef, node.key, node.computed || t.isLiteral(node.key));
|
||||
if (!node.static) {
|
||||
classRef = t.memberExpression(classRef, t.identifier("prototype"));
|
||||
}
|
||||
const methodName = t.memberExpression(
|
||||
classRef,
|
||||
node.key,
|
||||
node.computed || t.isLiteral(node.key),
|
||||
);
|
||||
|
||||
let func = t.functionExpression(null, node.params, node.body, node.generator, node.async);
|
||||
let func = t.functionExpression(
|
||||
null,
|
||||
node.params,
|
||||
node.body,
|
||||
node.generator,
|
||||
node.async,
|
||||
);
|
||||
func.returnType = node.returnType;
|
||||
const key = t.toComputedKey(node, node.key);
|
||||
if (t.isStringLiteral(key)) {
|
||||
@ -27,7 +39,9 @@ export default class LooseClassTransformer extends VanillaTransformer {
|
||||
});
|
||||
}
|
||||
|
||||
const expr = t.expressionStatement(t.assignmentExpression("=", methodName, func));
|
||||
const expr = t.expressionStatement(
|
||||
t.assignmentExpression("=", methodName, func),
|
||||
);
|
||||
t.inheritsComments(expr, node);
|
||||
this.body.push(expr);
|
||||
return true;
|
||||
|
||||
@ -22,14 +22,20 @@ const noMethodVisitor = {
|
||||
},
|
||||
};
|
||||
|
||||
const verifyConstructorVisitor = visitors.merge([noMethodVisitor, {
|
||||
const verifyConstructorVisitor = visitors.merge([
|
||||
noMethodVisitor,
|
||||
{
|
||||
MemberExpression: {
|
||||
exit(path) {
|
||||
const objectPath = path.get("object");
|
||||
if (this.isDerived && !this.hasBareSuper && objectPath.isSuper()) {
|
||||
const hasArrowFunctionParent = path.findParent((p) => p.isArrowFunctionExpression());
|
||||
const hasArrowFunctionParent = path.findParent(p =>
|
||||
p.isArrowFunctionExpression(),
|
||||
);
|
||||
if (!hasArrowFunctionParent) {
|
||||
throw objectPath.buildCodeFrameError("'super.*' is not allowed before super()");
|
||||
throw objectPath.buildCodeFrameError(
|
||||
"'super.*' is not allowed before super()",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -41,7 +47,9 @@ const verifyConstructorVisitor = visitors.merge([noMethodVisitor, {
|
||||
this.hasBareSuper = true;
|
||||
|
||||
if (!this.isDerived) {
|
||||
throw path.buildCodeFrameError("super() is only allowed in a derived constructor");
|
||||
throw path.buildCodeFrameError(
|
||||
"super() is only allowed in a derived constructor",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -49,20 +57,26 @@ const verifyConstructorVisitor = visitors.merge([noMethodVisitor, {
|
||||
|
||||
ThisExpression(path) {
|
||||
if (this.isDerived && !this.hasBareSuper) {
|
||||
const fn = path.find((p) => p.isFunction());
|
||||
const fn = path.find(p => p.isFunction());
|
||||
|
||||
if (!fn || !fn.isArrowFunctionExpression()) {
|
||||
throw path.buildCodeFrameError("'this' is not allowed before super()");
|
||||
throw path.buildCodeFrameError(
|
||||
"'this' is not allowed before super()",
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
}]);
|
||||
},
|
||||
]);
|
||||
|
||||
const findThisesVisitor = visitors.merge([noMethodVisitor, {
|
||||
const findThisesVisitor = visitors.merge([
|
||||
noMethodVisitor,
|
||||
{
|
||||
ThisExpression(path) {
|
||||
this.superThises.push(path);
|
||||
},
|
||||
}]);
|
||||
},
|
||||
]);
|
||||
|
||||
export default class ClassTransformer {
|
||||
constructor(path: NodePath, file) {
|
||||
@ -92,8 +106,9 @@ export default class ClassTransformer {
|
||||
this.classId = this.node.id;
|
||||
|
||||
// this is the name of the binding that will **always** reference the class we've constructed
|
||||
this.classRef = this.node.id ? t.identifier(this.node.id.name) :
|
||||
this.scope.generateUidIdentifier("class");
|
||||
this.classRef = this.node.id
|
||||
? t.identifier(this.node.id.name)
|
||||
: this.scope.generateUidIdentifier("class");
|
||||
|
||||
this.superName = this.node.superClass || t.identifier("Function");
|
||||
this.isDerived = !!this.node.superClass;
|
||||
@ -106,7 +121,7 @@ export default class ClassTransformer {
|
||||
|
||||
//
|
||||
|
||||
const constructorBody = this.constructorBody = t.blockStatement([]);
|
||||
const constructorBody = (this.constructorBody = t.blockStatement([]));
|
||||
this.constructor = this.buildConstructor();
|
||||
|
||||
//
|
||||
@ -129,15 +144,17 @@ export default class ClassTransformer {
|
||||
|
||||
// make sure this class isn't directly called (with A() instead new A())
|
||||
if (!this.isLoose) {
|
||||
constructorBody.body.unshift(t.expressionStatement(t.callExpression(
|
||||
file.addHelper("classCallCheck"), [
|
||||
constructorBody.body.unshift(
|
||||
t.expressionStatement(
|
||||
t.callExpression(file.addHelper("classCallCheck"), [
|
||||
t.thisExpression(),
|
||||
this.classRef,
|
||||
]
|
||||
)));
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
body = body.concat(this.staticPropBody.map((fn) => fn(this.classRef)));
|
||||
body = body.concat(this.staticPropBody.map(fn => fn(this.classRef)));
|
||||
|
||||
if (this.classId) {
|
||||
// named class with only a constructor
|
||||
@ -147,7 +164,10 @@ export default class ClassTransformer {
|
||||
//
|
||||
body.push(t.returnStatement(this.classRef));
|
||||
|
||||
const container = t.arrowFunctionExpression(closureParams, t.blockStatement(body));
|
||||
const container = t.arrowFunctionExpression(
|
||||
closureParams,
|
||||
t.blockStatement(body),
|
||||
);
|
||||
return t.callExpression(container, closureArgs);
|
||||
}
|
||||
|
||||
@ -201,12 +221,12 @@ export default class ClassTransformer {
|
||||
body = t.blockStatement([]);
|
||||
}
|
||||
|
||||
this.path.get("body").unshiftContainer("body", t.classMethod(
|
||||
"constructor",
|
||||
t.identifier("constructor"),
|
||||
params,
|
||||
body
|
||||
));
|
||||
this.path
|
||||
.get("body")
|
||||
.unshiftContainer(
|
||||
"body",
|
||||
t.classMethod("constructor", t.identifier("constructor"), params, body),
|
||||
);
|
||||
}
|
||||
|
||||
buildBody() {
|
||||
@ -216,7 +236,9 @@ export default class ClassTransformer {
|
||||
|
||||
if (this.userConstructor) {
|
||||
const constructorBody = this.constructorBody;
|
||||
constructorBody.body = constructorBody.body.concat(this.userConstructor.body.body);
|
||||
constructorBody.body = constructorBody.body.concat(
|
||||
this.userConstructor.body.body,
|
||||
);
|
||||
t.inherits(this.constructor, this.userConstructor);
|
||||
t.inherits(constructorBody, this.userConstructor.body);
|
||||
}
|
||||
@ -236,7 +258,8 @@ export default class ClassTransformer {
|
||||
|
||||
if (node.decorators) {
|
||||
throw path.buildCodeFrameError(
|
||||
"Method has decorators, put the decorator plugin before the classes one.");
|
||||
"Method has decorators, put the decorator plugin before the classes one.",
|
||||
);
|
||||
}
|
||||
|
||||
if (t.isClassMethod(node)) {
|
||||
@ -246,11 +269,14 @@ export default class ClassTransformer {
|
||||
path.traverse(verifyConstructorVisitor, this);
|
||||
|
||||
if (!this.hasBareSuper && this.isDerived) {
|
||||
throw path.buildCodeFrameError("missing super() call in constructor");
|
||||
throw path.buildCodeFrameError(
|
||||
"missing super() call in constructor",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const replaceSupers = new ReplaceSupers({
|
||||
const replaceSupers = new ReplaceSupers(
|
||||
{
|
||||
forceSuperMemoisation: isConstructor,
|
||||
methodPath: path,
|
||||
methodNode: node,
|
||||
@ -260,7 +286,9 @@ export default class ClassTransformer {
|
||||
isLoose: this.isLoose,
|
||||
scope: this.scope,
|
||||
file: this.file,
|
||||
}, true);
|
||||
},
|
||||
true,
|
||||
);
|
||||
|
||||
replaceSupers.replace();
|
||||
|
||||
@ -298,8 +326,12 @@ export default class ClassTransformer {
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
if (instanceProps) instanceProps = defineMap.toComputedObjectFromClass(instanceProps);
|
||||
if (staticProps) staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
||||
if (instanceProps) {
|
||||
instanceProps = defineMap.toComputedObjectFromClass(instanceProps);
|
||||
}
|
||||
if (staticProps) {
|
||||
staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
||||
}
|
||||
|
||||
const nullNode = t.nullLiteral();
|
||||
|
||||
@ -330,10 +362,11 @@ export default class ClassTransformer {
|
||||
}
|
||||
args = args.slice(0, lastNonNullIndex + 1);
|
||||
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("createClass"), args)
|
||||
));
|
||||
body.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("createClass"), args),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
this.clearDescriptors();
|
||||
@ -353,13 +386,21 @@ export default class ClassTransformer {
|
||||
if (
|
||||
bareSuperNode.arguments.length === 2 &&
|
||||
t.isSpreadElement(bareSuperNode.arguments[1]) &&
|
||||
t.isIdentifier(bareSuperNode.arguments[1].argument, { name: "arguments" })
|
||||
t.isIdentifier(bareSuperNode.arguments[1].argument, {
|
||||
name: "arguments",
|
||||
})
|
||||
) {
|
||||
// special case single arguments spread
|
||||
bareSuperNode.arguments[1] = bareSuperNode.arguments[1].argument;
|
||||
bareSuperNode.callee = t.memberExpression(superRef, t.identifier("apply"));
|
||||
bareSuperNode.callee = t.memberExpression(
|
||||
superRef,
|
||||
t.identifier("apply"),
|
||||
);
|
||||
} else {
|
||||
bareSuperNode.callee = t.memberExpression(superRef, t.identifier("call"));
|
||||
bareSuperNode.callee = t.memberExpression(
|
||||
superRef,
|
||||
t.identifier("call"),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
bareSuperNode = optimiseCall(
|
||||
@ -367,12 +408,15 @@ export default class ClassTransformer {
|
||||
"||",
|
||||
t.memberExpression(this.classRef, t.identifier("__proto__")),
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[this.classRef]
|
||||
)
|
||||
t.memberExpression(
|
||||
t.identifier("Object"),
|
||||
t.identifier("getPrototypeOf"),
|
||||
),
|
||||
[this.classRef],
|
||||
),
|
||||
),
|
||||
t.thisExpression(),
|
||||
bareSuperNode.arguments
|
||||
bareSuperNode.arguments,
|
||||
);
|
||||
}
|
||||
|
||||
@ -383,11 +427,11 @@ export default class ClassTransformer {
|
||||
} else {
|
||||
call = t.callExpression(
|
||||
this.file.addHelper("possibleConstructorReturn"),
|
||||
[t.thisExpression(), bareSuperNode]
|
||||
[t.thisExpression(), bareSuperNode],
|
||||
);
|
||||
}
|
||||
|
||||
const bareSuperAfter = this.bareSuperAfter.map((fn) => fn(thisRef));
|
||||
const bareSuperAfter = this.bareSuperAfter.map(fn => fn(thisRef));
|
||||
|
||||
if (
|
||||
bareSuper.parentPath.isExpressionStatement() &&
|
||||
@ -409,14 +453,11 @@ export default class ClassTransformer {
|
||||
bareSuper.parentPath.replaceWith(t.returnStatement(call));
|
||||
} else {
|
||||
bareSuper.replaceWithMultiple([
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(thisRef, call),
|
||||
]),
|
||||
t.variableDeclaration("var", [t.variableDeclarator(thisRef, call)]),
|
||||
...bareSuperAfter,
|
||||
t.expressionStatement(thisRef),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
verifyConstructor() {
|
||||
@ -457,13 +498,16 @@ export default class ClassTransformer {
|
||||
let wrapReturn;
|
||||
|
||||
if (this.isLoose) {
|
||||
wrapReturn = (returnArg) => {
|
||||
return returnArg ? t.logicalExpression("||", returnArg, thisRef) : thisRef;
|
||||
wrapReturn = returnArg => {
|
||||
return returnArg
|
||||
? t.logicalExpression("||", returnArg, thisRef)
|
||||
: thisRef;
|
||||
};
|
||||
} else {
|
||||
wrapReturn = (returnArg) => t.callExpression(
|
||||
wrapReturn = returnArg =>
|
||||
t.callExpression(
|
||||
this.file.addHelper("possibleConstructorReturn"),
|
||||
[thisRef].concat(returnArg || [])
|
||||
[thisRef].concat(returnArg || []),
|
||||
);
|
||||
}
|
||||
|
||||
@ -471,14 +515,18 @@ export default class ClassTransformer {
|
||||
// return
|
||||
const bodyPaths = body.get("body");
|
||||
if (bodyPaths.length && !bodyPaths.pop().isReturnStatement()) {
|
||||
body.pushContainer("body", t.returnStatement(
|
||||
guaranteedSuperBeforeFinish ? thisRef : wrapReturn()));
|
||||
body.pushContainer(
|
||||
"body",
|
||||
t.returnStatement(guaranteedSuperBeforeFinish ? thisRef : wrapReturn()),
|
||||
);
|
||||
}
|
||||
|
||||
for (const returnPath of this.superReturns) {
|
||||
if (returnPath.node.argument) {
|
||||
const ref = returnPath.scope.generateDeclaredUidIdentifier("ret");
|
||||
returnPath.get("argument").replaceWithMultiple([
|
||||
returnPath
|
||||
.get("argument")
|
||||
.replaceWithMultiple([
|
||||
t.assignmentExpression("=", ref, returnPath.node.argument),
|
||||
wrapReturn(ref),
|
||||
]);
|
||||
@ -510,7 +558,11 @@ export default class ClassTransformer {
|
||||
* Replace the constructor body of our class.
|
||||
*/
|
||||
|
||||
pushConstructor(replaceSupers, method: { type: "ClassMethod" }, path: NodePath) {
|
||||
pushConstructor(
|
||||
replaceSupers,
|
||||
method: { type: "ClassMethod" },
|
||||
path: NodePath,
|
||||
) {
|
||||
this.bareSupers = replaceSupers.bareSupers;
|
||||
this.superReturns = replaceSupers.returns;
|
||||
|
||||
@ -561,9 +613,15 @@ export default class ClassTransformer {
|
||||
// Unshift to ensure that the constructor inheritance is set up before
|
||||
// any properties can be assigned to the prototype.
|
||||
this.pushedInherits = true;
|
||||
this.body.unshift(t.expressionStatement(t.callExpression(
|
||||
this.isLoose ? this.file.addHelper("inheritsLoose") : this.file.addHelper("inherits"),
|
||||
[this.classRef, this.superName]
|
||||
)));
|
||||
this.body.unshift(
|
||||
t.expressionStatement(
|
||||
t.callExpression(
|
||||
this.isLoose
|
||||
? this.file.addHelper("inheritsLoose")
|
||||
: this.file.addHelper("inherits"),
|
||||
[this.classRef, this.superName],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,13 @@ export default function ({ types: t, template }) {
|
||||
if (t.isObjectProperty(prop)) {
|
||||
return prop.value;
|
||||
} else if (t.isObjectMethod(prop)) {
|
||||
return t.functionExpression(null, prop.params, prop.body, prop.generator, prop.async);
|
||||
return t.functionExpression(
|
||||
null,
|
||||
prop.params,
|
||||
prop.body,
|
||||
prop.generator,
|
||||
prop.async,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,31 +22,44 @@ export default function ({ types: t, template }) {
|
||||
if (prop.kind === "get" && prop.kind === "set") {
|
||||
pushMutatorDefine(objId, prop, body);
|
||||
} else {
|
||||
body.push(t.expressionStatement(
|
||||
body.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, prop.key, prop.computed || t.isLiteral(prop.key)),
|
||||
getValue(prop)
|
||||
)
|
||||
));
|
||||
t.memberExpression(
|
||||
objId,
|
||||
prop.key,
|
||||
prop.computed || t.isLiteral(prop.key),
|
||||
),
|
||||
getValue(prop),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function pushMutatorDefine({ objId, body, getMutatorId, scope }, prop) {
|
||||
let key = !prop.computed && t.isIdentifier(prop.key) ? t.stringLiteral(prop.key.name) : prop.key;
|
||||
let key =
|
||||
!prop.computed && t.isIdentifier(prop.key)
|
||||
? t.stringLiteral(prop.key.name)
|
||||
: prop.key;
|
||||
|
||||
const maybeMemoise = scope.maybeGenerateMemoised(key);
|
||||
if (maybeMemoise) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression("=", maybeMemoise, key)));
|
||||
body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", maybeMemoise, key)),
|
||||
);
|
||||
key = maybeMemoise;
|
||||
}
|
||||
|
||||
body.push(...buildMutatorMapAssign({
|
||||
body.push(
|
||||
...buildMutatorMapAssign({
|
||||
MUTATOR_MAP_REF: getMutatorId(),
|
||||
KEY: key,
|
||||
VALUE: getValue(prop),
|
||||
KIND: t.identifier(prop.kind),
|
||||
}));
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function loose(info) {
|
||||
@ -71,13 +90,15 @@ export default function ({ types: t, template }) {
|
||||
getValue(prop),
|
||||
]);
|
||||
} else {
|
||||
body.push(t.expressionStatement(
|
||||
body.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(state.addHelper("defineProperty"), [
|
||||
objId,
|
||||
key,
|
||||
getValue(prop),
|
||||
])
|
||||
));
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,9 +139,11 @@ export default function ({ types: t, template }) {
|
||||
const initPropExpression = t.objectExpression(initProps);
|
||||
const body = [];
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
body.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, initPropExpression),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
|
||||
let callback = spec;
|
||||
if (state.opts.loose) callback = loose;
|
||||
@ -131,9 +154,11 @@ export default function ({ types: t, template }) {
|
||||
if (!mutatorRef) {
|
||||
mutatorRef = scope.generateUidIdentifier("mutatorMap");
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
body.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(mutatorRef, t.objectExpression([])),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
return mutatorRef;
|
||||
@ -150,10 +175,14 @@ export default function ({ types: t, template }) {
|
||||
});
|
||||
|
||||
if (mutatorRef) {
|
||||
body.push(t.expressionStatement(t.callExpression(
|
||||
body.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(
|
||||
state.addHelper("defineEnumerableProperties"),
|
||||
[objId, mutatorRef]
|
||||
)));
|
||||
[objId, mutatorRef],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (single) {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
export default function({ types: t }) {
|
||||
|
||||
/**
|
||||
* Test if a VariableDeclaration's declarations contains any Patterns.
|
||||
*/
|
||||
@ -86,7 +85,10 @@ export default function ({ types: t }) {
|
||||
}
|
||||
|
||||
toArray(node, count) {
|
||||
if (this.file.opts.loose || (t.isIdentifier(node) && this.arrays[node.name])) {
|
||||
if (
|
||||
this.file.opts.loose ||
|
||||
(t.isIdentifier(node) && this.arrays[node.name])
|
||||
) {
|
||||
return node;
|
||||
} else {
|
||||
return this.scope.toArray(node, count);
|
||||
@ -97,7 +99,9 @@ export default function ({ types: t }) {
|
||||
// we need to assign the current value of the assignment to avoid evaluating
|
||||
// it more than once
|
||||
|
||||
const tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
|
||||
const tempValueRef = this.scope.generateUidIdentifierBasedOnNode(
|
||||
valueRef,
|
||||
);
|
||||
|
||||
const declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempValueRef, valueRef),
|
||||
@ -110,13 +114,13 @@ export default function ({ types: t }) {
|
||||
const tempConditional = t.conditionalExpression(
|
||||
t.binaryExpression("===", tempValueRef, t.identifier("undefined")),
|
||||
pattern.right,
|
||||
tempValueRef
|
||||
tempValueRef,
|
||||
);
|
||||
|
||||
const left = pattern.left;
|
||||
if (t.isPattern(left)) {
|
||||
const tempValueDefault = t.expressionStatement(
|
||||
t.assignmentExpression("=", tempValueRef, tempConditional)
|
||||
t.assignmentExpression("=", tempValueRef, tempConditional),
|
||||
);
|
||||
tempValueDefault._blockHoist = this.blockHoist;
|
||||
|
||||
@ -143,7 +147,9 @@ export default function ({ types: t }) {
|
||||
if (t.isRestElement(prop)) continue;
|
||||
|
||||
let key = prop.key;
|
||||
if (t.isIdentifier(key) && !prop.computed) key = t.stringLiteral(prop.key.name);
|
||||
if (t.isIdentifier(key) && !prop.computed) {
|
||||
key = t.stringLiteral(prop.key.name);
|
||||
}
|
||||
keys.push(key);
|
||||
}
|
||||
|
||||
@ -152,7 +158,9 @@ export default function ({ types: t }) {
|
||||
//
|
||||
|
||||
const value = t.callExpression(
|
||||
this.file.addHelper("objectWithoutProperties"), [objRef, keys]);
|
||||
this.file.addHelper("objectWithoutProperties"),
|
||||
[objRef, keys],
|
||||
);
|
||||
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
|
||||
}
|
||||
|
||||
@ -173,9 +181,13 @@ export default function ({ types: t }) {
|
||||
// https://github.com/babel/babel/issues/681
|
||||
|
||||
if (!pattern.properties.length) {
|
||||
this.nodes.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [objRef])
|
||||
));
|
||||
this.nodes.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [
|
||||
objRef,
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// if we have more than one properties in this pattern and the objectRef is a
|
||||
@ -207,7 +219,9 @@ export default function ({ types: t }) {
|
||||
// pattern has less elements than the array and doesn't have a rest so some
|
||||
// elements wont be evaluated
|
||||
if (pattern.elements.length > arr.elements.length) return;
|
||||
if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false;
|
||||
if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const elem of (pattern.elements: Array)) {
|
||||
// deopt on holes
|
||||
@ -293,8 +307,10 @@ export default function ({ types: t }) {
|
||||
|
||||
if (t.isRestElement(elem)) {
|
||||
elemRef = this.toArray(arrayRef);
|
||||
elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")),
|
||||
[t.numericLiteral(i)]);
|
||||
elemRef = t.callExpression(
|
||||
t.memberExpression(elemRef, t.identifier("slice")),
|
||||
[t.numericLiteral(i)],
|
||||
);
|
||||
|
||||
// set the element to the rest element argument since we've dealt with it
|
||||
// being a rest already
|
||||
@ -327,7 +343,6 @@ export default function ({ types: t }) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
ExportNamedDeclaration(path) {
|
||||
@ -364,9 +379,9 @@ export default function ({ types: t }) {
|
||||
|
||||
path.ensureBlock();
|
||||
|
||||
node.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(left, temp),
|
||||
]));
|
||||
node.body.body.unshift(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(left, temp)]),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -432,12 +447,17 @@ export default function ({ types: t }) {
|
||||
});
|
||||
|
||||
let ref;
|
||||
if (path.isCompletionRecord() || !path.parentPath.isExpressionStatement()) {
|
||||
if (
|
||||
path.isCompletionRecord() ||
|
||||
!path.parentPath.isExpressionStatement()
|
||||
) {
|
||||
ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
nodes.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, node.right),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
|
||||
if (t.isArrayExpression(node.right)) {
|
||||
destructuring.arrays[ref.name] = true;
|
||||
@ -486,15 +506,23 @@ export default function ({ types: t }) {
|
||||
t.inherits(nodes[nodes.length - 1], declar);
|
||||
}
|
||||
} else {
|
||||
nodes.push(t.inherits(
|
||||
destructuring.buildVariableAssignment(declar.id, declar.init), declar));
|
||||
nodes.push(
|
||||
t.inherits(
|
||||
destructuring.buildVariableAssignment(declar.id, declar.init),
|
||||
declar,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const nodesOut = [];
|
||||
for (const node of nodes) {
|
||||
const tail = nodesOut[nodesOut.length - 1];
|
||||
if (tail && t.isVariableDeclaration(tail) && t.isVariableDeclaration(node)) {
|
||||
if (
|
||||
tail &&
|
||||
t.isVariableDeclaration(tail) &&
|
||||
t.isVariableDeclaration(node)
|
||||
) {
|
||||
// Create a single compound declarations
|
||||
tail.declarations.push(...node.declarations);
|
||||
} else {
|
||||
|
||||
@ -12,7 +12,9 @@ export default function() {
|
||||
visitor: {
|
||||
ObjectExpression(path) {
|
||||
const { node } = path;
|
||||
const plainProps = node.properties.filter((prop) => !t.isSpreadElement(prop) && !prop.computed);
|
||||
const plainProps = node.properties.filter(
|
||||
prop => !t.isSpreadElement(prop) && !prop.computed,
|
||||
);
|
||||
|
||||
// A property is a duplicate key if:
|
||||
// * the property is a data property, and is preceeded by a data,
|
||||
@ -43,7 +45,11 @@ export default function() {
|
||||
alreadySeenSetters[name] = true;
|
||||
break;
|
||||
default:
|
||||
if (alreadySeenData[name] || alreadySeenGetters[name] || alreadySeenSetters[name]) {
|
||||
if (
|
||||
alreadySeenData[name] ||
|
||||
alreadySeenGetters[name] ||
|
||||
alreadySeenSetters[name]
|
||||
) {
|
||||
isDuplicate = true;
|
||||
}
|
||||
alreadySeenData[name] = true;
|
||||
|
||||
@ -57,9 +57,9 @@ export default function ({ messages, template, types: t }) {
|
||||
|
||||
if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) {
|
||||
const uid = scope.generateUidIdentifier("arr");
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, right),
|
||||
]));
|
||||
nodes.push(
|
||||
t.variableDeclaration("var", [t.variableDeclarator(uid, right)]),
|
||||
);
|
||||
right = uid;
|
||||
}
|
||||
|
||||
@ -81,8 +81,11 @@ export default function ({ messages, template, types: t }) {
|
||||
left.declarations[0].init = iterationValue;
|
||||
loop.body.body.unshift(left);
|
||||
} else {
|
||||
loop.body.body.unshift(t.expressionStatement(
|
||||
t.assignmentExpression("=", left, iterationValue)));
|
||||
loop.body.body.unshift(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression("=", left, iterationValue),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (path.parentPath.isLabeledStatement()) {
|
||||
@ -111,19 +114,18 @@ export default function ({ messages, template, types: t }) {
|
||||
} else if (right.isIdentifier() && right.isPure()) {
|
||||
const binding = path.scope.getBinding(right.node.name);
|
||||
return optimize(path, binding.path.get("init"));
|
||||
} else if (right.isCallExpression() && (
|
||||
isArrayFrom(right.get("callee").node) ||
|
||||
} else if (
|
||||
right.isCallExpression() &&
|
||||
(isArrayFrom(right.get("callee").node) ||
|
||||
isObjectKeys(right.get("callee").node) ||
|
||||
isObjectValues(right.get("callee").node) ||
|
||||
isObjectEntries(right.get("callee").node)
|
||||
)
|
||||
isObjectEntries(right.get("callee").node))
|
||||
) {
|
||||
const initPath = right === path.get("right") ? path : right.find((p) => p.isStatement());
|
||||
const initPath =
|
||||
right === path.get("right") ? path : right.find(p => p.isStatement());
|
||||
const uid = path.scope.generateUidIdentifierBasedOnNode(right.node);
|
||||
initPath.insertBefore(
|
||||
t.variableDeclaration("const", [
|
||||
t.variableDeclarator(uid, right.node),
|
||||
])
|
||||
t.variableDeclaration("const", [t.variableDeclarator(uid, right.node)]),
|
||||
);
|
||||
right.replaceWith(uid);
|
||||
return replaceWithArray(path);
|
||||
@ -176,7 +178,11 @@ export default function ({ messages, template, types: t }) {
|
||||
const { left } = node;
|
||||
let declar, id;
|
||||
|
||||
if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
|
||||
if (
|
||||
t.isIdentifier(left) ||
|
||||
t.isPattern(left) ||
|
||||
t.isMemberExpression(left)
|
||||
) {
|
||||
// for (i of test), for ({ i } of test)
|
||||
id = left;
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
@ -186,7 +192,10 @@ export default function ({ messages, template, types: t }) {
|
||||
t.variableDeclarator(left.declarations[0].id, id),
|
||||
]);
|
||||
} else {
|
||||
throw file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));
|
||||
throw file.buildCodeFrameError(
|
||||
left,
|
||||
messages.get("unknownForHead", left.type),
|
||||
);
|
||||
}
|
||||
|
||||
const iteratorKey = scope.generateUidIdentifier("iterator");
|
||||
@ -230,16 +239,25 @@ export default function ({ messages, template, types: t }) {
|
||||
const stepKey = scope.generateUidIdentifier("step");
|
||||
const stepValue = t.memberExpression(stepKey, t.identifier("value"));
|
||||
|
||||
if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
|
||||
if (
|
||||
t.isIdentifier(left) ||
|
||||
t.isPattern(left) ||
|
||||
t.isMemberExpression(left)
|
||||
) {
|
||||
// for (i of test), for ({ i } of test)
|
||||
declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue));
|
||||
declar = t.expressionStatement(
|
||||
t.assignmentExpression("=", left, stepValue),
|
||||
);
|
||||
} else if (t.isVariableDeclaration(left)) {
|
||||
// for (let i of test)
|
||||
declar = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(left.declarations[0].id, stepValue),
|
||||
]);
|
||||
} else {
|
||||
throw file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));
|
||||
throw file.buildCodeFrameError(
|
||||
left,
|
||||
messages.get("unknownForHead", left.type),
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
@ -248,7 +266,9 @@ export default function ({ messages, template, types: t }) {
|
||||
|
||||
const template = buildForOf({
|
||||
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: iteratorKey,
|
||||
STEP_KEY: stepKey,
|
||||
|
||||
@ -4,7 +4,12 @@ export default function ({ types: t }) {
|
||||
BinaryExpression(path) {
|
||||
const { node } = path;
|
||||
if (node.operator === "instanceof") {
|
||||
path.replaceWith(t.callExpression(this.addHelper("instanceof"), [node.left, node.right]));
|
||||
path.replaceWith(
|
||||
t.callExpression(this.addHelper("instanceof"), [
|
||||
node.left,
|
||||
node.right,
|
||||
]),
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -63,7 +63,9 @@ export default function ({ types: t }) {
|
||||
CallExpression(path) {
|
||||
if (!isValidRequireCall(path)) return;
|
||||
const source = path.node.arguments[0];
|
||||
const ref = path.scope.generateUidIdentifier(basename(source.value, extname(source.value)));
|
||||
const ref = path.scope.generateUidIdentifier(
|
||||
basename(source.value, extname(source.value)),
|
||||
);
|
||||
this.sources.push([ref, source, true]);
|
||||
path.remove();
|
||||
},
|
||||
@ -126,11 +128,13 @@ export default function ({ types: t }) {
|
||||
factory.expression.body.directives = node.directives;
|
||||
node.directives = [];
|
||||
|
||||
node.body = [buildDefine({
|
||||
node.body = [
|
||||
buildDefine({
|
||||
MODULE_NAME: moduleName,
|
||||
SOURCES: sources,
|
||||
FACTORY: factory,
|
||||
})];
|
||||
}),
|
||||
];
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -42,8 +42,13 @@ const buildExportAll = template(`
|
||||
});
|
||||
`);
|
||||
|
||||
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassProperty",
|
||||
"ClassMethod", "ObjectMethod"];
|
||||
const THIS_BREAK_KEYS = [
|
||||
"FunctionExpression",
|
||||
"FunctionDeclaration",
|
||||
"ClassProperty",
|
||||
"ClassMethod",
|
||||
"ObjectMethod",
|
||||
];
|
||||
|
||||
export default function() {
|
||||
const REASSIGN_REMAP_SKIP = Symbol();
|
||||
@ -61,8 +66,12 @@ export default function () {
|
||||
path.replaceWith(t.sequenceExpression([t.numericLiteral(0), remap]));
|
||||
} else if (path.isJSXIdentifier() && t.isMemberExpression(remap)) {
|
||||
const { object, property } = remap;
|
||||
path.replaceWith(t.JSXMemberExpression(t.JSXIdentifier(object.name),
|
||||
t.JSXIdentifier(property.name)));
|
||||
path.replaceWith(
|
||||
t.JSXMemberExpression(
|
||||
t.JSXIdentifier(object.name),
|
||||
t.JSXIdentifier(property.name),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
path.replaceWith(remap);
|
||||
}
|
||||
@ -104,9 +113,17 @@ export default function () {
|
||||
// redeclared in this scope
|
||||
if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return;
|
||||
|
||||
const node = t.assignmentExpression(path.node.operator[0] + "=", arg.node, t.numericLiteral(1));
|
||||
const node = t.assignmentExpression(
|
||||
path.node.operator[0] + "=",
|
||||
arg.node,
|
||||
t.numericLiteral(1),
|
||||
);
|
||||
|
||||
if ((path.parentPath.isExpressionStatement() && !path.isCompletionRecord()) || path.node.prefix) {
|
||||
if (
|
||||
(path.parentPath.isExpressionStatement() &&
|
||||
!path.isCompletionRecord()) ||
|
||||
path.node.prefix
|
||||
) {
|
||||
path.replaceWith(node);
|
||||
this.requeueInParent(path);
|
||||
return;
|
||||
@ -118,7 +135,8 @@ export default function () {
|
||||
let operator;
|
||||
if (path.node.operator === "--") {
|
||||
operator = "+";
|
||||
} else { // "++"
|
||||
} else {
|
||||
// "++"
|
||||
operator = "-";
|
||||
}
|
||||
nodes.push(t.binaryExpression(operator, arg.node, t.numericLiteral(1)));
|
||||
@ -139,7 +157,7 @@ export default function () {
|
||||
|
||||
if (
|
||||
state.opts.allowTopLevelThis !== true &&
|
||||
!path.findParent((path) => THIS_BREAK_KEYS.indexOf(path.type) >= 0)
|
||||
!path.findParent(path => THIS_BREAK_KEYS.indexOf(path.type) >= 0)
|
||||
) {
|
||||
path.replaceWith(t.identifier("undefined"));
|
||||
}
|
||||
@ -177,12 +195,15 @@ export default function () {
|
||||
const cached = requires[source];
|
||||
if (cached) return cached;
|
||||
|
||||
const ref = path.scope.generateUidIdentifier(basename(source, extname(source)));
|
||||
const ref = path.scope.generateUidIdentifier(
|
||||
basename(source, extname(source)),
|
||||
);
|
||||
|
||||
const varDecl = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, buildRequire(
|
||||
t.stringLiteral(source)
|
||||
).expression),
|
||||
t.variableDeclarator(
|
||||
ref,
|
||||
buildRequire(t.stringLiteral(source)).expression,
|
||||
),
|
||||
]);
|
||||
|
||||
// Copy location from the original import statement for sourcemap
|
||||
@ -197,7 +218,7 @@ export default function () {
|
||||
|
||||
topNodes.push(varDecl);
|
||||
|
||||
return requires[source] = ref;
|
||||
return (requires[source] = ref);
|
||||
}
|
||||
|
||||
function addTo(obj, key, arr) {
|
||||
@ -209,11 +230,16 @@ export default function () {
|
||||
if (path.isExportDeclaration()) {
|
||||
hasExports = true;
|
||||
|
||||
const specifiers = [].concat(path.get("declaration"), path.get("specifiers"));
|
||||
const specifiers = [].concat(
|
||||
path.get("declaration"),
|
||||
path.get("specifiers"),
|
||||
);
|
||||
for (const specifier of specifiers) {
|
||||
const ids = specifier.getBindingIdentifiers();
|
||||
if (ids.__esModule) {
|
||||
throw specifier.buildCodeFrameError("Illegal export \"__esModule\"");
|
||||
throw specifier.buildCodeFrameError(
|
||||
'Illegal export "__esModule"',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,7 +259,7 @@ export default function () {
|
||||
if (typeof path.node._blockHoist === "number") {
|
||||
importsEntry.maxBlockHoist = Math.max(
|
||||
path.node._blockHoist,
|
||||
importsEntry.maxBlockHoist
|
||||
importsEntry.maxBlockHoist,
|
||||
);
|
||||
}
|
||||
|
||||
@ -250,7 +276,12 @@ export default function () {
|
||||
topNodes.push(buildExportsAssignment(defNode, id));
|
||||
path.replaceWith(declaration.node);
|
||||
} else {
|
||||
topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node)));
|
||||
topNodes.push(
|
||||
buildExportsAssignment(
|
||||
defNode,
|
||||
t.toExpression(declaration.node),
|
||||
),
|
||||
);
|
||||
path.remove();
|
||||
}
|
||||
} else if (declaration.isClassDeclaration()) {
|
||||
@ -263,7 +294,12 @@ export default function () {
|
||||
buildExportsAssignment(defNode, id),
|
||||
]);
|
||||
} else {
|
||||
path.replaceWith(buildExportsAssignment(defNode, t.toExpression(declaration.node)));
|
||||
path.replaceWith(
|
||||
buildExportsAssignment(
|
||||
defNode,
|
||||
t.toExpression(declaration.node),
|
||||
),
|
||||
);
|
||||
|
||||
// Manualy re-queue `export default class {}` expressions so that the ES3 transform
|
||||
// has an opportunity to convert them. Ideally this would happen automatically from the
|
||||
@ -271,7 +307,12 @@ export default function () {
|
||||
path.parentPath.requeue(path.get("expression.left"));
|
||||
}
|
||||
} else {
|
||||
path.replaceWith(buildExportsAssignment(t.identifier("default"), declaration.node));
|
||||
path.replaceWith(
|
||||
buildExportsAssignment(
|
||||
t.identifier("default"),
|
||||
declaration.node,
|
||||
),
|
||||
);
|
||||
|
||||
// Manualy re-queue `export default foo;` expressions so that the ES3 transform
|
||||
// has an opportunity to convert them. Ideally this would happen automatically from the
|
||||
@ -306,7 +347,9 @@ export default function () {
|
||||
|
||||
if (id.isIdentifier()) {
|
||||
addTo(exports, id.node.name, id.node);
|
||||
init.replaceWith(buildExportsAssignment(id.node, init.node).expression);
|
||||
init.replaceWith(
|
||||
buildExportsAssignment(id.node, init.node).expression,
|
||||
);
|
||||
nonHoistedExportNames[id.node.name] = true;
|
||||
} else if (id.isObjectPattern()) {
|
||||
for (let i = 0; i < id.node.properties.length; i++) {
|
||||
@ -318,7 +361,9 @@ export default function () {
|
||||
propValue = prop.argument;
|
||||
}
|
||||
addTo(exports, propValue.name, propValue);
|
||||
exportsToInsert.push(buildExportsAssignment(propValue, propValue));
|
||||
exportsToInsert.push(
|
||||
buildExportsAssignment(propValue, propValue),
|
||||
);
|
||||
nonHoistedExportNames[propValue.name] = true;
|
||||
}
|
||||
} else if (id.isArrayPattern() && id.node.elements) {
|
||||
@ -332,7 +377,9 @@ export default function () {
|
||||
}
|
||||
const name = elem.name;
|
||||
addTo(exports, name, elem);
|
||||
exportsToInsert.push(buildExportsAssignment(elem, elem));
|
||||
exportsToInsert.push(
|
||||
buildExportsAssignment(elem, elem),
|
||||
);
|
||||
nonHoistedExportNames[name] = true;
|
||||
}
|
||||
}
|
||||
@ -356,15 +403,25 @@ export default function () {
|
||||
// todo
|
||||
} else if (specifier.isExportSpecifier()) {
|
||||
if (!noInterop && specifier.node.local.name === "default") {
|
||||
topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name),
|
||||
topNodes.push(
|
||||
buildExportsFrom(
|
||||
t.stringLiteral(specifier.node.exported.name),
|
||||
t.memberExpression(
|
||||
t.callExpression(this.addHelper("interopRequireDefault"), [ref]),
|
||||
specifier.node.local
|
||||
)
|
||||
));
|
||||
t.callExpression(
|
||||
this.addHelper("interopRequireDefault"),
|
||||
[ref],
|
||||
),
|
||||
specifier.node.local,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name),
|
||||
t.memberExpression(ref, specifier.node.local)));
|
||||
topNodes.push(
|
||||
buildExportsFrom(
|
||||
t.stringLiteral(specifier.node.exported.name),
|
||||
t.memberExpression(ref, specifier.node.local),
|
||||
),
|
||||
);
|
||||
}
|
||||
nonHoistedExportNames[specifier.node.exported.name] = true;
|
||||
}
|
||||
@ -372,16 +429,28 @@ export default function () {
|
||||
} else {
|
||||
for (const specifier of specifiers) {
|
||||
if (specifier.isExportSpecifier()) {
|
||||
addTo(exports, specifier.node.local.name, specifier.node.exported);
|
||||
addTo(
|
||||
exports,
|
||||
specifier.node.local.name,
|
||||
specifier.node.exported,
|
||||
);
|
||||
nonHoistedExportNames[specifier.node.exported.name] = true;
|
||||
nodes.push(buildExportsAssignment(specifier.node.exported, specifier.node.local));
|
||||
nodes.push(
|
||||
buildExportsAssignment(
|
||||
specifier.node.exported,
|
||||
specifier.node.local,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
path.replaceWithMultiple(nodes);
|
||||
} else if (path.isExportAllDeclaration()) {
|
||||
const exportNode = buildExportAll({
|
||||
OBJECT: addRequire(path.node.source.value, path.node._blockHoist),
|
||||
OBJECT: addRequire(
|
||||
path.node.source.value,
|
||||
path.node._blockHoist,
|
||||
),
|
||||
});
|
||||
exportNode.loc = path.node.loc;
|
||||
topNodes.push(exportNode);
|
||||
@ -407,8 +476,8 @@ export default function () {
|
||||
specifier.local,
|
||||
t.callExpression(
|
||||
this.addHelper("interopRequireWildcard"),
|
||||
[uid]
|
||||
)
|
||||
[uid],
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
@ -420,7 +489,10 @@ export default function () {
|
||||
}
|
||||
wildcard = specifier.local;
|
||||
} else if (t.isImportDefaultSpecifier(specifier)) {
|
||||
specifiers[i] = t.importSpecifier(specifier.local, t.identifier("default"));
|
||||
specifiers[i] = t.importSpecifier(
|
||||
specifier.local,
|
||||
t.identifier("default"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,14 +503,16 @@ export default function () {
|
||||
if (wildcard) {
|
||||
target = wildcard;
|
||||
} else if (!noInterop) {
|
||||
target = wildcard = path.scope.generateUidIdentifier(uid.name);
|
||||
target = wildcard = path.scope.generateUidIdentifier(
|
||||
uid.name,
|
||||
);
|
||||
const varDecl = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
target,
|
||||
t.callExpression(
|
||||
this.addHelper("interopRequireDefault"),
|
||||
[uid]
|
||||
)
|
||||
[uid],
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
@ -449,8 +523,10 @@ export default function () {
|
||||
topNodes.push(varDecl);
|
||||
}
|
||||
}
|
||||
remaps[specifier.local.name] = t.memberExpression(target,
|
||||
t.cloneWithoutLoc(specifier.imported));
|
||||
remaps[specifier.local.name] = t.memberExpression(
|
||||
target,
|
||||
t.cloneWithoutLoc(specifier.imported),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -462,25 +538,29 @@ export default function () {
|
||||
}
|
||||
|
||||
if (hasImports && Object.keys(nonHoistedExportNames).length) {
|
||||
|
||||
// avoid creating too long of export assignment to prevent stack overflow
|
||||
const maxHoistedExportsNodeAssignmentLength = 100;
|
||||
const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames);
|
||||
|
||||
for (
|
||||
let currentExportsNodeAssignmentLength = 0;
|
||||
currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length;
|
||||
currentExportsNodeAssignmentLength <
|
||||
nonHoistedExportNamesArr.length;
|
||||
currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength
|
||||
) {
|
||||
const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice(
|
||||
currentExportsNodeAssignmentLength,
|
||||
currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength);
|
||||
currentExportsNodeAssignmentLength +
|
||||
maxHoistedExportsNodeAssignmentLength,
|
||||
);
|
||||
|
||||
let hoistedExportsNode = t.identifier("undefined");
|
||||
|
||||
nonHoistedExportNamesChunk.forEach(function(name) {
|
||||
hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode)
|
||||
.expression;
|
||||
hoistedExportsNode = buildExportsAssignment(
|
||||
t.identifier(name),
|
||||
hoistedExportsNode,
|
||||
).expression;
|
||||
});
|
||||
|
||||
const node = t.expressionStatement(hoistedExportsNode);
|
||||
@ -493,7 +573,9 @@ export default function () {
|
||||
// add __esModule declaration if this file has any exports
|
||||
if (hasExports && !strict) {
|
||||
let buildTemplate = buildExportsModuleDeclaration;
|
||||
if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration;
|
||||
if (this.opts.loose) {
|
||||
buildTemplate = buildLooseExportsModuleDeclaration;
|
||||
}
|
||||
|
||||
const declar = buildTemplate();
|
||||
declar._blockHoist = 3;
|
||||
@ -506,7 +588,7 @@ export default function () {
|
||||
remaps,
|
||||
scope,
|
||||
exports,
|
||||
requeueInParent: (newPath) => path.requeue(newPath),
|
||||
requeueInParent: newPath => path.requeue(newPath),
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@ -3,7 +3,7 @@ const babel = require("babel-core");
|
||||
const vm = require("vm");
|
||||
|
||||
test("Re-export doesn't overwrite __esModule flag", function() {
|
||||
let code = "export * from \"./dep\";";
|
||||
let code = 'export * from "./dep";';
|
||||
const depStub = {
|
||||
__esModule: false,
|
||||
};
|
||||
@ -20,10 +20,8 @@ test("Re-export doesn't overwrite __esModule flag", function () {
|
||||
context.exports = context.module.exports;
|
||||
|
||||
code = babel.transform(code, {
|
||||
"plugins": [
|
||||
[require("../"), { loose: true }],
|
||||
],
|
||||
"ast": false,
|
||||
plugins: [[require("../"), { loose: true }]],
|
||||
ast: false,
|
||||
}).code;
|
||||
|
||||
vm.runInNewContext(code, context);
|
||||
@ -32,6 +30,6 @@ test("Re-export doesn't overwrite __esModule flag", function () {
|
||||
assert.equal(
|
||||
context.exports.__esModule,
|
||||
true,
|
||||
"Expected exports.__esModule === true"
|
||||
"Expected exports.__esModule === true",
|
||||
);
|
||||
});
|
||||
|
||||
@ -20,7 +20,6 @@ const buildExportAll = template(`
|
||||
}
|
||||
`);
|
||||
|
||||
|
||||
const TYPE_IMPORT = "Import";
|
||||
|
||||
export default function({ types: t }) {
|
||||
@ -49,20 +48,22 @@ export default function ({ types: t }) {
|
||||
// in order to ensure the same update expression value
|
||||
let isPostUpdateExpression = path.isUpdateExpression() && !node.prefix;
|
||||
if (isPostUpdateExpression) {
|
||||
if (node.operator === "++")
|
||||
{node = t.binaryExpression("+", node.argument, t.numericLiteral(1));}
|
||||
else if (node.operator === "--")
|
||||
{node = t.binaryExpression("-", node.argument, t.numericLiteral(1));}
|
||||
else
|
||||
{isPostUpdateExpression = false;}
|
||||
if (node.operator === "++") {
|
||||
node = t.binaryExpression("+", node.argument, t.numericLiteral(1));
|
||||
} else if (node.operator === "--") {
|
||||
node = t.binaryExpression("-", node.argument, t.numericLiteral(1));
|
||||
} else {
|
||||
isPostUpdateExpression = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const exportedName of exportedNames) {
|
||||
node = this.buildCall(exportedName, node).expression;
|
||||
}
|
||||
|
||||
if (isPostUpdateExpression)
|
||||
{node = t.sequenceExpression([node, path.node]);}
|
||||
if (isPostUpdateExpression) {
|
||||
node = t.sequenceExpression([node, path.node]);
|
||||
}
|
||||
|
||||
path.replaceWith(node);
|
||||
},
|
||||
@ -70,18 +71,26 @@ export default function ({ types: t }) {
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
|
||||
CallExpression(path, state) {
|
||||
if (path.node.callee.type === TYPE_IMPORT) {
|
||||
const contextIdent = state.contextIdent;
|
||||
path.replaceWith(t.callExpression(t.memberExpression(contextIdent, t.identifier("import")),
|
||||
path.node.arguments));
|
||||
path.replaceWith(
|
||||
t.callExpression(
|
||||
t.memberExpression(contextIdent, t.identifier("import")),
|
||||
path.node.arguments,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
ReferencedIdentifier(path, state) {
|
||||
if (path.node.name == "__moduleName" && !path.scope.hasBinding("__moduleName")) {
|
||||
path.replaceWith(t.memberExpression(state.contextIdent, t.identifier("id")));
|
||||
if (
|
||||
path.node.name == "__moduleName" &&
|
||||
!path.scope.hasBinding("__moduleName")
|
||||
) {
|
||||
path.replaceWith(
|
||||
t.memberExpression(state.contextIdent, t.identifier("id")),
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@ -115,14 +124,16 @@ export default function ({ types: t }) {
|
||||
}
|
||||
});
|
||||
if (!module) {
|
||||
modules.push(module = { key: source, imports: [], exports: [] });
|
||||
modules.push(
|
||||
(module = { key: source, imports: [], exports: [] }),
|
||||
);
|
||||
}
|
||||
module[key] = module[key].concat(specifiers);
|
||||
}
|
||||
|
||||
function buildExportCall(name, val) {
|
||||
return t.expressionStatement(
|
||||
t.callExpression(exportIdent, [t.stringLiteral(name), val])
|
||||
t.callExpression(exportIdent, [t.stringLiteral(name), val]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -154,7 +165,10 @@ export default function ({ types: t }) {
|
||||
path.remove();
|
||||
} else if (path.isExportDefaultDeclaration()) {
|
||||
const declar = path.get("declaration");
|
||||
if (declar.isClassDeclaration() || declar.isFunctionDeclaration()) {
|
||||
if (
|
||||
declar.isClassDeclaration() ||
|
||||
declar.isFunctionDeclaration()
|
||||
) {
|
||||
const id = declar.node.id;
|
||||
const nodes = [];
|
||||
|
||||
@ -163,7 +177,9 @@ export default function ({ types: t }) {
|
||||
nodes.push(buildExportCall("default", id));
|
||||
addExportName(id.name, "default");
|
||||
} else {
|
||||
nodes.push(buildExportCall("default", t.toExpression(declar.node)));
|
||||
nodes.push(
|
||||
buildExportCall("default", t.toExpression(declar.node)),
|
||||
);
|
||||
}
|
||||
|
||||
if (!canHoist || declar.isClassDeclaration()) {
|
||||
@ -212,8 +228,16 @@ export default function ({ types: t }) {
|
||||
const nodes = [];
|
||||
|
||||
for (const specifier of specifiers) {
|
||||
nodes.push(buildExportCall(specifier.exported.name, specifier.local));
|
||||
addExportName(specifier.local.name, specifier.exported.name);
|
||||
nodes.push(
|
||||
buildExportCall(
|
||||
specifier.exported.name,
|
||||
specifier.local,
|
||||
),
|
||||
);
|
||||
addExportName(
|
||||
specifier.local.name,
|
||||
specifier.exported.name,
|
||||
);
|
||||
}
|
||||
|
||||
path.replaceWithMultiple(nodes);
|
||||
@ -229,59 +253,97 @@ export default function ({ types: t }) {
|
||||
|
||||
for (let specifier of specifiers.imports) {
|
||||
if (t.isImportNamespaceSpecifier(specifier)) {
|
||||
setterBody.push(t.expressionStatement(t.assignmentExpression("=", specifier.local, target)));
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression("=", specifier.local, target),
|
||||
),
|
||||
);
|
||||
} else if (t.isImportDefaultSpecifier(specifier)) {
|
||||
specifier = t.importSpecifier(specifier.local, t.identifier("default"));
|
||||
specifier = t.importSpecifier(
|
||||
specifier.local,
|
||||
t.identifier("default"),
|
||||
);
|
||||
}
|
||||
|
||||
if (t.isImportSpecifier(specifier)) {
|
||||
setterBody.push(t.expressionStatement(t.assignmentExpression("=", specifier.local,
|
||||
t.memberExpression(target, specifier.imported))));
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
specifier.local,
|
||||
t.memberExpression(target, specifier.imported),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (specifiers.exports.length) {
|
||||
const exportObjRef = path.scope.generateUidIdentifier("exportObj");
|
||||
const exportObjRef = path.scope.generateUidIdentifier(
|
||||
"exportObj",
|
||||
);
|
||||
|
||||
setterBody.push(t.variableDeclaration("var", [
|
||||
setterBody.push(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(exportObjRef, t.objectExpression([])),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
|
||||
for (const node of specifiers.exports) {
|
||||
if (t.isExportAllDeclaration(node)) {
|
||||
setterBody.push(buildExportAll({
|
||||
setterBody.push(
|
||||
buildExportAll({
|
||||
KEY: path.scope.generateUidIdentifier("key"),
|
||||
EXPORT_OBJ: exportObjRef,
|
||||
TARGET: target,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
} else if (t.isExportSpecifier(node)) {
|
||||
setterBody.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(exportObjRef, node.exported),
|
||||
t.memberExpression(target, node.local))
|
||||
));
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(exportObjRef, node.exported),
|
||||
t.memberExpression(target, node.local),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
||||
setterBody.push(t.expressionStatement(t.callExpression(exportIdent, [exportObjRef])));
|
||||
setterBody.push(
|
||||
t.expressionStatement(
|
||||
t.callExpression(exportIdent, [exportObjRef]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
sources.push(t.stringLiteral(specifiers.key));
|
||||
setters.push(t.functionExpression(null, [target], t.blockStatement(setterBody)));
|
||||
setters.push(
|
||||
t.functionExpression(
|
||||
null,
|
||||
[target],
|
||||
t.blockStatement(setterBody),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
let moduleName = this.getModuleName();
|
||||
if (moduleName) moduleName = t.stringLiteral(moduleName);
|
||||
|
||||
if (canHoist) {
|
||||
hoistVariables(path, (id) => variableIds.push(id));
|
||||
hoistVariables(path, id => variableIds.push(id));
|
||||
}
|
||||
|
||||
if (variableIds.length) {
|
||||
beforeBody.unshift(t.variableDeclaration("var",
|
||||
variableIds.map((id) => t.variableDeclarator(id))));
|
||||
beforeBody.unshift(
|
||||
t.variableDeclaration(
|
||||
"var",
|
||||
variableIds.map(id => t.variableDeclarator(id)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
path.traverse(reassignmentVisitor, {
|
||||
@ -297,7 +359,9 @@ export default function ({ types: t }) {
|
||||
path.node.body = [
|
||||
buildTemplate({
|
||||
SYSTEM_REGISTER: t.memberExpression(
|
||||
t.identifier(state.opts.systemGlobal || "System"), t.identifier("register")),
|
||||
t.identifier(state.opts.systemGlobal || "System"),
|
||||
t.identifier("register"),
|
||||
),
|
||||
BEFORE_BODY: beforeBody,
|
||||
MODULE_NAME: moduleName,
|
||||
SETTERS: setters,
|
||||
|
||||
@ -59,7 +59,7 @@ export default function ({ types: t }) {
|
||||
const func = call.arguments[1];
|
||||
const browserGlobals = state.opts.globals || {};
|
||||
|
||||
const commonArgs = amdArgs.elements.map((arg) => {
|
||||
const commonArgs = amdArgs.elements.map(arg => {
|
||||
if (arg.value === "module" || arg.value === "exports") {
|
||||
return t.identifier(arg.value);
|
||||
} else {
|
||||
@ -67,30 +67,39 @@ export default function ({ types: t }) {
|
||||
}
|
||||
});
|
||||
|
||||
const browserArgs = amdArgs.elements.map((arg) => {
|
||||
const browserArgs = amdArgs.elements.map(arg => {
|
||||
if (arg.value === "module") {
|
||||
return t.identifier("mod");
|
||||
} else if (arg.value === "exports") {
|
||||
return t.memberExpression(t.identifier("mod"), t.identifier("exports"));
|
||||
return t.memberExpression(
|
||||
t.identifier("mod"),
|
||||
t.identifier("exports"),
|
||||
);
|
||||
} else {
|
||||
let memberExpression;
|
||||
|
||||
if (state.opts.exactGlobals) {
|
||||
const globalRef = browserGlobals[arg.value];
|
||||
if (globalRef) {
|
||||
memberExpression = globalRef.split(".").reduce(
|
||||
(accum, curr) => t.memberExpression(accum, t.identifier(curr)), t.identifier("global")
|
||||
memberExpression = globalRef
|
||||
.split(".")
|
||||
.reduce(
|
||||
(accum, curr) =>
|
||||
t.memberExpression(accum, t.identifier(curr)),
|
||||
t.identifier("global"),
|
||||
);
|
||||
} else {
|
||||
memberExpression = t.memberExpression(
|
||||
t.identifier("global"), t.identifier(t.toIdentifier(arg.value))
|
||||
t.identifier("global"),
|
||||
t.identifier(t.toIdentifier(arg.value)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const requireName = basename(arg.value, extname(arg.value));
|
||||
const globalName = browserGlobals[requireName] || requireName;
|
||||
memberExpression = t.memberExpression(
|
||||
t.identifier("global"), t.identifier(t.toIdentifier(globalName))
|
||||
t.identifier("global"),
|
||||
t.identifier(t.toIdentifier(globalName)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -98,10 +107,15 @@ export default function ({ types: t }) {
|
||||
}
|
||||
});
|
||||
|
||||
const moduleNameOrBasename = moduleName ? moduleName.value :
|
||||
basename(this.file.opts.filename, extname(this.file.opts.filename));
|
||||
const moduleNameOrBasename = moduleName
|
||||
? moduleName.value
|
||||
: basename(
|
||||
this.file.opts.filename,
|
||||
extname(this.file.opts.filename),
|
||||
);
|
||||
let globalToAssign = t.memberExpression(
|
||||
t.identifier("global"), t.identifier(t.toIdentifier(moduleNameOrBasename))
|
||||
t.identifier("global"),
|
||||
t.identifier(t.toIdentifier(moduleNameOrBasename)),
|
||||
);
|
||||
let prerequisiteAssignments = null;
|
||||
|
||||
@ -113,7 +127,9 @@ export default function ({ types: t }) {
|
||||
|
||||
const members = globalName.split(".");
|
||||
globalToAssign = members.slice(1).reduce((accum, curr) => {
|
||||
prerequisiteAssignments.push(buildPrerequisiteAssignment({ GLOBAL_REFERENCE: accum }));
|
||||
prerequisiteAssignments.push(
|
||||
buildPrerequisiteAssignment({ GLOBAL_REFERENCE: accum }),
|
||||
);
|
||||
return t.memberExpression(accum, t.identifier(curr));
|
||||
}, t.memberExpression(t.identifier("global"), t.identifier(members[0])));
|
||||
}
|
||||
@ -125,13 +141,15 @@ export default function ({ types: t }) {
|
||||
GLOBAL_TO_ASSIGN: globalToAssign,
|
||||
});
|
||||
|
||||
last.replaceWith(buildWrapper({
|
||||
last.replaceWith(
|
||||
buildWrapper({
|
||||
MODULE_NAME: moduleName,
|
||||
AMD_ARGUMENTS: amdArgs,
|
||||
COMMON_ARGUMENTS: commonArgs,
|
||||
GLOBAL_EXPORT: globalExport,
|
||||
FUNC: func,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -18,15 +18,22 @@ export default function ({ types: t }) {
|
||||
visitor: {
|
||||
ObjectExpression(path, state) {
|
||||
let objectRef;
|
||||
const getObjectRef = () => objectRef = objectRef || path.scope.generateUidIdentifier("obj");
|
||||
const getObjectRef = () =>
|
||||
(objectRef = objectRef || path.scope.generateUidIdentifier("obj"));
|
||||
|
||||
path.get("properties").forEach((propertyPath) => {
|
||||
path.get("properties").forEach(propertyPath => {
|
||||
if (!propertyPath.isMethod()) return;
|
||||
|
||||
const propPaths: Array = path.get("properties");
|
||||
for (let propPath of propPaths) {
|
||||
if (propPath.isObjectProperty()) propPath = propPath.get("value");
|
||||
replacePropertySuper(propPath, propPath.node, path.scope, getObjectRef, state);
|
||||
replacePropertySuper(
|
||||
propPath,
|
||||
propPath.node,
|
||||
path.scope,
|
||||
getObjectRef,
|
||||
state,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -7,7 +7,8 @@ import * as rest from "./rest";
|
||||
|
||||
export default function() {
|
||||
return {
|
||||
visitor: visitors.merge([{
|
||||
visitor: visitors.merge([
|
||||
{
|
||||
ArrowFunctionExpression(path) {
|
||||
// In some conversion cases, it may have already been converted to a function while this callback
|
||||
// was queued up.
|
||||
@ -22,6 +23,10 @@ export default function () {
|
||||
}
|
||||
}
|
||||
},
|
||||
}, destructuring.visitor, rest.visitor, def.visitor]),
|
||||
},
|
||||
destructuring.visitor,
|
||||
rest.visitor,
|
||||
def.visitor,
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
@ -86,37 +86,28 @@ const memberExpressionOptimisationVisitor = {
|
||||
if (parentPath.isMemberExpression({ object: node })) {
|
||||
const grandparentPath = parentPath.parentPath;
|
||||
|
||||
const argsOptEligible = !state.deopted && !(
|
||||
// ex: `args[0] = "whatever"`
|
||||
const argsOptEligible =
|
||||
!state.deopted &&
|
||||
!// ex: `args[0] = "whatever"`
|
||||
(
|
||||
grandparentPath.isAssignmentExpression() &&
|
||||
parentPath.node === grandparentPath.node.left
|
||||
) ||
|
||||
|
||||
(grandparentPath.isAssignmentExpression() &&
|
||||
parentPath.node === grandparentPath.node.left) ||
|
||||
// ex: `[args[0]] = ["whatever"]`
|
||||
grandparentPath.isLVal() ||
|
||||
|
||||
// ex: `for (rest[0] in this)`
|
||||
// ex: `for (rest[0] of this)`
|
||||
grandparentPath.isForXStatement() ||
|
||||
|
||||
// ex: `++args[0]`
|
||||
// ex: `args[0]--`
|
||||
grandparentPath.isUpdateExpression() ||
|
||||
|
||||
// ex: `delete args[0]`
|
||||
grandparentPath.isUnaryExpression({ operator: "delete" }) ||
|
||||
|
||||
// ex: `args[0]()`
|
||||
// ex: `new args[0]()`
|
||||
// ex: `new args[0]`
|
||||
(
|
||||
(
|
||||
grandparentPath.isCallExpression() ||
|
||||
grandparentPath.isNewExpression()
|
||||
) &&
|
||||
parentPath.node === grandparentPath.node.callee
|
||||
)
|
||||
((grandparentPath.isCallExpression() ||
|
||||
grandparentPath.isNewExpression()) &&
|
||||
parentPath.node === grandparentPath.node.callee)
|
||||
);
|
||||
|
||||
if (argsOptEligible) {
|
||||
@ -127,9 +118,8 @@ const memberExpressionOptimisationVisitor = {
|
||||
state.candidates.push({ cause: "indexGetter", path });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (parentPath.node.property.name === "length") {
|
||||
// args.length
|
||||
else if (parentPath.node.property.name === "length") {
|
||||
state.candidates.push({ cause: "lengthGetter", path });
|
||||
return;
|
||||
}
|
||||
@ -177,32 +167,42 @@ function optimiseIndexGetter(path, argsId, offset) {
|
||||
// Avoid unnecessary '+ 0'
|
||||
index = path.parent.property;
|
||||
} else {
|
||||
index = t.binaryExpression("+", path.parent.property, t.numericLiteral(offset));
|
||||
index = t.binaryExpression(
|
||||
"+",
|
||||
path.parent.property,
|
||||
t.numericLiteral(offset),
|
||||
);
|
||||
}
|
||||
|
||||
const { scope } = path;
|
||||
if (!scope.isPure(index)) {
|
||||
const temp = scope.generateUidIdentifierBasedOnNode(index);
|
||||
scope.push({ id: temp, kind: "var" });
|
||||
path.parentPath.replaceWith(restIndexImpure({
|
||||
path.parentPath.replaceWith(
|
||||
restIndexImpure({
|
||||
ARGUMENTS: argsId,
|
||||
INDEX: index,
|
||||
REF: temp,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
path.parentPath.replaceWith(restIndex({
|
||||
path.parentPath.replaceWith(
|
||||
restIndex({
|
||||
ARGUMENTS: argsId,
|
||||
INDEX: index,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function optimiseLengthGetter(path, argsId, offset) {
|
||||
if (offset) {
|
||||
path.parentPath.replaceWith(restLength({
|
||||
path.parentPath.replaceWith(
|
||||
restLength({
|
||||
ARGUMENTS: argsId,
|
||||
OFFSET: t.numericLiteral(offset),
|
||||
}));
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
path.replaceWith(argsId);
|
||||
}
|
||||
@ -266,7 +266,7 @@ export const visitor = {
|
||||
}
|
||||
|
||||
state.references = state.references.concat(
|
||||
state.candidates.map(({ path }) => path)
|
||||
state.candidates.map(({ path }) => path),
|
||||
);
|
||||
|
||||
const start = t.numericLiteral(node.params.length);
|
||||
@ -290,7 +290,7 @@ export const visitor = {
|
||||
arrLen = t.conditionalExpression(
|
||||
t.binaryExpression(">", len, start),
|
||||
t.binaryExpression("-", len, start),
|
||||
t.numericLiteral(0)
|
||||
t.numericLiteral(0),
|
||||
);
|
||||
}
|
||||
|
||||
@ -311,10 +311,12 @@ export const visitor = {
|
||||
// perform allocation at the lowest common ancestor of all references
|
||||
loop._blockHoist = 1;
|
||||
|
||||
let target = path.getEarliestCommonAncestorFrom(state.references).getStatementParent();
|
||||
let target = path
|
||||
.getEarliestCommonAncestorFrom(state.references)
|
||||
.getStatementParent();
|
||||
|
||||
// don't perform the allocation inside a loop
|
||||
target.findParent((path) => {
|
||||
target.findParent(path => {
|
||||
if (path.isLoop()) {
|
||||
target = path;
|
||||
} else {
|
||||
|
||||
@ -6,14 +6,16 @@ export default function () {
|
||||
ObjectMethod(path) {
|
||||
const { node } = path;
|
||||
if (node.kind === "method") {
|
||||
const func = t.functionExpression(null, node.params, node.body, node.generator, node.async);
|
||||
const func = t.functionExpression(
|
||||
null,
|
||||
node.params,
|
||||
node.body,
|
||||
node.generator,
|
||||
node.async,
|
||||
);
|
||||
func.returnType = node.returnType;
|
||||
|
||||
path.replaceWith(t.objectProperty(
|
||||
node.key,
|
||||
func,
|
||||
node.computed
|
||||
));
|
||||
path.replaceWith(t.objectProperty(node.key, func, node.computed));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
export default function({ types: t }) {
|
||||
function getSpreadLiteral(spread, scope, state) {
|
||||
if (state.opts.loose && !t.isIdentifier(spread.argument, { name: "arguments" })) {
|
||||
if (
|
||||
state.opts.loose &&
|
||||
!t.isIdentifier(spread.argument, { name: "arguments" })
|
||||
) {
|
||||
return spread.argument;
|
||||
} else {
|
||||
return scope.toArray(spread.argument, true);
|
||||
@ -55,7 +58,12 @@ export default function ({ types: t }) {
|
||||
first = t.arrayExpression([]);
|
||||
}
|
||||
|
||||
path.replaceWith(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
|
||||
path.replaceWith(
|
||||
t.callExpression(
|
||||
t.memberExpression(first, t.identifier("concat")),
|
||||
nodes,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
CallExpression(path, state) {
|
||||
@ -80,7 +88,12 @@ export default function ({ types: t }) {
|
||||
|
||||
const first = nodes.shift();
|
||||
if (nodes.length) {
|
||||
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
|
||||
node.arguments.push(
|
||||
t.callExpression(
|
||||
t.memberExpression(first, t.identifier("concat")),
|
||||
nodes,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
node.arguments.push(first);
|
||||
}
|
||||
@ -116,10 +129,13 @@ export default function ({ types: t }) {
|
||||
|
||||
const context = t.arrayExpression([t.nullLiteral()]);
|
||||
|
||||
args = t.callExpression(
|
||||
t.memberExpression(context, t.identifier("concat")),
|
||||
nodes,
|
||||
);
|
||||
|
||||
args = t.callExpression(t.memberExpression(context, t.identifier("concat")), nodes);
|
||||
|
||||
path.replaceWith(t.newExpression(
|
||||
path.replaceWith(
|
||||
t.newExpression(
|
||||
t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(
|
||||
@ -127,14 +143,15 @@ export default function ({ types: t }) {
|
||||
t.identifier("Function"),
|
||||
t.identifier("prototype"),
|
||||
),
|
||||
t.identifier("bind")
|
||||
t.identifier("bind"),
|
||||
),
|
||||
t.identifier("apply")
|
||||
t.identifier("apply"),
|
||||
),
|
||||
[node.callee, args]
|
||||
[node.callee, args],
|
||||
),
|
||||
[]
|
||||
));
|
||||
[],
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -8,10 +8,12 @@ export default function () {
|
||||
const { node } = path;
|
||||
if (!regex.is(node, "y")) return;
|
||||
|
||||
path.replaceWith(t.newExpression(t.identifier("RegExp"), [
|
||||
path.replaceWith(
|
||||
t.newExpression(t.identifier("RegExp"), [
|
||||
t.stringLiteral(node.pattern),
|
||||
t.stringLiteral(node.flags),
|
||||
]));
|
||||
]),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
export default function({ types: t }) {
|
||||
|
||||
function buildConcatCallExressions(items) {
|
||||
let avail = true;
|
||||
return items.reduce(function(left, right) {
|
||||
@ -15,7 +14,7 @@ export default function ({ types: t }) {
|
||||
}
|
||||
return t.callExpression(
|
||||
t.memberExpression(left, t.identifier("concat")),
|
||||
[right]
|
||||
[right],
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -23,7 +22,6 @@ export default function ({ types: t }) {
|
||||
return {
|
||||
visitor: {
|
||||
TaggedTemplateExpression(path, state) {
|
||||
|
||||
const { node } = path;
|
||||
const { quasi } = node;
|
||||
|
||||
@ -32,7 +30,8 @@ export default function ({ types: t }) {
|
||||
|
||||
for (const elem of (quasi.quasis: Array)) {
|
||||
const { raw, cooked } = elem.value;
|
||||
const value = cooked == null
|
||||
const value =
|
||||
cooked == null
|
||||
? path.scope.buildUndefinedNode()
|
||||
: t.stringLiteral(cooked);
|
||||
|
||||
@ -46,7 +45,7 @@ export default function ({ types: t }) {
|
||||
const templateObject = state.file.addTemplateObject(
|
||||
templateName,
|
||||
t.arrayExpression(strings),
|
||||
t.arrayExpression(raws)
|
||||
t.arrayExpression(raws),
|
||||
);
|
||||
|
||||
const args = [templateObject].concat(quasi.expressions);
|
||||
@ -75,7 +74,8 @@ export default function ({ types: t }) {
|
||||
|
||||
// since `+` is left-to-right associative
|
||||
// ensure the first node is a string if first/second isn't
|
||||
const considerSecondNode = state.opts.spec || !t.isStringLiteral(nodes[1]);
|
||||
const considerSecondNode =
|
||||
state.opts.spec || !t.isStringLiteral(nodes[1]);
|
||||
if (!t.isStringLiteral(nodes[0]) && considerSecondNode) {
|
||||
nodes.unshift(t.stringLiteral(""));
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ export default function ({ types: t }) {
|
||||
UnaryExpression(path) {
|
||||
const { node, parent } = path;
|
||||
if (node[IGNORE]) return;
|
||||
if (path.find((path) => path.node && !!path.node._generated)) return;
|
||||
if (path.find(path => path.node && !!path.node._generated)) return;
|
||||
|
||||
if (
|
||||
path.parentPath.isBinaryExpression() &&
|
||||
@ -24,7 +24,8 @@ export default function ({ types: t }) {
|
||||
// need to handle symbols
|
||||
const opposite = path.getOpposite();
|
||||
if (
|
||||
opposite.isLiteral() && opposite.node.value !== "symbol" &&
|
||||
opposite.isLiteral() &&
|
||||
opposite.node.value !== "symbol" &&
|
||||
opposite.node.value !== "object"
|
||||
) {
|
||||
return;
|
||||
@ -32,16 +33,20 @@ export default function ({ types: t }) {
|
||||
}
|
||||
|
||||
if (node.operator === "typeof") {
|
||||
const call = t.callExpression(this.addHelper("typeof"), [node.argument]);
|
||||
const call = t.callExpression(this.addHelper("typeof"), [
|
||||
node.argument,
|
||||
]);
|
||||
if (path.get("argument").isIdentifier()) {
|
||||
const undefLiteral = t.stringLiteral("undefined");
|
||||
const unary = t.unaryExpression("typeof", node.argument);
|
||||
unary[IGNORE] = true;
|
||||
path.replaceWith(t.conditionalExpression(
|
||||
path.replaceWith(
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", unary, undefLiteral),
|
||||
undefLiteral,
|
||||
call
|
||||
));
|
||||
call,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
path.replaceWith(call);
|
||||
}
|
||||
|
||||
@ -4,7 +4,11 @@ export default function ({ types: t }) {
|
||||
MemberExpression: {
|
||||
exit({ node }) {
|
||||
const prop = node.property;
|
||||
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
if (
|
||||
!node.computed &&
|
||||
t.isIdentifier(prop) &&
|
||||
!t.isValidIdentifier(prop.name)
|
||||
) {
|
||||
// foo.default -> foo["default"]
|
||||
node.property = t.stringLiteral(prop.name);
|
||||
node.computed = true;
|
||||
|
||||
@ -4,7 +4,11 @@ export default function ({ types: t }) {
|
||||
ObjectProperty: {
|
||||
exit({ node }) {
|
||||
const key = node.key;
|
||||
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
if (
|
||||
!node.computed &&
|
||||
t.isIdentifier(key) &&
|
||||
!t.isValidIdentifier(key.name)
|
||||
) {
|
||||
// default: "bar" -> "default": "bar"
|
||||
node.key = t.stringLiteral(key.name);
|
||||
}
|
||||
|
||||
@ -25,10 +25,15 @@ export default function ({ types: t }) {
|
||||
}
|
||||
});
|
||||
|
||||
path.replaceWith(t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
|
||||
[node, defineMap.toDefineObject(mutatorMap)]
|
||||
));
|
||||
path.replaceWith(
|
||||
t.callExpression(
|
||||
t.memberExpression(
|
||||
t.identifier("Object"),
|
||||
t.identifier("defineProperties"),
|
||||
),
|
||||
[node, defineMap.toDefineObject(mutatorMap)],
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -2,7 +2,10 @@ export default function ({ parse, traverse }) {
|
||||
return {
|
||||
visitor: {
|
||||
CallExpression(path) {
|
||||
if (path.get("callee").isIdentifier({ name: "eval" }) && path.node.arguments.length === 1) {
|
||||
if (
|
||||
path.get("callee").isIdentifier({ name: "eval" }) &&
|
||||
path.node.arguments.length === 1
|
||||
) {
|
||||
const evaluate = path.get("arguments")[0].evaluate();
|
||||
if (!evaluate.confident) return;
|
||||
|
||||
|
||||
@ -9,7 +9,10 @@ export default function ({ types: t }) {
|
||||
operator: "**",
|
||||
|
||||
build(left, right) {
|
||||
return t.callExpression(t.memberExpression(t.identifier("Math"), t.identifier("pow")), [left, right]);
|
||||
return t.callExpression(
|
||||
t.memberExpression(t.identifier("Math"), t.identifier("pow")),
|
||||
[left, right],
|
||||
);
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
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