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("default", ["build"]);
|
||||||
|
|
||||||
gulp.task("build", function() {
|
gulp.task("build", function() {
|
||||||
return gulp.src(scripts, { base: base })
|
return gulp
|
||||||
.pipe(plumber({
|
.src(scripts, { base: base })
|
||||||
|
.pipe(
|
||||||
|
plumber({
|
||||||
errorHandler: function(err) {
|
errorHandler: function(err) {
|
||||||
gutil.log(err.stack);
|
gutil.log(err.stack);
|
||||||
},
|
},
|
||||||
}))
|
})
|
||||||
.pipe(newer({
|
)
|
||||||
|
.pipe(
|
||||||
|
newer({
|
||||||
dest: base,
|
dest: base,
|
||||||
map: swapSrcWithLib,
|
map: swapSrcWithLib,
|
||||||
}))
|
})
|
||||||
.pipe(through.obj(function (file, enc, callback) {
|
)
|
||||||
|
.pipe(
|
||||||
|
through.obj(function(file, enc, callback) {
|
||||||
gutil.log("Compiling", "'" + chalk.cyan(file.relative) + "'...");
|
gutil.log("Compiling", "'" + chalk.cyan(file.relative) + "'...");
|
||||||
callback(null, file);
|
callback(null, file);
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(babel())
|
.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.
|
// Passing 'file.relative' because newer() above uses a relative path and this keeps it consistent.
|
||||||
file.path = path.resolve(file.base, swapSrcWithLib(file.relative));
|
file.path = path.resolve(file.base, swapSrcWithLib(file.relative));
|
||||||
callback(null, file);
|
callback(null, file);
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
.pipe(gulp.dest(base));
|
.pipe(gulp.dest(base));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -24,9 +24,21 @@ function collect(value, previousValue): Array<string> {
|
|||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
program.option("-e, --eval [script]", "Evaluate script");
|
program.option("-e, --eval [script]", "Evaluate script");
|
||||||
program.option("-p, --print [code]", "Evaluate script and print result");
|
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(
|
||||||
program.option("-i, --ignore [globs]", "A comma-separated list of glob patterns to skip compiling", collect);
|
"-o, --only [globs]",
|
||||||
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx,.mjs]", collect);
|
"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("-w, --plugins [string]", "", collect);
|
||||||
program.option("-b, --presets [string]", "", collect);
|
program.option("-b, --presets [string]", "", collect);
|
||||||
/* eslint-enable max-len */
|
/* eslint-enable max-len */
|
||||||
@ -55,16 +67,21 @@ const replPlugin = ({ types: t }) => ({
|
|||||||
|
|
||||||
VariableDeclaration(path) {
|
VariableDeclaration(path) {
|
||||||
if (path.node.kind !== "var") {
|
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) {
|
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,
|
// If the executed code doesn't evaluate to a value,
|
||||||
// prevent implicit strict mode from printing 'use strict'.
|
// 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
|
// make the filename absolute
|
||||||
const filename = args[0];
|
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
|
// add back on node and concat the sliced args
|
||||||
process.argv = ["node"].concat(args);
|
process.argv = ["node"].concat(args);
|
||||||
|
|||||||
@ -10,8 +10,16 @@ function collect(value, previousValue): Array<string> {
|
|||||||
return previousValue ? previousValue.concat(values) : values;
|
return previousValue ? previousValue.concat(values) : values;
|
||||||
}
|
}
|
||||||
|
|
||||||
commander.option("-l, --whitelist [whitelist]", "Whitelist of helpers to ONLY include", collect);
|
commander.option(
|
||||||
commander.option("-t, --output-type [type]", "Type of output (global|umd|var)", "global");
|
"-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.usage("[options]");
|
||||||
commander.parse(process.argv);
|
commander.parse(process.argv);
|
||||||
|
|||||||
@ -59,7 +59,10 @@ getV8Flags(function (err, v8Flags) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 || arg.indexOf("--trace") === 0) {
|
if (
|
||||||
|
v8Flags.indexOf(getNormalizedV8Flag(flag)) >= 0 ||
|
||||||
|
arg.indexOf("--trace") === 0
|
||||||
|
) {
|
||||||
args.unshift(arg);
|
args.unshift(arg);
|
||||||
} else {
|
} else {
|
||||||
args.push(arg);
|
args.push(arg);
|
||||||
@ -80,7 +83,9 @@ getV8Flags(function (err, v8Flags) {
|
|||||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||||
|
|
||||||
const child_process = require("child_process");
|
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) {
|
proc.on("exit", function(code, signal) {
|
||||||
process.on("exit", function() {
|
process.on("exit", function() {
|
||||||
if (signal) {
|
if (signal) {
|
||||||
|
|||||||
@ -8,17 +8,25 @@ import * as util from "./util";
|
|||||||
|
|
||||||
export default function(commander, filenames, opts) {
|
export default function(commander, filenames, opts) {
|
||||||
function write(src, relative) {
|
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
|
// remove extension and then append back on .js
|
||||||
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
|
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||||
|
|
||||||
const dest = path.join(commander.outDir, relative);
|
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)),
|
sourceFileName: slash(path.relative(dest + "/..", src)),
|
||||||
sourceMapTarget: path.basename(relative),
|
sourceMapTarget: path.basename(relative),
|
||||||
}, opts));
|
},
|
||||||
|
opts,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (!data) return false;
|
if (!data) return false;
|
||||||
|
|
||||||
|
|||||||
@ -39,14 +39,17 @@ export default function (commander, filenames, opts) {
|
|||||||
column: mapping.generatedColumn,
|
column: mapping.generatedColumn,
|
||||||
},
|
},
|
||||||
source: mapping.source,
|
source: mapping.source,
|
||||||
original: mapping.source == null ? null : {
|
original:
|
||||||
|
mapping.source == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
line: mapping.originalLine,
|
line: mapping.originalLine,
|
||||||
column: mapping.originalColumn,
|
column: mapping.originalColumn,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
sources.forEach((source) => {
|
sources.forEach(source => {
|
||||||
const content = consumer.sourceContentFor(source, true);
|
const content = consumer.sourceContentFor(source, true);
|
||||||
if (content !== null) {
|
if (content !== null) {
|
||||||
map.setSourceContent(source, content);
|
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
|
// add the inline sourcemap comment if we've either explicitly asked for inline source
|
||||||
// maps, or we've requested them without any output file
|
// 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();
|
code += "\n" + convertSourceMap.fromObject(map).toComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,9 +103,18 @@ export default function (commander, filenames, opts) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
process.stdin.on("end", function() {
|
process.stdin.on("end", function() {
|
||||||
results.push(util.transform(commander.filename, code, defaults({
|
results.push(
|
||||||
|
util.transform(
|
||||||
|
commander.filename,
|
||||||
|
code,
|
||||||
|
defaults(
|
||||||
|
{
|
||||||
sourceFileName: "stdin",
|
sourceFileName: "stdin",
|
||||||
}, opts)));
|
},
|
||||||
|
opts,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
output();
|
output();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -126,13 +141,22 @@ export default function (commander, filenames, opts) {
|
|||||||
_filenames.forEach(function(filename) {
|
_filenames.forEach(function(filename) {
|
||||||
let sourceFilename = filename;
|
let sourceFilename = filename;
|
||||||
if (commander.outFile) {
|
if (commander.outFile) {
|
||||||
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
|
sourceFilename = path.relative(
|
||||||
|
path.dirname(commander.outFile),
|
||||||
|
sourceFilename,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
sourceFilename = slash(sourceFilename);
|
sourceFilename = slash(sourceFilename);
|
||||||
|
|
||||||
const data = util.compile(filename, defaults({
|
const data = util.compile(
|
||||||
|
filename,
|
||||||
|
defaults(
|
||||||
|
{
|
||||||
sourceFileName: sourceFilename,
|
sourceFileName: sourceFilename,
|
||||||
}, opts));
|
},
|
||||||
|
opts,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
@ -143,22 +167,25 @@ export default function (commander, filenames, opts) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const files = function() {
|
const files = function() {
|
||||||
|
|
||||||
if (!commander.skipInitialBuild) {
|
if (!commander.skipInitialBuild) {
|
||||||
walk();
|
walk();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commander.watch) {
|
if (commander.watch) {
|
||||||
const chokidar = util.requireChokidar();
|
const chokidar = util.requireChokidar();
|
||||||
chokidar.watch(filenames, {
|
chokidar
|
||||||
|
.watch(filenames, {
|
||||||
persistent: true,
|
persistent: true,
|
||||||
ignoreInitial: true,
|
ignoreInitial: true,
|
||||||
awaitWriteFinish: {
|
awaitWriteFinish: {
|
||||||
stabilityThreshold: 50,
|
stabilityThreshold: 50,
|
||||||
pollInterval: 10,
|
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") {
|
if (type === "add" || type === "change") {
|
||||||
util.log(type + " " + filename);
|
util.log(type + " " + filename);
|
||||||
|
|||||||
@ -34,45 +34,117 @@ function collect(value, previousValue): Array<string> {
|
|||||||
|
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
// Standard Babel input configs.
|
// 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(
|
||||||
commander.option("--presets [list]", "comma-separated list of preset names", collect);
|
"-f, --filename [filename]",
|
||||||
commander.option("--plugins [list]", "comma-separated list of plugin names", collect);
|
"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.
|
// Basic file input configuration.
|
||||||
commander.option("--source-type [script|module]", "");
|
commander.option("--source-type [script|module]", "");
|
||||||
commander.option("--no-babelrc", "Whether or not to look up .babelrc and .babelignore files");
|
commander.option(
|
||||||
commander.option("--ignore [list]", "list of glob paths to **not** compile", collect);
|
"--no-babelrc",
|
||||||
commander.option("--only [list]", "list of glob paths to **only** compile", collect);
|
"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.
|
// 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.
|
// General output formatting.
|
||||||
commander.option("--no-comments", "write comments to generated output (true by default)");
|
commander.option(
|
||||||
commander.option("--retain-lines", "retain line numbers - will result in really ugly code");
|
"--no-comments",
|
||||||
commander.option("--compact [true|false|auto]", "do not include superfluous whitespace characters and line terminators", booleanify);
|
"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("--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(
|
||||||
commander.option("--auxiliary-comment-after [string]", "print a comment after any injected non-user code");
|
"--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.
|
// General soucemap formatting.
|
||||||
commander.option("-s, --source-maps [true|false|inline|both]", "", booleanify);
|
commander.option("-s, --source-maps [true|false|inline|both]", "", booleanify);
|
||||||
commander.option("--source-map-target [string]", "set `file` on returned source map");
|
commander.option(
|
||||||
commander.option("--source-file-name [string]", "set `sources[0]` on returned source map");
|
"--source-map-target [string]",
|
||||||
commander.option("--source-root [filename]", "the root from which all sources are relative");
|
"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.
|
// 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("-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.
|
// "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("-w, --watch", "Recompile files on changes");
|
||||||
commander.option("--skip-initial-build", "Do not compile files before watching");
|
commander.option(
|
||||||
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
|
"--skip-initial-build",
|
||||||
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
|
"Do not compile files before watching",
|
||||||
commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files");
|
);
|
||||||
|
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");
|
commander.option("-q, --quiet", "Don't log anything");
|
||||||
/* eslint-enable max-len */
|
/* eslint-enable max-len */
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,10 @@ export { readdir };
|
|||||||
/**
|
/**
|
||||||
* Test if a filename ends with a compilable extension.
|
* 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 exts = altExts || babel.DEFAULT_EXTENSIONS;
|
||||||
const ext = path.extname(filename);
|
const ext = path.extname(filename);
|
||||||
return includes(exts, ext);
|
return includes(exts, ext);
|
||||||
@ -74,7 +77,7 @@ export function requireChokidar() {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
"The optional dependency chokidar failed to install and is required for " +
|
"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;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,8 +53,13 @@ const assertTest = function (stdout, stderr, opts) {
|
|||||||
|
|
||||||
if (opts.stderr) {
|
if (opts.stderr) {
|
||||||
if (opts.stderrContains) {
|
if (opts.stderrContains) {
|
||||||
assert.ok(includes(stderr, expectStderr), "stderr " + JSON.stringify(stderr) +
|
assert.ok(
|
||||||
" didn't contain " + JSON.stringify(expectStderr));
|
includes(stderr, expectStderr),
|
||||||
|
"stderr " +
|
||||||
|
JSON.stringify(stderr) +
|
||||||
|
" didn't contain " +
|
||||||
|
JSON.stringify(expectStderr),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
chai.expect(stderr).to.equal(expectStderr, "stderr didn't match");
|
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.stdout) {
|
||||||
if (opts.stdoutContains) {
|
if (opts.stdoutContains) {
|
||||||
assert.ok(includes(stdout, expectStdout), "stdout " + JSON.stringify(stdout) +
|
assert.ok(
|
||||||
" didn't contain " + JSON.stringify(expectStdout));
|
includes(stdout, expectStdout),
|
||||||
|
"stdout " +
|
||||||
|
JSON.stringify(stdout) +
|
||||||
|
" didn't contain " +
|
||||||
|
JSON.stringify(expectStdout),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
chai.expect(stdout).to.equal(expectStdout, "stdout didn't match");
|
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 expect = opts.outFiles[filename];
|
||||||
const actual = actualFiles[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) {
|
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) {
|
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);
|
.to.contain.key(filename);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -142,7 +156,8 @@ const buildTest = function (binName, testName, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
err.message = args.map((arg) => `"${ arg }"`).join(" ") + ": " + err.message;
|
err.message =
|
||||||
|
args.map(arg => `"${arg}"`).join(" ") + ": " + err.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(err);
|
callback(err);
|
||||||
|
|||||||
@ -94,7 +94,7 @@ function highlight(defs: Object, text: string) {
|
|||||||
const type = getTokenType(args);
|
const type = getTokenType(args);
|
||||||
const colorize = defs[type];
|
const colorize = defs[type];
|
||||||
if (colorize) {
|
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 {
|
} else {
|
||||||
return args[0];
|
return args[0];
|
||||||
}
|
}
|
||||||
@ -106,9 +106,15 @@ function highlight(defs: Object, text: string) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function getMarkerLines(
|
function getMarkerLines(
|
||||||
loc: NodeLocation, source: Array<string>, opts: Object
|
loc: NodeLocation,
|
||||||
|
source: Array<string>,
|
||||||
|
opts: Object,
|
||||||
): { start: number, end: number, markerLines: 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 endLoc: Location = Object.assign({}, startLoc, loc.end);
|
||||||
const linesAbove = opts.linesAbove || 2;
|
const linesAbove = opts.linesAbove || 2;
|
||||||
const linesBelow = opts.linesBelow || 3;
|
const linesBelow = opts.linesBelow || 3;
|
||||||
@ -170,7 +176,8 @@ export function codeFrameColumns (
|
|||||||
loc: NodeLocation,
|
loc: NodeLocation,
|
||||||
opts: Object = {},
|
opts: Object = {},
|
||||||
): string {
|
): string {
|
||||||
const highlighted = (opts.highlightCode && Chalk.supportsColor) || opts.forceColor;
|
const highlighted =
|
||||||
|
(opts.highlightCode && Chalk.supportsColor) || opts.forceColor;
|
||||||
let chalk = Chalk;
|
let chalk = Chalk;
|
||||||
if (opts.forceColor) {
|
if (opts.forceColor) {
|
||||||
chalk = new Chalk.constructor({ enabled: true });
|
chalk = new Chalk.constructor({ enabled: true });
|
||||||
@ -186,7 +193,9 @@ export function codeFrameColumns (
|
|||||||
|
|
||||||
const numberMaxWidth = String(end).length;
|
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 number = start + 1 + index;
|
||||||
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
||||||
const gutter = ` ${paddedNumber} | `;
|
const gutter = ` ${paddedNumber} | `;
|
||||||
@ -194,7 +203,9 @@ export function codeFrameColumns (
|
|||||||
if (hasMarker) {
|
if (hasMarker) {
|
||||||
let markerLine = "";
|
let markerLine = "";
|
||||||
if (Array.isArray(hasMarker)) {
|
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;
|
const numberOfMarkers = hasMarker[1] || 1;
|
||||||
|
|
||||||
markerLine = [
|
markerLine = [
|
||||||
@ -213,7 +224,8 @@ export function codeFrameColumns (
|
|||||||
} else {
|
} else {
|
||||||
return ` ${maybeHighlight(defs.gutter, gutter)}${line}`;
|
return ` ${maybeHighlight(defs.gutter, gutter)}${line}`;
|
||||||
}
|
}
|
||||||
}).join("\n");
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
if (highlighted) {
|
if (highlighted) {
|
||||||
return chalk.reset(frame);
|
return chalk.reset(frame);
|
||||||
@ -236,7 +248,7 @@ export default function (
|
|||||||
deprecationWarningShown = true;
|
deprecationWarningShown = true;
|
||||||
|
|
||||||
const deprecationError = new Error(
|
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";
|
deprecationError.name = "DeprecationWarning";
|
||||||
|
|
||||||
@ -249,7 +261,9 @@ export default function (
|
|||||||
|
|
||||||
colNumber = Math.max(colNumber, 0);
|
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);
|
return codeFrameColumns(rawLines, location, opts);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,30 +4,24 @@ import codeFrame, { codeFrameColumns } from "..";
|
|||||||
|
|
||||||
describe("babel-code-frame", function() {
|
describe("babel-code-frame", function() {
|
||||||
it("basic usage", function() {
|
it("basic usage", function() {
|
||||||
const rawLines = [
|
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||||
"class Foo {",
|
assert.equal(
|
||||||
" constructor()",
|
codeFrame(rawLines, 2, 16),
|
||||||
"};",
|
[
|
||||||
].join("\n");
|
|
||||||
assert.equal(codeFrame(rawLines, 2, 16), [
|
|
||||||
" 1 | class Foo {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor()",
|
"> 2 | constructor()",
|
||||||
" | ^",
|
" | ^",
|
||||||
" 3 | };",
|
" 3 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("optional column number", function() {
|
it("optional column number", function() {
|
||||||
const rawLines = [
|
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||||
"class Foo {",
|
assert.equal(
|
||||||
" constructor()",
|
codeFrame(rawLines, 2, null),
|
||||||
"};",
|
[" 1 | class Foo {", "> 2 | constructor()", " 3 | };"].join("\n"),
|
||||||
].join("\n");
|
);
|
||||||
assert.equal(codeFrame(rawLines, 2, null), [
|
|
||||||
" 1 | class Foo {",
|
|
||||||
"> 2 | constructor()",
|
|
||||||
" 3 | };",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("maximum context lines and padding", function() {
|
it("maximum context lines and padding", function() {
|
||||||
@ -44,7 +38,9 @@ describe("babel-code-frame", function () {
|
|||||||
" return a + b",
|
" return a + b",
|
||||||
"}",
|
"}",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 7, 2), [
|
assert.equal(
|
||||||
|
codeFrame(rawLines, 7, 2),
|
||||||
|
[
|
||||||
" 5 | * @param b Number",
|
" 5 | * @param b Number",
|
||||||
" 6 | * @returns Number",
|
" 6 | * @returns Number",
|
||||||
"> 7 | */",
|
"> 7 | */",
|
||||||
@ -52,7 +48,8 @@ describe("babel-code-frame", function () {
|
|||||||
" 8 | ",
|
" 8 | ",
|
||||||
" 9 | function sum(a, b) {",
|
" 9 | function sum(a, b) {",
|
||||||
" 10 | return a + b",
|
" 10 | return a + b",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("no unnecessary padding due to one-off errors", function() {
|
it("no unnecessary padding due to one-off errors", function() {
|
||||||
@ -69,7 +66,9 @@ describe("babel-code-frame", function () {
|
|||||||
" return a + b",
|
" return a + b",
|
||||||
"}",
|
"}",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 6, 2), [
|
assert.equal(
|
||||||
|
codeFrame(rawLines, 6, 2),
|
||||||
|
[
|
||||||
" 4 | * @param a Number",
|
" 4 | * @param a Number",
|
||||||
" 5 | * @param b Number",
|
" 5 | * @param b Number",
|
||||||
"> 6 | * @returns Number",
|
"> 6 | * @returns Number",
|
||||||
@ -77,7 +76,8 @@ describe("babel-code-frame", function () {
|
|||||||
" 7 | */",
|
" 7 | */",
|
||||||
" 8 | ",
|
" 8 | ",
|
||||||
" 9 | function sum(a, b) {",
|
" 9 | function sum(a, b) {",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("tabs", function() {
|
it("tabs", function() {
|
||||||
@ -86,12 +86,15 @@ describe("babel-code-frame", function () {
|
|||||||
"\t \t\t constructor\t(\t)",
|
"\t \t\t constructor\t(\t)",
|
||||||
"\t};",
|
"\t};",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 2, 25), [
|
assert.equal(
|
||||||
|
codeFrame(rawLines, 2, 25),
|
||||||
|
[
|
||||||
" 1 | \tclass Foo {",
|
" 1 | \tclass Foo {",
|
||||||
"> 2 | \t \t\t constructor\t(\t)",
|
"> 2 | \t \t\t constructor\t(\t)",
|
||||||
" | \t \t\t \t \t ^",
|
" | \t \t\t \t \t ^",
|
||||||
" 3 | \t};",
|
" 3 | \t};",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opts.highlightCode", function() {
|
it("opts.highlightCode", function() {
|
||||||
@ -99,10 +102,10 @@ describe("babel-code-frame", function () {
|
|||||||
const result = codeFrame(rawLines, 1, 9, { highlightCode: true });
|
const result = codeFrame(rawLines, 1, 9, { highlightCode: true });
|
||||||
const stripped = chalk.stripColor(result);
|
const stripped = chalk.stripColor(result);
|
||||||
assert.ok(result.length > stripped.length);
|
assert.ok(result.length > stripped.length);
|
||||||
assert.equal(stripped, [
|
assert.equal(
|
||||||
"> 1 | console.log('babel')",
|
stripped,
|
||||||
" | ^",
|
["> 1 | console.log('babel')", " | ^"].join("\n"),
|
||||||
].join("\n"));
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opts.linesAbove", function() {
|
it("opts.linesAbove", function() {
|
||||||
@ -119,14 +122,17 @@ describe("babel-code-frame", function () {
|
|||||||
" return a + b",
|
" return a + b",
|
||||||
"}",
|
"}",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 7, 2, { linesAbove: 1 }), [
|
assert.equal(
|
||||||
|
codeFrame(rawLines, 7, 2, { linesAbove: 1 }),
|
||||||
|
[
|
||||||
" 6 | * @returns Number",
|
" 6 | * @returns Number",
|
||||||
"> 7 | */",
|
"> 7 | */",
|
||||||
" | ^",
|
" | ^",
|
||||||
" 8 | ",
|
" 8 | ",
|
||||||
" 9 | function sum(a, b) {",
|
" 9 | function sum(a, b) {",
|
||||||
" 10 | return a + b",
|
" 10 | return a + b",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opts.linesBelow", function() {
|
it("opts.linesBelow", function() {
|
||||||
@ -143,13 +149,16 @@ describe("babel-code-frame", function () {
|
|||||||
" return a + b",
|
" return a + b",
|
||||||
"}",
|
"}",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 7, 2, { linesBelow: 1 }), [
|
assert.equal(
|
||||||
|
codeFrame(rawLines, 7, 2, { linesBelow: 1 }),
|
||||||
|
[
|
||||||
" 5 | * @param b Number",
|
" 5 | * @param b Number",
|
||||||
" 6 | * @returns Number",
|
" 6 | * @returns Number",
|
||||||
"> 7 | */",
|
"> 7 | */",
|
||||||
" | ^",
|
" | ^",
|
||||||
" 8 | ",
|
" 8 | ",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opts.linesAbove and opts.linesBelow", function() {
|
it("opts.linesAbove and opts.linesBelow", function() {
|
||||||
@ -166,78 +175,82 @@ describe("babel-code-frame", function () {
|
|||||||
" return a + b",
|
" return a + b",
|
||||||
"}",
|
"}",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(codeFrame(rawLines, 7, 2, { linesAbove: 1, linesBelow: 1 }), [
|
assert.equal(
|
||||||
" 6 | * @returns Number",
|
codeFrame(rawLines, 7, 2, { linesAbove: 1, linesBelow: 1 }),
|
||||||
"> 7 | */",
|
[" 6 | * @returns Number", "> 7 | */", " | ^", " 8 | "].join(
|
||||||
" | ^",
|
"\n",
|
||||||
" 8 | ",
|
),
|
||||||
].join("\n"));
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opts.forceColor", function() {
|
it("opts.forceColor", function() {
|
||||||
const marker = chalk.red.bold;
|
const marker = chalk.red.bold;
|
||||||
const gutter = chalk.grey;
|
const gutter = chalk.grey;
|
||||||
|
|
||||||
const rawLines = [
|
const rawLines = ["", "", "", ""].join("\n");
|
||||||
"",
|
assert.equal(
|
||||||
"",
|
codeFrame(rawLines, 3, null, {
|
||||||
"",
|
linesAbove: 1,
|
||||||
"",
|
linesBelow: 1,
|
||||||
].join("\n");
|
forceColor: true,
|
||||||
assert.equal(codeFrame(rawLines, 3, null, { linesAbove: 1, linesBelow: 1, forceColor: true }),
|
}),
|
||||||
chalk.reset([
|
chalk.reset(
|
||||||
|
[
|
||||||
" " + gutter(" 2 | "),
|
" " + gutter(" 2 | "),
|
||||||
marker(">") + gutter(" 3 | "),
|
marker(">") + gutter(" 3 | "),
|
||||||
" " + gutter(" 4 | "),
|
" " + gutter(" 4 | "),
|
||||||
].join("\n"))
|
].join("\n"),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("basic usage, new API", function() {
|
it("basic usage, new API", function() {
|
||||||
const rawLines = [
|
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||||
"class Foo {",
|
assert.equal(
|
||||||
" constructor()",
|
codeFrameColumns(rawLines, { start: { line: 2, column: 16 } }),
|
||||||
"};",
|
[
|
||||||
].join("\n");
|
|
||||||
assert.equal(codeFrameColumns(rawLines, { start: { line: 2, column: 16 } }), [
|
|
||||||
" 1 | class Foo {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor()",
|
"> 2 | constructor()",
|
||||||
" | ^",
|
" | ^",
|
||||||
" 3 | };",
|
" 3 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mark multiple columns", function() {
|
it("mark multiple columns", function() {
|
||||||
const rawLines = [
|
const rawLines = ["class Foo {", " constructor()", "};"].join("\n");
|
||||||
"class Foo {",
|
|
||||||
" constructor()",
|
|
||||||
"};",
|
|
||||||
].join("\n");
|
|
||||||
assert.equal(
|
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 {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor()",
|
"> 2 | constructor()",
|
||||||
" | ^^^^^^^^^^^^^",
|
" | ^^^^^^^^^^^^^",
|
||||||
" 3 | };",
|
" 3 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mark multiple columns across lines", function() {
|
it("mark multiple columns across lines", function() {
|
||||||
const rawLines = [
|
const rawLines = ["class Foo {", " constructor() {", " }", "};"].join(
|
||||||
"class Foo {",
|
"\n",
|
||||||
" constructor() {",
|
);
|
||||||
" }",
|
|
||||||
"};",
|
|
||||||
].join("\n");
|
|
||||||
assert.equal(
|
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 {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor() {",
|
"> 2 | constructor() {",
|
||||||
" | ^",
|
" | ^",
|
||||||
"> 3 | }",
|
"> 3 | }",
|
||||||
" | ^^^",
|
" | ^^^",
|
||||||
" 4 | };",
|
" 4 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mark multiple columns across multiple lines", function() {
|
it("mark multiple columns across multiple lines", function() {
|
||||||
@ -249,7 +262,11 @@ describe("babel-code-frame", function () {
|
|||||||
"};",
|
"};",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(
|
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 {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor() {",
|
"> 2 | constructor() {",
|
||||||
" | ^",
|
" | ^",
|
||||||
@ -258,7 +275,8 @@ describe("babel-code-frame", function () {
|
|||||||
"> 4 | }",
|
"> 4 | }",
|
||||||
" | ^^^",
|
" | ^^^",
|
||||||
" 5 | };",
|
" 5 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("mark across multiple lines without columns", function() {
|
it("mark across multiple lines without columns", function() {
|
||||||
@ -270,12 +288,14 @@ describe("babel-code-frame", function () {
|
|||||||
"};",
|
"};",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
assert.equal(
|
assert.equal(
|
||||||
codeFrameColumns(rawLines, { start: { line: 2 }, end: { line: 4 } }), [
|
codeFrameColumns(rawLines, { start: { line: 2 }, end: { line: 4 } }),
|
||||||
|
[
|
||||||
" 1 | class Foo {",
|
" 1 | class Foo {",
|
||||||
"> 2 | constructor() {",
|
"> 2 | constructor() {",
|
||||||
"> 3 | console.log(arguments);",
|
"> 3 | console.log(arguments);",
|
||||||
"> 4 | }",
|
"> 4 | }",
|
||||||
" 5 | };",
|
" 5 | };",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -57,16 +57,14 @@ class ConfigChainBuilder {
|
|||||||
/**
|
/**
|
||||||
* Tests if a filename should be ignored based on "ignore" and "only" options.
|
* Tests if a filename should be ignored based on "ignore" and "only" options.
|
||||||
*/
|
*/
|
||||||
shouldIgnore(
|
shouldIgnore(ignore: mixed, only: mixed, dirname: string): boolean {
|
||||||
ignore: mixed,
|
|
||||||
only: mixed,
|
|
||||||
dirname: string,
|
|
||||||
): boolean {
|
|
||||||
if (!this.filename) return false;
|
if (!this.filename) return false;
|
||||||
|
|
||||||
if (ignore) {
|
if (ignore) {
|
||||||
if (!Array.isArray(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;
|
if (this.matchesPatterns(ignore, dirname)) return true;
|
||||||
@ -74,7 +72,9 @@ class ConfigChainBuilder {
|
|||||||
|
|
||||||
if (only) {
|
if (only) {
|
||||||
if (!Array.isArray(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;
|
if (!this.matchesPatterns(only, dirname)) return true;
|
||||||
@ -89,21 +89,27 @@ class ConfigChainBuilder {
|
|||||||
*/
|
*/
|
||||||
matchesPatterns(patterns: Array<mixed>, dirname: string) {
|
matchesPatterns(patterns: Array<mixed>, dirname: string) {
|
||||||
const filename = this.filename;
|
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 res = [];
|
||||||
const strings = [];
|
const strings = [];
|
||||||
const fns = [];
|
const fns = [];
|
||||||
|
|
||||||
patterns.forEach((pattern) => {
|
patterns.forEach(pattern => {
|
||||||
if (typeof pattern === "string") strings.push(pattern);
|
if (typeof pattern === "string") strings.push(pattern);
|
||||||
else if (typeof pattern === "function") fns.push(pattern);
|
else if (typeof pattern === "function") fns.push(pattern);
|
||||||
else if (pattern instanceof RegExp) res.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 (res.some(re => re.test(filename))) return true;
|
||||||
if (fns.some((fn) => fn(filename))) return true;
|
if (fns.some(fn => fn(filename))) return true;
|
||||||
|
|
||||||
if (strings.length > 0) {
|
if (strings.length > 0) {
|
||||||
let possibleDirs = this.possibleDirs;
|
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.
|
// Preserve the "!" prefix so that micromatch can use it for negation.
|
||||||
const negate = pattern[0] === "!";
|
const negate = pattern[0] === "!";
|
||||||
if (negate) pattern = pattern.slice(1);
|
if (negate) pattern = pattern.slice(1);
|
||||||
@ -131,7 +137,9 @@ class ConfigChainBuilder {
|
|||||||
return (negate ? "!" : "") + path.resolve(dirname, pattern);
|
return (negate ? "!" : "") + path.resolve(dirname, pattern);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0) {
|
if (
|
||||||
|
micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,16 +158,16 @@ class ConfigChainBuilder {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeConfig({
|
mergeConfig({ type, options: rawOpts, alias, dirname }) {
|
||||||
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.
|
// 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.
|
// 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);
|
const options = Object.assign({}, rawOpts);
|
||||||
@ -168,13 +176,19 @@ class ConfigChainBuilder {
|
|||||||
|
|
||||||
const envKey = getEnv();
|
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");
|
throw new Error(".env block must be an object, null, or undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
const envOpts = rawOpts.env && rawOpts.env[envKey];
|
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");
|
throw new Error(".env[...] block must be an object, null, or undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,11 +210,13 @@ class ConfigChainBuilder {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (rawOpts.extends) {
|
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 extendsConfig = loadConfig(rawOpts.extends, dirname);
|
||||||
|
|
||||||
const existingConfig = this.configs.some((config) => {
|
const existingConfig = this.configs.some(config => {
|
||||||
return config.alias === extendsConfig.filepath;
|
return config.alias === extendsConfig.filepath;
|
||||||
});
|
});
|
||||||
if (!existingConfig) {
|
if (!existingConfig) {
|
||||||
@ -214,4 +230,3 @@ class ConfigChainBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ type CacheEntry<ResultT> = Array<[ ResultT, () => boolean ]>;
|
|||||||
export function makeStrongCache<ArgT, ResultT>(
|
export function makeStrongCache<ArgT, ResultT>(
|
||||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||||
autoPermacache?: boolean,
|
autoPermacache?: boolean,
|
||||||
): (ArgT) => ResultT {
|
): ArgT => ResultT {
|
||||||
return makeCachedFunction(new Map(), handler, autoPermacache);
|
return makeCachedFunction(new Map(), handler, autoPermacache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,17 +34,19 @@ export function makeStrongCache<ArgT, ResultT>(
|
|||||||
export function makeWeakCache<ArgT: {}, ResultT>(
|
export function makeWeakCache<ArgT: {}, ResultT>(
|
||||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||||
autoPermacache?: boolean,
|
autoPermacache?: boolean,
|
||||||
): (ArgT) => ResultT {
|
): ArgT => ResultT {
|
||||||
return makeCachedFunction(new WeakMap(), handler, autoPermacache);
|
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>>(
|
function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
||||||
callCache: Cache,
|
callCache: Cache,
|
||||||
handler: (ArgT, CacheConfigurator) => ResultT,
|
handler: (ArgT, CacheConfigurator) => ResultT,
|
||||||
autoPermacache: boolean = true,
|
autoPermacache: boolean = true,
|
||||||
): (ArgT) => ResultT {
|
): ArgT => ResultT {
|
||||||
return function cachedFunction(arg) {
|
return function cachedFunction(arg) {
|
||||||
let cachedValue: CacheEntry<ResultT> | void = callCache.get(arg);
|
let cachedValue: CacheEntry<ResultT> | void = callCache.get(arg);
|
||||||
|
|
||||||
@ -64,7 +66,8 @@ function makeCachedFunction<ArgT, ResultT, Cache: CacheMap<ArgT, ResultT>>(
|
|||||||
|
|
||||||
if (!result.configured) {
|
if (!result.configured) {
|
||||||
// eslint-disable-next-line max-len
|
// 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",
|
"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:",
|
"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",
|
" // 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.",
|
" // 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",
|
" // .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",
|
" // based on previous instantiated plugins. If you want to recreate the plugin and discard the",
|
||||||
" // previous instance whenever something changes, you may use:",
|
" // 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:",
|
" // Note, we also expose the following more-verbose versions of the above examples:",
|
||||||
" api.cache.forever(); // api.cache(true)",
|
" 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 the value that will be cached.",
|
||||||
" return { };",
|
" return { };",
|
||||||
"};",
|
"};",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.never) {
|
if (!result.never) {
|
||||||
if (result.forever) {
|
if (result.forever) {
|
||||||
cachedValue = [
|
cachedValue = [[value, () => true]];
|
||||||
[value, () => true],
|
|
||||||
];
|
|
||||||
} else if (result.invalidate) {
|
} else if (result.invalidate) {
|
||||||
cachedValue = [
|
cachedValue = [[value, result.valid]];
|
||||||
[value, result.valid],
|
|
||||||
];
|
|
||||||
} else {
|
} else {
|
||||||
cachedValue = cachedValue || [];
|
cachedValue = cachedValue || [];
|
||||||
cachedValue.push([value, result.valid]);
|
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 pairs = [];
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
@ -137,7 +141,8 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
|||||||
active = false;
|
active = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cache: CacheConfigurator = Object.assign((function cacheFn(val) {
|
const cache: CacheConfigurator = Object.assign(
|
||||||
|
(function cacheFn(val) {
|
||||||
if (typeof val === "boolean") {
|
if (typeof val === "boolean") {
|
||||||
if (val) cache.forever();
|
if (val) cache.forever();
|
||||||
else cache.never();
|
else cache.never();
|
||||||
@ -145,23 +150,44 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cache.using(val);
|
return cache.using(val);
|
||||||
}: any), ({
|
}: any),
|
||||||
|
({
|
||||||
forever() {
|
forever() {
|
||||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
if (!active) {
|
||||||
if (result.never) throw new Error("Caching has already been configured with .never()");
|
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.forever = true;
|
||||||
result.configured = true;
|
result.configured = true;
|
||||||
},
|
},
|
||||||
never() {
|
never() {
|
||||||
if (!active) throw new Error("Cannot change caching after evaluation has completed.");
|
if (!active) {
|
||||||
if (result.forever) throw new Error("Caching has already been configured with .forever()");
|
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.never = true;
|
||||||
result.configured = true;
|
result.configured = true;
|
||||||
},
|
},
|
||||||
using<T>(handler: () => T): T {
|
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) {
|
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;
|
result.configured = true;
|
||||||
|
|
||||||
@ -170,9 +196,15 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
|||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
invalidate<T>(handler: () => T): T {
|
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) {
|
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.invalidate = true;
|
||||||
result.configured = true;
|
result.configured = true;
|
||||||
@ -181,7 +213,8 @@ function makeCacheConfig(): { cache: CacheConfigurator, result: *, deactivate: (
|
|||||||
pairs.push([key, handler]);
|
pairs.push([key, handler]);
|
||||||
return key;
|
return key;
|
||||||
},
|
},
|
||||||
}: CacheConfiguratorObj));
|
}: CacheConfiguratorObj),
|
||||||
|
);
|
||||||
|
|
||||||
return { cache, result, deactivate };
|
return { cache, result, deactivate };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
export function getEnv(defaultValue: string = "development"): string {
|
export function getEnv(defaultValue: string = "development"): string {
|
||||||
return process.env.BABEL_ENV
|
return process.env.BABEL_ENV || process.env.NODE_ENV || defaultValue;
|
||||||
|| process.env.NODE_ENV
|
|
||||||
|| defaultValue;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,8 +46,11 @@ export function findConfigs(dirname: string): Array<ConfigFile> {
|
|||||||
const config = readConfig(filepath);
|
const config = readConfig(filepath);
|
||||||
|
|
||||||
if (config && previousConfig) {
|
if (config && previousConfig) {
|
||||||
throw new Error(`Multiple configuration files found. Please remove one:\n- ${
|
throw new Error(
|
||||||
path.basename(previousConfig.filepath)}\n- ${name}\nfrom ${loc}`);
|
`Multiple configuration files found. Please remove one:\n- ${path.basename(
|
||||||
|
previousConfig.filepath,
|
||||||
|
)}\n- ${name}\nfrom ${loc}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return config || previousConfig;
|
return config || previousConfig;
|
||||||
@ -73,7 +76,9 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
|||||||
const filepath = resolve.sync(name, { basedir: dirname });
|
const filepath = resolve.sync(name, { basedir: dirname });
|
||||||
|
|
||||||
const conf = readConfig(filepath);
|
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;
|
return conf;
|
||||||
}
|
}
|
||||||
@ -83,7 +88,9 @@ export function loadConfig(name: string, dirname: string): ConfigFile {
|
|||||||
* throw if there are parsing errors while loading a config.
|
* throw if there are parsing errors while loading a config.
|
||||||
*/
|
*/
|
||||||
function readConfig(filepath) {
|
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) => {
|
const readConfigJS = makeStrongCache((filepath, cache) => {
|
||||||
@ -96,7 +103,10 @@ const readConfigJS = makeStrongCache((filepath, cache) => {
|
|||||||
try {
|
try {
|
||||||
// $FlowIssue
|
// $FlowIssue
|
||||||
const configModule = (require(filepath): mixed);
|
const configModule = (require(filepath): mixed);
|
||||||
options = configModule && configModule.__esModule ? (configModule.default || undefined) : configModule;
|
options =
|
||||||
|
configModule && configModule.__esModule
|
||||||
|
? configModule.default || undefined
|
||||||
|
: configModule;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
||||||
throw err;
|
throw err;
|
||||||
@ -113,7 +123,9 @@ const readConfigJS = makeStrongCache((filepath, cache) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
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 {
|
return {
|
||||||
@ -144,8 +156,12 @@ const readConfigFile = makeStaticFileCache((filepath, content) => {
|
|||||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof options !== "object") throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
if (typeof options !== "object") {
|
||||||
if (Array.isArray(options)) throw new Error(`${filepath}: Expected config object but found array`);
|
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||||
|
}
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
throw new Error(`${filepath}: Expected config object but found array`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filepath,
|
filepath,
|
||||||
@ -157,8 +173,8 @@ const readConfigFile = makeStaticFileCache((filepath, content) => {
|
|||||||
const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
||||||
const ignore = content
|
const ignore = content
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map((line) => line.replace(/#(.*?)$/, "").trim())
|
.map(line => line.replace(/#(.*?)$/, "").trim())
|
||||||
.filter((line) => !!line);
|
.filter(line => !!line);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filepath,
|
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) => {
|
return makeStrongCache((filepath, cache) => {
|
||||||
if (cache.invalidate(() => fileMtime(filepath)) === null) {
|
if (cache.invalidate(() => fileMtime(filepath)) === null) {
|
||||||
cache.forever();
|
cache.forever();
|
||||||
|
|||||||
@ -25,18 +25,38 @@ export function resolvePreset(name: string, dirname: string): string|null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadPlugin(name: string, dirname: string): { filepath: string, value: mixed } {
|
export function loadPlugin(
|
||||||
throw new Error(`Cannot load plugin ${name} relative to ${dirname} in a browser`);
|
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 } {
|
export function loadPreset(
|
||||||
throw new Error(`Cannot load preset ${name} relative to ${dirname} in a browser`);
|
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 } {
|
export function loadParser(
|
||||||
throw new Error(`Cannot load parser ${name} relative to ${dirname} in a browser`);
|
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 } {
|
export function loadGenerator(
|
||||||
throw new Error(`Cannot load generator ${name} relative to ${dirname} in a browser`);
|
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);
|
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);
|
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 {
|
return {
|
||||||
filepath,
|
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);
|
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 {
|
return {
|
||||||
filepath,
|
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 filepath = resolve.sync(name, { basedir: dirname });
|
||||||
|
|
||||||
const mod = requireModule(filepath);
|
const mod = requireModule(filepath);
|
||||||
|
|
||||||
if (!mod) {
|
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") {
|
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 {
|
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 filepath = resolve.sync(name, { basedir: dirname });
|
||||||
|
|
||||||
const mod = requireModule(filepath);
|
const mod = requireModule(filepath);
|
||||||
|
|
||||||
if (!mod) {
|
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") {
|
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 {
|
return {
|
||||||
@ -85,18 +109,33 @@ function standardizeName(type: "plugin"|"preset", name: string) {
|
|||||||
|
|
||||||
const isPreset = type === "preset";
|
const isPreset = type === "preset";
|
||||||
|
|
||||||
return name
|
return (
|
||||||
|
name
|
||||||
// foo -> babel-preset-foo
|
// 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
|
// @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
|
// @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
|
// 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);
|
const standardizedName = standardizeName(type, name);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -119,7 +158,9 @@ function resolveStandardizedName(type: "plugin"|"preset", name: string, dirname:
|
|||||||
|
|
||||||
let resolvedBabel = false;
|
let resolvedBabel = false;
|
||||||
try {
|
try {
|
||||||
resolve.sync(standardizeName(type, "@babel/" + name), { basedir: dirname });
|
resolve.sync(standardizeName(type, "@babel/" + name), {
|
||||||
|
basedir: dirname,
|
||||||
|
});
|
||||||
resolvedBabel = true;
|
resolvedBabel = true;
|
||||||
} catch (e2) {}
|
} catch (e2) {}
|
||||||
|
|
||||||
|
|||||||
@ -11,14 +11,19 @@ import path from "path";
|
|||||||
import traverse from "babel-traverse";
|
import traverse from "babel-traverse";
|
||||||
import clone from "lodash/clone";
|
import clone from "lodash/clone";
|
||||||
|
|
||||||
import { loadPlugin, loadPreset, loadParser, loadGenerator } from "./loading/files";
|
import {
|
||||||
|
loadPlugin,
|
||||||
|
loadPreset,
|
||||||
|
loadParser,
|
||||||
|
loadGenerator,
|
||||||
|
} from "./loading/files";
|
||||||
|
|
||||||
type MergeOptions = {
|
type MergeOptions = {
|
||||||
+type: "arguments" | "options" | "preset",
|
+type: "arguments" | "options" | "preset",
|
||||||
options: {},
|
options: {},
|
||||||
alias: string,
|
alias: string,
|
||||||
loc: string,
|
loc: string,
|
||||||
dirname: string
|
dirname: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const optionNames = new Set([
|
const optionNames = new Set([
|
||||||
@ -100,9 +105,12 @@ class OptionManager {
|
|||||||
mergeOptions(config: MergeOptions, pass?: Array<[Plugin, ?{}]>) {
|
mergeOptions(config: MergeOptions, pass?: Array<[Plugin, ?{}]>) {
|
||||||
const result = loadConfig(config);
|
const result = loadConfig(config);
|
||||||
|
|
||||||
const plugins = result.plugins.map((descriptor) => loadPluginDescriptor(descriptor));
|
const plugins = result.plugins.map(descriptor =>
|
||||||
const presets = result.presets.map((descriptor) => loadPresetDescriptor(descriptor));
|
loadPluginDescriptor(descriptor),
|
||||||
|
);
|
||||||
|
const presets = result.presets.map(descriptor =>
|
||||||
|
loadPresetDescriptor(descriptor),
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
config.options.passPerPreset != null &&
|
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
|
// 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.
|
// to keep things simple we just bail out if re-wrapping the message.
|
||||||
if (!/^\[BABEL\]/.test(e.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}`;
|
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,
|
// 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.
|
// it will be in the right structure to not change behavior.
|
||||||
opts.plugins = this.passes[0];
|
opts.plugins = this.passes[0];
|
||||||
opts.presets = this.passes.slice(1)
|
opts.presets = this.passes
|
||||||
.filter((plugins) => plugins.length > 0)
|
.slice(1)
|
||||||
.map((plugins) => ({ plugins }));
|
.filter(plugins => plugins.length > 0)
|
||||||
|
.map(plugins => ({ plugins }));
|
||||||
|
|
||||||
if (opts.inputSourceMap) {
|
if (opts.inputSourceMap) {
|
||||||
opts.sourceMaps = true;
|
opts.sourceMaps = true;
|
||||||
@ -209,19 +219,28 @@ type BasicDescriptor = {
|
|||||||
/**
|
/**
|
||||||
* Load and validate the given config into a set of options, plugins, and presets.
|
* Load and validate the given config into a set of options, plugins, and presets.
|
||||||
*/
|
*/
|
||||||
function loadConfig(config): {
|
function loadConfig(
|
||||||
|
config,
|
||||||
|
): {
|
||||||
options: {},
|
options: {},
|
||||||
plugins: Array<BasicDescriptor>,
|
plugins: Array<BasicDescriptor>,
|
||||||
presets: Array<BasicDescriptor>,
|
presets: Array<BasicDescriptor>,
|
||||||
} {
|
} {
|
||||||
const options = normalizeOptions(config);
|
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");
|
throw new Error(".plugins should be an array, null, or undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
const plugins = (config.options.plugins || []).map((plugin, index) => {
|
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 {
|
return {
|
||||||
alias: filepath || `${config.loc}$${index}`,
|
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");
|
throw new Error(".presets should be an array, null, or undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
const presets = (config.options.presets || []).map((preset, index) => {
|
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 {
|
return {
|
||||||
alias: filepath || `${config.loc}$${index}`,
|
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.
|
* Load a generic plugin/preset from the given descriptor loaded from the config object.
|
||||||
*/
|
*/
|
||||||
function loadDescriptor(descriptor, skipOptions) {
|
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;
|
const { value, options } = descriptor;
|
||||||
let item;
|
let item;
|
||||||
@ -266,7 +294,9 @@ function loadDescriptor(descriptor, skipOptions) {
|
|||||||
item = value(context, options, { dirname: descriptor.dirname });
|
item = value(context, options, { dirname: descriptor.dirname });
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} 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;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,11 +312,15 @@ function loadDescriptor(descriptor, skipOptions) {
|
|||||||
*/
|
*/
|
||||||
const PLUGIN_CACHE = new WeakMap();
|
const PLUGIN_CACHE = new WeakMap();
|
||||||
function loadPluginDescriptor(descriptor) {
|
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);
|
let result = PLUGIN_CACHE.get(descriptor.value);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = instantiatePlugin(loadDescriptor(descriptor, true /* skipOptions */));
|
result = instantiatePlugin(
|
||||||
|
loadDescriptor(descriptor, true /* skipOptions */),
|
||||||
|
);
|
||||||
PLUGIN_CACHE.set(descriptor.value, result);
|
PLUGIN_CACHE.set(descriptor.value, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,14 +328,21 @@ function loadPluginDescriptor(descriptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function instantiatePlugin({ value: pluginObj, descriptor }) {
|
function instantiatePlugin({ value: pluginObj, descriptor }) {
|
||||||
Object.keys(pluginObj).forEach((key) => {
|
Object.keys(pluginObj).forEach(key => {
|
||||||
if (!ALLOWED_PLUGIN_KEYS.has(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)) {
|
if (
|
||||||
throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. " +
|
pluginObj.visitor &&
|
||||||
"Please target individual nodes.");
|
(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, {
|
const plugin = Object.assign({}, pluginObj, {
|
||||||
@ -325,8 +366,14 @@ function instantiatePlugin({ value: pluginObj, descriptor }) {
|
|||||||
|
|
||||||
plugin.pre = chain(inherits.pre, plugin.pre);
|
plugin.pre = chain(inherits.pre, plugin.pre);
|
||||||
plugin.post = chain(inherits.post, plugin.post);
|
plugin.post = chain(inherits.post, plugin.post);
|
||||||
plugin.manipulateOptions = chain(inherits.manipulateOptions, plugin.manipulateOptions);
|
plugin.manipulateOptions = chain(
|
||||||
plugin.visitor = traverse.visitors.merge([inherits.visitor, plugin.visitor]);
|
inherits.manipulateOptions,
|
||||||
|
plugin.manipulateOptions,
|
||||||
|
);
|
||||||
|
plugin.visitor = traverse.visitors.merge([
|
||||||
|
inherits.visitor,
|
||||||
|
plugin.visitor,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Plugin(plugin, descriptor.alias);
|
return new Plugin(plugin, descriptor.alias);
|
||||||
@ -371,10 +418,18 @@ function normalizeOptions(config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === "preset") {
|
if (type === "preset") {
|
||||||
if (options.only !== undefined) throw new Error(`${alias}.only is not supported in a preset`);
|
if (options.only !== undefined) {
|
||||||
if (options.ignore !== undefined) throw new Error(`${alias}.ignore is not supported in a preset`);
|
throw new Error(`${alias}.only 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.ignore !== undefined) {
|
||||||
|
throw new Error(`${alias}.ignore is not supported in a preset`);
|
||||||
|
}
|
||||||
|
if (options.extends !== undefined) {
|
||||||
|
throw new Error(`${alias}.extends is not supported in a preset`);
|
||||||
|
}
|
||||||
|
if (options.env !== undefined) {
|
||||||
|
throw new Error(`${alias}.env is not supported in a preset`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.sourceMap !== undefined) {
|
if (options.sourceMap !== undefined) {
|
||||||
@ -390,7 +445,10 @@ function normalizeOptions(config) {
|
|||||||
// check for an unknown option
|
// check for an unknown option
|
||||||
if (!optionNames.has(key)) {
|
if (!optionNames.has(key)) {
|
||||||
if (removed[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 {
|
} else {
|
||||||
// eslint-disable-next-line max-len
|
// 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.`;
|
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") {
|
if (options.parserOpts && typeof options.parserOpts.parser === "string") {
|
||||||
options.parserOpts = Object.assign({}, options.parserOpts);
|
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 = 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;
|
delete options.passPerPreset;
|
||||||
@ -420,7 +487,11 @@ function normalizeOptions(config) {
|
|||||||
/**
|
/**
|
||||||
* Given a plugin/preset item, resolve it into a standard format.
|
* 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,
|
filepath: string | null,
|
||||||
value: {} | Function,
|
value: {} | Function,
|
||||||
options: ?{},
|
options: ?{},
|
||||||
@ -429,7 +500,9 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
|||||||
let value = pair;
|
let value = pair;
|
||||||
if (Array.isArray(pair)) {
|
if (Array.isArray(pair)) {
|
||||||
if (pair.length > 2) {
|
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;
|
[value, options] = pair;
|
||||||
@ -437,10 +510,7 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
|||||||
|
|
||||||
let filepath = null;
|
let filepath = null;
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
({
|
({ filepath, value } = resolver(value, dirname));
|
||||||
filepath,
|
|
||||||
value,
|
|
||||||
} = resolver(value, dirname));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@ -456,11 +526,15 @@ function normalizePair(pair: mixed, resolver, dirname): {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value !== "object" && typeof value !== "function") {
|
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") {
|
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 };
|
return { filepath, value, options };
|
||||||
|
|||||||
@ -5,8 +5,13 @@ export default class Plugin {
|
|||||||
if (plugin.name != null && typeof plugin.name !== "string") {
|
if (plugin.name != null && typeof plugin.name !== "string") {
|
||||||
throw new Error("Plugin .name must be a string, null, or undefined");
|
throw new Error("Plugin .name must be a string, null, or undefined");
|
||||||
}
|
}
|
||||||
if (plugin.manipulateOptions != null && typeof plugin.manipulateOptions !== "function") {
|
if (
|
||||||
throw new Error("Plugin .manipulateOptions must be a function, null, or undefined");
|
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") {
|
if (plugin.post != null && typeof plugin.post !== "function") {
|
||||||
throw new Error("Plugin .post must be a function, null, or undefined");
|
throw new Error("Plugin .post must be a function, null, or undefined");
|
||||||
|
|||||||
@ -2,52 +2,58 @@
|
|||||||
/* eslint max-len: "off" */
|
/* eslint max-len: "off" */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
"auxiliaryComment": {
|
auxiliaryComment: {
|
||||||
"message": "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
message: "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
||||||
},
|
},
|
||||||
"blacklist": {
|
blacklist: {
|
||||||
"message": "Put the specific transforms you want in the `plugins` option",
|
message: "Put the specific transforms you want in the `plugins` option",
|
||||||
},
|
},
|
||||||
"breakConfig": {
|
breakConfig: {
|
||||||
"message": "This is not a necessary option in Babel 6",
|
message: "This is not a necessary option in Babel 6",
|
||||||
},
|
},
|
||||||
"experimental": {
|
experimental: {
|
||||||
"message": "Put the specific transforms you want in the `plugins` option",
|
message: "Put the specific transforms you want in the `plugins` option",
|
||||||
},
|
},
|
||||||
"externalHelpers": {
|
externalHelpers: {
|
||||||
"message": "Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/",
|
message:
|
||||||
|
"Use the `external-helpers` plugin instead. Check out http://babeljs.io/docs/plugins/external-helpers/",
|
||||||
},
|
},
|
||||||
"extra": {
|
extra: {
|
||||||
"message": "",
|
message: "",
|
||||||
},
|
},
|
||||||
"jsxPragma": {
|
jsxPragma: {
|
||||||
"message": "use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/",
|
message:
|
||||||
|
"use the `pragma` option in the `react-jsx` plugin . Check out http://babeljs.io/docs/plugins/transform-react-jsx/",
|
||||||
},
|
},
|
||||||
// "keepModuleIdExtensions": {
|
// "keepModuleIdExtensions": {
|
||||||
// "message": ""
|
// "message": ""
|
||||||
// },
|
// },
|
||||||
"loose": {
|
loose: {
|
||||||
"message": "Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option.",
|
message:
|
||||||
|
"Specify the `loose` option for the relevant plugin you are using or use a preset that sets the option.",
|
||||||
},
|
},
|
||||||
"metadataUsedHelpers": {
|
metadataUsedHelpers: {
|
||||||
"message": "Not required anymore as this is enabled by default",
|
message: "Not required anymore as this is enabled by default",
|
||||||
},
|
},
|
||||||
"modules": {
|
modules: {
|
||||||
"message": "Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules",
|
message:
|
||||||
|
"Use the corresponding module transform plugin in the `plugins` option. Check out http://babeljs.io/docs/plugins/#modules",
|
||||||
},
|
},
|
||||||
"nonStandard": {
|
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/",
|
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": {
|
optional: {
|
||||||
"message": "Put the specific transforms you want in the `plugins` option",
|
message: "Put the specific transforms you want in the `plugins` option",
|
||||||
},
|
},
|
||||||
"sourceMapName": {
|
sourceMapName: {
|
||||||
"message": "Use the `sourceMapTarget` option",
|
message: "Use the `sourceMapTarget` option",
|
||||||
},
|
},
|
||||||
"stage": {
|
stage: {
|
||||||
"message": "Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets",
|
message:
|
||||||
|
"Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets",
|
||||||
},
|
},
|
||||||
"whitelist": {
|
whitelist: {
|
||||||
"message": "Put the specific transforms you want in the `plugins` option",
|
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
|
* 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.
|
* 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) {
|
function buildGlobal(namespace, builder) {
|
||||||
const body = [];
|
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([
|
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(
|
t.variableDeclarator(
|
||||||
namespace,
|
namespace,
|
||||||
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace),
|
t.assignmentExpression(
|
||||||
t.objectExpression([]))
|
"=",
|
||||||
|
t.memberExpression(t.identifier("global"), namespace),
|
||||||
|
t.objectExpression([]),
|
||||||
),
|
),
|
||||||
]));
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
builder(body);
|
builder(body);
|
||||||
|
|
||||||
@ -39,9 +51,11 @@ function buildGlobal(namespace, builder) {
|
|||||||
|
|
||||||
function buildUmd(namespace, builder) {
|
function buildUmd(namespace, builder) {
|
||||||
const body = [];
|
const body = [];
|
||||||
body.push(t.variableDeclaration("var", [
|
body.push(
|
||||||
|
t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(namespace, t.identifier("global")),
|
t.variableDeclarator(namespace, t.identifier("global")),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
builder(body);
|
builder(body);
|
||||||
|
|
||||||
@ -51,7 +65,7 @@ function buildUmd(namespace, builder) {
|
|||||||
BROWSER_ARGUMENTS: t.assignmentExpression(
|
BROWSER_ARGUMENTS: t.assignmentExpression(
|
||||||
"=",
|
"=",
|
||||||
t.memberExpression(t.identifier("root"), namespace),
|
t.memberExpression(t.identifier("root"), namespace),
|
||||||
t.objectExpression([])
|
t.objectExpression([]),
|
||||||
),
|
),
|
||||||
COMMON_ARGUMENTS: t.identifier("exports"),
|
COMMON_ARGUMENTS: t.identifier("exports"),
|
||||||
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
||||||
@ -63,9 +77,11 @@ function buildUmd(namespace, builder) {
|
|||||||
|
|
||||||
function buildVar(namespace, builder) {
|
function buildVar(namespace, builder) {
|
||||||
const body = [];
|
const body = [];
|
||||||
body.push(t.variableDeclaration("var", [
|
body.push(
|
||||||
|
t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(namespace, t.objectExpression([])),
|
t.variableDeclarator(namespace, t.objectExpression([])),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
builder(body);
|
builder(body);
|
||||||
body.push(t.expressionStatement(namespace));
|
body.push(t.expressionStatement(namespace));
|
||||||
return t.program(body);
|
return t.program(body);
|
||||||
@ -76,9 +92,15 @@ function buildHelpers(body, namespace, whitelist) {
|
|||||||
if (whitelist && whitelist.indexOf(name) < 0) return;
|
if (whitelist && whitelist.indexOf(name) < 0) return;
|
||||||
|
|
||||||
const key = t.identifier(name);
|
const key = t.identifier(name);
|
||||||
body.push(t.expressionStatement(
|
body.push(
|
||||||
t.assignmentExpression("=", t.memberExpression(namespace, key), helpers.get(name))
|
t.expressionStatement(
|
||||||
));
|
t.assignmentExpression(
|
||||||
|
"=",
|
||||||
|
t.memberExpression(namespace, key),
|
||||||
|
helpers.get(name),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export default function(
|
export default function(
|
||||||
|
|||||||
@ -150,7 +150,7 @@ export default class File extends Store {
|
|||||||
|
|
||||||
if (opts.sourceRoot != null) {
|
if (opts.sourceRoot != null) {
|
||||||
// remove sourceRoot from filename
|
// remove sourceRoot from filename
|
||||||
const sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
const sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "/?");
|
||||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,17 +172,25 @@ export default class File extends Store {
|
|||||||
|
|
||||||
resolveModuleSource(source: string): string {
|
resolveModuleSource(source: string): string {
|
||||||
const resolveModuleSource = this.opts.resolveModuleSource;
|
const resolveModuleSource = this.opts.resolveModuleSource;
|
||||||
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
|
if (resolveModuleSource) {
|
||||||
|
source = resolveModuleSource(source, this.opts.filename);
|
||||||
|
}
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
addImport(source: string, imported: string, name?: string = imported): Object {
|
addImport(
|
||||||
|
source: string,
|
||||||
|
imported: string,
|
||||||
|
name?: string = imported,
|
||||||
|
): Object {
|
||||||
const alias = `${source}:${imported}`;
|
const alias = `${source}:${imported}`;
|
||||||
let id = this.dynamicImportIds[alias];
|
let id = this.dynamicImportIds[alias];
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
source = this.resolveModuleSource(source);
|
source = this.resolveModuleSource(source);
|
||||||
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(name);
|
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(
|
||||||
|
name,
|
||||||
|
);
|
||||||
|
|
||||||
const specifiers = [];
|
const specifiers = [];
|
||||||
|
|
||||||
@ -222,7 +230,9 @@ export default class File extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ref = getHelper(name);
|
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) {
|
if (t.isFunctionExpression(ref) && !ref.id) {
|
||||||
ref.body._compact = true;
|
ref.body._compact = true;
|
||||||
@ -257,7 +267,9 @@ export default class File extends Store {
|
|||||||
const declar = this.declarations[name];
|
const declar = this.declarations[name];
|
||||||
if (declar) return declar;
|
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 helperId = this.addHelper(helperName);
|
||||||
const init = t.callExpression(helperId, [strings, raw]);
|
const init = t.callExpression(helperId, [strings, raw]);
|
||||||
@ -270,7 +282,11 @@ export default class File extends Store {
|
|||||||
return uid;
|
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 loc = node && (node.loc || node._loc);
|
||||||
|
|
||||||
const err = new Error(msg);
|
const err = new Error(msg);
|
||||||
@ -280,7 +296,8 @@ export default class File extends Store {
|
|||||||
} else {
|
} else {
|
||||||
traverse(node, errorVisitor, this.scope, err);
|
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) {
|
if (err.loc) {
|
||||||
err.message += ". Location has been estimated.";
|
err.message += ". Location has been estimated.";
|
||||||
@ -318,7 +335,10 @@ export default class File extends Store {
|
|||||||
mergedGenerator.addMapping({
|
mergedGenerator.addMapping({
|
||||||
source: mapping.source,
|
source: mapping.source,
|
||||||
|
|
||||||
original: mapping.source == null ? null : {
|
original:
|
||||||
|
mapping.source == null
|
||||||
|
? null
|
||||||
|
: {
|
||||||
line: mapping.originalLine,
|
line: mapping.originalLine,
|
||||||
column: mapping.originalColumn,
|
column: mapping.originalColumn,
|
||||||
},
|
},
|
||||||
@ -401,7 +421,11 @@ export default class File extends Store {
|
|||||||
debug(this.opts, "Start transform traverse");
|
debug(this.opts, "Start transform traverse");
|
||||||
|
|
||||||
// merge all plugin visitors into a single visitor
|
// 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);
|
traverse(this.ast, visitor, this.scope);
|
||||||
|
|
||||||
debug(this.opts, "End transform traverse");
|
debug(this.opts, "End transform traverse");
|
||||||
@ -410,7 +434,6 @@ export default class File extends Store {
|
|||||||
const fn = plugin.post;
|
const fn = plugin.post;
|
||||||
if (fn) fn.call(pass, this);
|
if (fn) fn.call(pass, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.generate();
|
return this.generate();
|
||||||
@ -428,7 +451,7 @@ export default class File extends Store {
|
|||||||
err._babel = true;
|
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;
|
const loc = err.loc;
|
||||||
if (loc) {
|
if (loc) {
|
||||||
@ -530,8 +553,11 @@ export default class File extends Store {
|
|||||||
|
|
||||||
debug(this.opts, "Generation start");
|
debug(this.opts, "Generation start");
|
||||||
|
|
||||||
const _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts,
|
const _result = gen(
|
||||||
this.code);
|
ast,
|
||||||
|
opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts,
|
||||||
|
this.code,
|
||||||
|
);
|
||||||
result.code = _result.code;
|
result.code = _result.code;
|
||||||
result.map = _result.map;
|
result.map = _result.map;
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,11 @@ import * as t from "babel-types";
|
|||||||
import File from "./file";
|
import File from "./file";
|
||||||
import loadConfig from "../config";
|
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;
|
opts.code = false;
|
||||||
if (visitor) {
|
if (visitor) {
|
||||||
opts.plugins = opts.plugins || [];
|
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);
|
const config = loadConfig(opts);
|
||||||
if (config === null) return null;
|
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") {
|
if (typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
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;
|
opts.filename = filename;
|
||||||
const config = loadConfig(opts);
|
const config = loadConfig(opts);
|
||||||
if (config === null) return null;
|
if (config === null) return null;
|
||||||
|
|||||||
@ -55,11 +55,14 @@ describe("parser and generator options", function() {
|
|||||||
it("experimental syntax", function() {
|
it("experimental syntax", function() {
|
||||||
const experimental = "var a: number = 1;";
|
const experimental = "var a: number = 1;";
|
||||||
|
|
||||||
assert.deepEqual(newTransform(experimental).ast, babel.transform(experimental, {
|
assert.deepEqual(
|
||||||
|
newTransform(experimental).ast,
|
||||||
|
babel.transform(experimental, {
|
||||||
parserOpts: {
|
parserOpts: {
|
||||||
plugins: ["flow"],
|
plugins: ["flow"],
|
||||||
},
|
},
|
||||||
}).ast);
|
}).ast,
|
||||||
|
);
|
||||||
assert.equal(newTransform(experimental).code, experimental);
|
assert.equal(newTransform(experimental).code, experimental);
|
||||||
|
|
||||||
function newTransformWithPlugins(string) {
|
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: {
|
parserOpts: {
|
||||||
plugins: ["flow"],
|
plugins: ["flow"],
|
||||||
},
|
},
|
||||||
}).ast);
|
}).ast,
|
||||||
|
);
|
||||||
assert.equal(newTransformWithPlugins(experimental).code, experimental);
|
assert.equal(newTransformWithPlugins(experimental).code, experimental);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("other options", function() {
|
it("other options", function() {
|
||||||
const experimental = "if (true) {\n import a from 'a';\n}";
|
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: {
|
parserOpts: {
|
||||||
allowImportExportEverywhere: true,
|
allowImportExportEverywhere: true,
|
||||||
},
|
},
|
||||||
}).ast);
|
}).ast,
|
||||||
|
);
|
||||||
assert.equal(newTransform(experimental).code, experimental);
|
assert.equal(newTransform(experimental).code, experimental);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -98,58 +107,78 @@ describe("api", function () {
|
|||||||
it("analyze", function() {
|
it("analyze", function() {
|
||||||
assert.equal(babel.analyse("foobar;").marked.length, 0);
|
assert.equal(babel.analyse("foobar;").marked.length, 0);
|
||||||
|
|
||||||
assert.equal(babel.analyse("foobar;", {
|
assert.equal(
|
||||||
plugins: [new Plugin({
|
babel.analyse("foobar;", {
|
||||||
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
Program: function(path) {
|
Program: function(path) {
|
||||||
path.mark("category", "foobar");
|
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) {
|
Program: function(path) {
|
||||||
path.mark("category", "foobar");
|
path.mark("category", "foobar");
|
||||||
},
|
},
|
||||||
}).marked[0].message, "foobar");
|
},
|
||||||
|
).marked[0].message,
|
||||||
|
"foobar",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("exposes the resolvePlugin method", function() {
|
it("exposes the resolvePlugin method", function() {
|
||||||
assert.throws(() => babel.resolvePlugin("nonexistent-plugin"),
|
assert.throws(
|
||||||
/Cannot find module 'babel-plugin-nonexistent-plugin'/);
|
() => babel.resolvePlugin("nonexistent-plugin"),
|
||||||
|
/Cannot find module 'babel-plugin-nonexistent-plugin'/,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("exposes the resolvePreset method", function() {
|
it("exposes the resolvePreset method", function() {
|
||||||
assert.throws(() => babel.resolvePreset("nonexistent-preset"),
|
assert.throws(
|
||||||
/Cannot find module 'babel-preset-nonexistent-preset'/);
|
() => babel.resolvePreset("nonexistent-preset"),
|
||||||
|
/Cannot find module 'babel-preset-nonexistent-preset'/,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("transformFile", function(done) {
|
it("transformFile", function(done) {
|
||||||
babel.transformFile(__dirname + "/fixtures/api/file.js", {
|
babel.transformFile(
|
||||||
|
__dirname + "/fixtures/api/file.js",
|
||||||
|
{
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
}, function (err, res) {
|
},
|
||||||
|
function(err, res) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
assert.equal(res.code, "foo();");
|
assert.equal(res.code, "foo();");
|
||||||
done();
|
done();
|
||||||
});
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("transformFileSync", function() {
|
it("transformFileSync", function() {
|
||||||
assert.equal(babel.transformFileSync(__dirname + "/fixtures/api/file.js", {
|
assert.equal(
|
||||||
|
babel.transformFileSync(__dirname + "/fixtures/api/file.js", {
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
}).code, "foo();");
|
}).code,
|
||||||
|
"foo();",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("options throw on falsy true", function() {
|
it("options throw on falsy true", function() {
|
||||||
return assert.throws(
|
return assert.throws(function() {
|
||||||
function () {
|
|
||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx", false],
|
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() {
|
it("options merge backwards", function() {
|
||||||
@ -157,7 +186,11 @@ describe("api", function () {
|
|||||||
presets: [__dirname + "/../../babel-preset-es2015"],
|
presets: [__dirname + "/../../babel-preset-es2015"],
|
||||||
plugins: [__dirname + "/../../babel-plugin-syntax-jsx"],
|
plugins: [__dirname + "/../../babel-plugin-syntax-jsx"],
|
||||||
}).then(function(result) {
|
}).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",
|
name: "foobar",
|
||||||
visitor: {
|
visitor: {
|
||||||
"Program|Identifier": function() {
|
"Program|Identifier": function() {
|
||||||
calledRaw++;
|
calledRaw++;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.equal(calledRaw, 4);
|
assert.equal(calledRaw, 4);
|
||||||
@ -207,7 +242,9 @@ describe("api", function () {
|
|||||||
new Plugin({
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
Function: function(path) {
|
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;
|
if (!babel.types.isTypeAlias(alias)) return;
|
||||||
|
|
||||||
// In case of `passPerPreset` being `false`, the
|
// In case of `passPerPreset` being `false`, the
|
||||||
@ -234,7 +271,8 @@ describe("api", function () {
|
|||||||
return {
|
return {
|
||||||
plugins: [
|
plugins: [
|
||||||
require(__dirname + "/../../babel-plugin-syntax-flow"),
|
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.equal(aliasBaseType, "NumberTypeAnnotation");
|
||||||
|
|
||||||
assert.deepEqual([
|
assert.deepEqual(
|
||||||
"\"use strict\";",
|
[
|
||||||
|
'"use strict";',
|
||||||
"",
|
"",
|
||||||
"var x = function x(y) {",
|
"var x = function x(y) {",
|
||||||
" return y;",
|
" return y;",
|
||||||
"};",
|
"};",
|
||||||
].join("\n"), result.code);
|
].join("\n"),
|
||||||
|
result.code,
|
||||||
|
);
|
||||||
|
|
||||||
// 2. passPerPreset: false
|
// 2. passPerPreset: false
|
||||||
|
|
||||||
@ -264,14 +305,16 @@ describe("api", function () {
|
|||||||
|
|
||||||
assert.equal(aliasBaseType, null);
|
assert.equal(aliasBaseType, null);
|
||||||
|
|
||||||
assert.deepEqual([
|
assert.deepEqual(
|
||||||
"\"use strict\";",
|
[
|
||||||
|
'"use strict";',
|
||||||
"",
|
"",
|
||||||
"var x = function x(y) {",
|
"var x = function x(y) {",
|
||||||
" return y;",
|
" return y;",
|
||||||
"};",
|
"};",
|
||||||
].join("\n"), result.code);
|
].join("\n"),
|
||||||
|
result.code,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("complex plugin and preset ordering", function() {
|
it("complex plugin and preset ordering", function() {
|
||||||
@ -279,7 +322,10 @@ describe("api", function () {
|
|||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
Program(path) {
|
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("", {
|
const result = babel.transform("", {
|
||||||
filename: path.join(__dirname, "fixtures", "config", "complex-plugin-config", "file.js"),
|
filename: path.join(
|
||||||
presets: [
|
__dirname,
|
||||||
pushPreset("argone"),
|
"fixtures",
|
||||||
pushPreset("argtwo"),
|
"config",
|
||||||
],
|
"complex-plugin-config",
|
||||||
|
"file.js",
|
||||||
|
),
|
||||||
|
presets: [pushPreset("argone"), pushPreset("argtwo")],
|
||||||
env: {
|
env: {
|
||||||
development: {
|
development: {
|
||||||
passPerPreset: true,
|
passPerPreset: true,
|
||||||
presets: [
|
presets: [pushPreset("argthree"), pushPreset("argfour")],
|
||||||
pushPreset("argthree"),
|
|
||||||
pushPreset("argfour"),
|
|
||||||
],
|
|
||||||
env: {
|
env: {
|
||||||
development: {
|
development: {
|
||||||
passPerPreset: true,
|
passPerPreset: true,
|
||||||
presets: [
|
presets: [pushPreset("argfive"), pushPreset("argsix")],
|
||||||
pushPreset("argfive"),
|
|
||||||
pushPreset("argsix"),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.equal(result.code, [
|
assert.equal(
|
||||||
|
result.code,
|
||||||
|
[
|
||||||
"argtwo;",
|
"argtwo;",
|
||||||
"argone;",
|
"argone;",
|
||||||
"eleven;",
|
"eleven;",
|
||||||
@ -342,13 +387,15 @@ describe("api", function () {
|
|||||||
"eight;",
|
"eight;",
|
||||||
"nine;",
|
"nine;",
|
||||||
"ten;",
|
"ten;",
|
||||||
].join("\n"));
|
].join("\n"),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("source map merging", function() {
|
it("source map merging", function() {
|
||||||
const result = babel.transform([
|
const result = babel.transform(
|
||||||
|
[
|
||||||
/* eslint-disable max-len */
|
/* 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() {",
|
"let Foo = function Foo() {",
|
||||||
" _classCallCheck(this, Foo);",
|
" _classCallCheck(this, Foo);",
|
||||||
@ -356,37 +403,47 @@ describe("api", function () {
|
|||||||
"",
|
"",
|
||||||
"//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZG91dCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztJQUFNLEdBQUcsWUFBSCxHQUFHO3dCQUFILEdBQUciLCJmaWxlIjoidW5kZWZpbmVkIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRm9vIHt9XG4iXX0=",
|
"//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZG91dCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztJQUFNLEdBQUcsWUFBSCxHQUFHO3dCQUFILEdBQUciLCJmaWxlIjoidW5kZWZpbmVkIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRm9vIHt9XG4iXX0=",
|
||||||
/* eslint-enable max-len */
|
/* eslint-enable max-len */
|
||||||
].join("\n"), {
|
].join("\n"),
|
||||||
|
{
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
assert.deepEqual([
|
assert.deepEqual(
|
||||||
|
[
|
||||||
"function _classCallCheck(instance, Constructor) {",
|
"function _classCallCheck(instance, Constructor) {",
|
||||||
" if (!(instance instanceof 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() {",
|
"let Foo = function Foo() {",
|
||||||
" _classCallCheck(this, Foo);",
|
" _classCallCheck(this, Foo);",
|
||||||
"};",
|
"};",
|
||||||
].join("\n"), result.code);
|
].join("\n"),
|
||||||
|
result.code,
|
||||||
|
);
|
||||||
|
|
||||||
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
const consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||||
|
|
||||||
assert.deepEqual(consumer.originalPositionFor({
|
assert.deepEqual(
|
||||||
|
consumer.originalPositionFor({
|
||||||
line: 7,
|
line: 7,
|
||||||
column: 4,
|
column: 4,
|
||||||
}), {
|
}),
|
||||||
|
{
|
||||||
name: null,
|
name: null,
|
||||||
source: "stdout",
|
source: "stdout",
|
||||||
line: 1,
|
line: 1,
|
||||||
column: 6,
|
column: 6,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("code option false", function() {
|
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);
|
assert.ok(!result.code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -401,62 +458,84 @@ describe("api", function () {
|
|||||||
return transformAsync("class Foo {}", {
|
return transformAsync("class Foo {}", {
|
||||||
auxiliaryCommentBefore: "before",
|
auxiliaryCommentBefore: "before",
|
||||||
auxiliaryCommentAfter: "after",
|
auxiliaryCommentAfter: "after",
|
||||||
plugins: [function (babel) {
|
plugins: [
|
||||||
|
function(babel) {
|
||||||
const t = babel.types;
|
const t = babel.types;
|
||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
Program: function(path) {
|
Program: function(path) {
|
||||||
path.unshiftContainer("body", t.expressionStatement(t.identifier("start")));
|
path.unshiftContainer(
|
||||||
path.pushContainer("body", t.expressionStatement(t.identifier("end")));
|
"body",
|
||||||
|
t.expressionStatement(t.identifier("start")),
|
||||||
|
);
|
||||||
|
path.pushContainer(
|
||||||
|
"body",
|
||||||
|
t.expressionStatement(t.identifier("end")),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
assert.equal(result.code,
|
assert.equal(
|
||||||
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/");
|
result.code,
|
||||||
|
"/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("modules metadata", function() {
|
it("modules metadata", function() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
// eslint-disable-next-line max-len
|
// 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], {
|
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||||
source: "external",
|
source: "external",
|
||||||
imported: ["externalName"],
|
imported: ["externalName"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "named",
|
kind: "named",
|
||||||
imported: "externalName",
|
imported: "externalName",
|
||||||
local: "localName",
|
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], {
|
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||||
source: "external",
|
source: "external",
|
||||||
imported: ["*"],
|
imported: ["*"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "namespace",
|
kind: "namespace",
|
||||||
local: "localName2",
|
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], {
|
assert.deepEqual(result.metadata.modules.imports[0], {
|
||||||
source: "external",
|
source: "external",
|
||||||
imported: ["default"],
|
imported: ["default"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "named",
|
kind: "named",
|
||||||
imported: "default",
|
imported: "default",
|
||||||
local: "localName3",
|
local: "localName3",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("import localName from \"./array\";", {
|
transformAsync('import localName from "./array";', {
|
||||||
resolveModuleSource: function() {
|
resolveModuleSource: function() {
|
||||||
return "override-source";
|
return "override-source";
|
||||||
},
|
},
|
||||||
@ -467,105 +546,129 @@ describe("api", function () {
|
|||||||
imported: ["default"],
|
imported: ["default"],
|
||||||
specifiers: [
|
specifiers: [
|
||||||
{
|
{
|
||||||
"kind": "named",
|
kind: "named",
|
||||||
"imported": "default",
|
imported: "default",
|
||||||
"local": "localName",
|
local: "localName",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export * as externalName1 from \"external\";", {
|
transformAsync('export * as externalName1 from "external";', {
|
||||||
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["externalName1"],
|
exported: ["externalName1"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "external-namespace",
|
kind: "external-namespace",
|
||||||
exported: "externalName1",
|
exported: "externalName1",
|
||||||
source: "external",
|
source: "external",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export externalName2 from \"external\";", {
|
transformAsync('export externalName2 from "external";', {
|
||||||
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
plugins: [require("../../babel-plugin-syntax-export-extensions")],
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["externalName2"],
|
exported: ["externalName2"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "external",
|
kind: "external",
|
||||||
local: "externalName2",
|
local: "externalName2",
|
||||||
exported: "externalName2",
|
exported: "externalName2",
|
||||||
source: "external",
|
source: "external",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export function namedFunction() {}").then(function (result) {
|
transformAsync("export function namedFunction() {}").then(function(
|
||||||
|
result,
|
||||||
|
) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["namedFunction"],
|
exported: ["namedFunction"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "local",
|
kind: "local",
|
||||||
local: "namedFunction",
|
local: "namedFunction",
|
||||||
exported: "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, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
"exported": ["foo"],
|
exported: ["foo"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "local",
|
kind: "local",
|
||||||
local: "foo",
|
local: "foo",
|
||||||
exported: "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, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["externalName3"],
|
exported: ["externalName3"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "local",
|
kind: "local",
|
||||||
local: "localName",
|
local: "localName",
|
||||||
exported: "externalName3",
|
exported: "externalName3",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export { externalName4 } from \"external\";").then(function (result) {
|
transformAsync('export { externalName4 } from "external";').then(function(
|
||||||
|
result,
|
||||||
|
) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["externalName4"],
|
exported: ["externalName4"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "external",
|
kind: "external",
|
||||||
local: "externalName4",
|
local: "externalName4",
|
||||||
exported: "externalName4",
|
exported: "externalName4",
|
||||||
source: "external",
|
source: "external",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export * from \"external\";").then(function (result) {
|
transformAsync('export * from "external";').then(function(result) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: [],
|
exported: [],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "external-all",
|
kind: "external-all",
|
||||||
source: "external",
|
source: "external",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
||||||
transformAsync("export default function defaultFunction() {}").then(function (result) {
|
transformAsync(
|
||||||
|
"export default function defaultFunction() {}",
|
||||||
|
).then(function(result) {
|
||||||
assert.deepEqual(result.metadata.modules.exports, {
|
assert.deepEqual(result.metadata.modules.exports, {
|
||||||
exported: ["defaultFunction"],
|
exported: ["defaultFunction"],
|
||||||
specifiers: [{
|
specifiers: [
|
||||||
|
{
|
||||||
kind: "local",
|
kind: "local",
|
||||||
local: "defaultFunction",
|
local: "defaultFunction",
|
||||||
exported: "default",
|
exported: "default",
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
@ -698,8 +801,10 @@ describe("api", function () {
|
|||||||
|
|
||||||
it("resolveModuleSource option", function() {
|
it("resolveModuleSource option", function() {
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
const actual = "import foo from \"foo-import-default\";\nimport \"foo-import-bare\";\nexport { foo } from \"foo-export-named\";";
|
const actual =
|
||||||
const expected = "import foo from \"resolved/foo-import-default\";\nimport \"resolved/foo-import-bare\";\nexport { foo } from \"resolved/foo-export-named\";";
|
'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 */
|
/* eslint-enable max-len */
|
||||||
|
|
||||||
return transformAsync(actual, {
|
return transformAsync(actual, {
|
||||||
|
|||||||
@ -5,7 +5,9 @@ import vm from "vm";
|
|||||||
|
|
||||||
describe("browserify", function() {
|
describe("browserify", function() {
|
||||||
it("babel/register may be used without breaking browserify", function(done) {
|
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) {
|
bundler.bundle(function(err, bundle) {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
|||||||
@ -27,7 +27,6 @@ describe("caching API", () => {
|
|||||||
return { arg, count: count++ };
|
return { arg, count: count++ };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
assert.deepEqual(fn("one"), { arg: "one", count: 0 });
|
assert.deepEqual(fn("one"), { arg: "one", count: 0 });
|
||||||
assert.equal(fn("one"), fn("one"));
|
assert.equal(fn("one"), fn("one"));
|
||||||
|
|
||||||
@ -210,44 +209,93 @@ describe("caching API", () => {
|
|||||||
return { arg, val, val2, count: count++ };
|
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.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"));
|
assert.equal(fn("two"), fn("two"));
|
||||||
|
|
||||||
other = "new";
|
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.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"));
|
assert.equal(fn("two"), fn("two"));
|
||||||
|
|
||||||
other = "default";
|
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.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"));
|
assert.equal(fn("two"), fn("two"));
|
||||||
|
|
||||||
other = "new";
|
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.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"));
|
assert.equal(fn("two"), fn("two"));
|
||||||
|
|
||||||
another = "second";
|
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.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"));
|
assert.equal(fn("two"), fn("two"));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should throw if caching is never configured and not defaulting", () => {
|
it("should throw if caching is never configured and not defaulting", () => {
|
||||||
@ -259,7 +307,7 @@ describe("caching API", () => {
|
|||||||
it("should auto-permacache by default", () => {
|
it("should auto-permacache by default", () => {
|
||||||
let count = 0;
|
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.deepEqual(fn("one"), { arg: "one", count: 0 });
|
||||||
assert.equal(fn("one"), fn("one"));
|
assert.equal(fn("one"), fn("one"));
|
||||||
@ -333,7 +381,10 @@ describe("caching API", () => {
|
|||||||
it("should throw if you configure .forever after exiting", () => {
|
it("should throw if you configure .forever after exiting", () => {
|
||||||
const fn = makeStrongCache((arg, cache) => cache);
|
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", () => {
|
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", () => {
|
it("should throw if you configure .using after exiting", () => {
|
||||||
const fn = makeStrongCache((arg, cache) => cache);
|
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", () => {
|
it("should throw if you configure .invalidate after exiting", () => {
|
||||||
const fn = makeStrongCache((arg, cache) => cache);
|
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",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["extended"],
|
||||||
"extended",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("extended.babelrc.json"),
|
alias: fixture("extended.babelrc.json"),
|
||||||
loc: fixture("extended.babelrc.json"),
|
loc: fixture("extended.babelrc.json"),
|
||||||
@ -72,9 +70,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["root"],
|
||||||
"root",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelrc"),
|
alias: fixture(".babelrc"),
|
||||||
loc: fixture(".babelrc"),
|
loc: fixture(".babelrc"),
|
||||||
@ -83,9 +79,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -114,9 +108,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -125,9 +117,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["dir2"],
|
||||||
"dir2",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("dir2", ".babelrc"),
|
alias: fixture("dir2", ".babelrc"),
|
||||||
loc: fixture("dir2", ".babelrc"),
|
loc: fixture("dir2", ".babelrc"),
|
||||||
@ -156,9 +146,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["extended"],
|
||||||
"extended",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("extended.babelrc.json"),
|
alias: fixture("extended.babelrc.json"),
|
||||||
loc: fixture("extended.babelrc.json"),
|
loc: fixture("extended.babelrc.json"),
|
||||||
@ -167,9 +155,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["root"],
|
||||||
"root",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelrc"),
|
alias: fixture(".babelrc"),
|
||||||
loc: fixture(".babelrc"),
|
loc: fixture(".babelrc"),
|
||||||
@ -178,9 +164,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -209,9 +193,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -220,9 +202,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["env-base"],
|
||||||
"env-base",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("env", ".babelrc"),
|
alias: fixture("env", ".babelrc"),
|
||||||
loc: fixture("env", ".babelrc"),
|
loc: fixture("env", ".babelrc"),
|
||||||
@ -253,9 +233,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -264,9 +242,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["env-base"],
|
||||||
"env-base",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("env", ".babelrc"),
|
alias: fixture("env", ".babelrc"),
|
||||||
loc: fixture("env", ".babelrc"),
|
loc: fixture("env", ".babelrc"),
|
||||||
@ -275,9 +251,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["env-foo"],
|
||||||
"env-foo",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("env", ".babelrc.env.foo"),
|
alias: fixture("env", ".babelrc.env.foo"),
|
||||||
loc: fixture("env", ".babelrc.env.foo"),
|
loc: fixture("env", ".babelrc.env.foo"),
|
||||||
@ -309,9 +283,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -320,9 +292,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["env-base"],
|
||||||
"env-base",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("env", ".babelrc"),
|
alias: fixture("env", ".babelrc"),
|
||||||
loc: fixture("env", ".babelrc"),
|
loc: fixture("env", ".babelrc"),
|
||||||
@ -331,9 +301,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["env-bar"],
|
||||||
"env-bar",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("env", ".babelrc.env.bar"),
|
alias: fixture("env", ".babelrc.env.bar"),
|
||||||
loc: fixture("env", ".babelrc.env.bar"),
|
loc: fixture("env", ".babelrc.env.bar"),
|
||||||
@ -353,7 +321,6 @@ describe("buildConfigChain", function () {
|
|||||||
assert.deepEqual(chain, expected);
|
assert.deepEqual(chain, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("env - foo", function() {
|
it("env - foo", function() {
|
||||||
process.env.NODE_ENV = "foo";
|
process.env.NODE_ENV = "foo";
|
||||||
|
|
||||||
@ -403,9 +370,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -414,10 +379,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["foo", "bar"],
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("js-config", ".babelrc.js"),
|
alias: fixture("js-config", ".babelrc.js"),
|
||||||
loc: fixture("js-config", ".babelrc.js"),
|
loc: fixture("js-config", ".babelrc.js"),
|
||||||
@ -446,9 +408,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -486,9 +446,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -497,10 +455,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["foo", "bar"],
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("js-config-default", ".babelrc.js"),
|
alias: fixture("js-config-default", ".babelrc.js"),
|
||||||
loc: fixture("js-config-default", ".babelrc.js"),
|
loc: fixture("js-config-default", ".babelrc.js"),
|
||||||
@ -528,9 +483,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -539,9 +492,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["extended"],
|
||||||
"extended",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("extended.babelrc.json"),
|
alias: fixture("extended.babelrc.json"),
|
||||||
loc: fixture("extended.babelrc.json"),
|
loc: fixture("extended.babelrc.json"),
|
||||||
@ -550,10 +501,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["foo", "bar"],
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("js-config-extended", ".babelrc.js"),
|
alias: fixture("js-config-extended", ".babelrc.js"),
|
||||||
loc: fixture("js-config-extended", ".babelrc.js"),
|
loc: fixture("js-config-extended", ".babelrc.js"),
|
||||||
@ -573,8 +521,10 @@ describe("buildConfigChain", function () {
|
|||||||
assert.deepEqual(chain, expected);
|
assert.deepEqual(chain, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("json-pkg-config-no-babel - should not throw if" +
|
it(
|
||||||
" package.json doesn't contain a `babel` field", function () {
|
"json-pkg-config-no-babel - should not throw if" +
|
||||||
|
" package.json doesn't contain a `babel` field",
|
||||||
|
function() {
|
||||||
const chain = buildConfigChain({
|
const chain = buildConfigChain({
|
||||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||||
});
|
});
|
||||||
@ -583,9 +533,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -594,9 +542,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
plugins: [
|
plugins: ["json"],
|
||||||
"json",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
|
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||||
loc: 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);
|
assert.deepEqual(chain, expected);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
it("should not ignore file matching negated file pattern", function() {
|
it("should not ignore file matching negated file pattern", function() {
|
||||||
const chain = buildConfigChain({
|
const chain = buildConfigChain({
|
||||||
@ -625,9 +572,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -636,10 +581,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["*", "!src.js"],
|
||||||
"*",
|
|
||||||
"!src.js",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("ignore-negate", ".babelrc"),
|
alias: fixture("ignore-negate", ".babelrc"),
|
||||||
loc: fixture("ignore-negate", ".babelrc"),
|
loc: fixture("ignore-negate", ".babelrc"),
|
||||||
@ -674,9 +616,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["root-ignore"],
|
||||||
"root-ignore",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture(".babelignore"),
|
alias: fixture(".babelignore"),
|
||||||
loc: fixture(".babelignore"),
|
loc: fixture(".babelignore"),
|
||||||
@ -685,10 +625,7 @@ describe("buildConfigChain", function () {
|
|||||||
{
|
{
|
||||||
type: "options",
|
type: "options",
|
||||||
options: {
|
options: {
|
||||||
ignore: [
|
ignore: ["*", "!folder"],
|
||||||
"*",
|
|
||||||
"!folder",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alias: fixture("ignore-negate-folder", ".babelrc"),
|
alias: fixture("ignore-negate-folder", ".babelrc"),
|
||||||
loc: fixture("ignore-negate-folder", ".babelrc"),
|
loc: fixture("ignore-negate-folder", ".babelrc"),
|
||||||
@ -714,83 +651,71 @@ describe("buildConfigChain", function () {
|
|||||||
assert.equal(chain2, null);
|
assert.equal(chain2, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("js-json-config - should throw an error if both a .babelrc" +
|
it(
|
||||||
" and a .babelrc.js are present", function () {
|
"js-json-config - should throw an error if both a .babelrc" +
|
||||||
assert.throws(
|
" and a .babelrc.js are present",
|
||||||
function() {
|
function() {
|
||||||
|
assert.throws(function() {
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("js-json-config", "src.js"),
|
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" +
|
it(
|
||||||
" and a package.json with a babel field are present", function () {
|
"js-pkg-config - should throw an error if both a .babelrc.js" +
|
||||||
assert.throws(
|
" and a package.json with a babel field are present",
|
||||||
function() {
|
function() {
|
||||||
|
assert.throws(function() {
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("js-pkg-config", "src.js"),
|
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" +
|
it(
|
||||||
" and a package.json with a babel field are present", function () {
|
"json-pkg-config - should throw an error if both a .babelrc" +
|
||||||
assert.throws(
|
" and a package.json with a babel field are present",
|
||||||
function() {
|
function() {
|
||||||
|
assert.throws(function() {
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("json-pkg-config", "src.js"),
|
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() {
|
it("js-config-error", function() {
|
||||||
assert.throws(
|
assert.throws(function() {
|
||||||
function () {
|
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("js-config-error", "src.js"),
|
filename: fixture("js-config-error", "src.js"),
|
||||||
});
|
});
|
||||||
},
|
}, /Error while loading config/);
|
||||||
/Error while loading config/
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("js-config-error2", function() {
|
it("js-config-error2", function() {
|
||||||
assert.throws(
|
assert.throws(function() {
|
||||||
function () {
|
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("js-config-error2", "src.js"),
|
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() {
|
it("js-config-error3", function() {
|
||||||
assert.throws(
|
assert.throws(function() {
|
||||||
function () {
|
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("js-config-error3", "src.js"),
|
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() {
|
it("json-config-error", function() {
|
||||||
assert.throws(
|
assert.throws(function() {
|
||||||
function () {
|
|
||||||
buildConfigChain({
|
buildConfigChain({
|
||||||
filename: fixture("json-config-error", "src.js"),
|
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);
|
assert.deepEqual(evaluate.value, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
traverse(parse(code, {
|
traverse(
|
||||||
|
parse(code, {
|
||||||
plugins: ["*"],
|
plugins: ["*"],
|
||||||
}), visitor);
|
}),
|
||||||
|
visitor,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,14 +59,39 @@ describe("evaluation", function () {
|
|||||||
addTest("'abc' === 'xyz' || 1 === 1", "LogicalExpression", true);
|
addTest("'abc' === 'xyz' || 1 === 1", "LogicalExpression", true);
|
||||||
addTest("'abc' === 'xyz' || 1 === 10", "LogicalExpression", false);
|
addTest("'abc' === 'xyz' || 1 === 10", "LogicalExpression", false);
|
||||||
addTest("'abc' === 'abc' || config.flag === 1", "LogicalExpression", true);
|
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("'abc' !== 'abc' && config.flag === 1", "LogicalExpression", false);
|
||||||
addTest("obj.a === 'abc' && 1 === 1", "LogicalExpression", undefined, true);
|
addTest("obj.a === 'abc' && 1 === 1", "LogicalExpression", undefined, true);
|
||||||
addTest("'abc' === 'abc' && (1 === 1 || config.flag)", "LogicalExpression", true);
|
addTest(
|
||||||
addTest("'abc' === 'xyz' || (1 === 1 && config.flag)", "LogicalExpression", undefined, true);
|
"'abc' === 'abc' && (1 === 1 || config.flag)",
|
||||||
addTest("'abc' === 'xyz' || (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
|
"LogicalExpression",
|
||||||
addTest("'abc' === 'abc' && (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
|
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("({})", "ObjectExpression", {});
|
||||||
addTest("({a: '1'})", "ObjectExpression", { a: "1" });
|
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", () => {
|
it("throws for babel 5 plugin", () => {
|
||||||
return assert.throws(() => {
|
return assert.throws(() => {
|
||||||
manageOptions({
|
manageOptions({
|
||||||
plugins: [
|
plugins: [({ Plugin }) => new Plugin("object-assign", {})],
|
||||||
({ Plugin }) => new Plugin("object-assign", {}),
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
}, /Babel 5 plugin is being run with Babel 6/);
|
}, /Babel 5 plugin is being run with Babel 6/);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("mergeOptions", () => {
|
describe("mergeOptions", () => {
|
||||||
it("throws for removed babel 5 options", () => {
|
it("throws for removed babel 5 options", () => {
|
||||||
return assert.throws(
|
return assert.throws(() => {
|
||||||
() => {
|
|
||||||
manageOptions({
|
manageOptions({
|
||||||
"randomOption": true,
|
randomOption: true,
|
||||||
});
|
});
|
||||||
},
|
}, /Unknown option: base.randomOption/);
|
||||||
/Unknown option: base.randomOption/
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("throws for removed babel 5 options", () => {
|
it("throws for removed babel 5 options", () => {
|
||||||
return assert.throws(
|
return assert.throws(
|
||||||
() => {
|
() => {
|
||||||
manageOptions({
|
manageOptions({
|
||||||
"auxiliaryComment": true,
|
auxiliaryComment: true,
|
||||||
"blacklist": true,
|
blacklist: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line max-len
|
// 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", () => {
|
it("throws for resolved but erroring preset", () => {
|
||||||
return assert.throws(
|
return assert.throws(() => {
|
||||||
() => {
|
|
||||||
manageOptions({
|
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) {
|
function presetTest(name) {
|
||||||
it(name, function() {
|
it(name, function() {
|
||||||
const { options, passes } = manageOptions({
|
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));
|
assert.equal(true, Array.isArray(options.plugins));
|
||||||
@ -66,9 +62,15 @@ describe("option-manager", () => {
|
|||||||
|
|
||||||
function presetThrowsTest(name, msg) {
|
function presetThrowsTest(name, msg) {
|
||||||
it(name, function() {
|
it(name, function() {
|
||||||
assert.throws(() => manageOptions({
|
assert.throws(
|
||||||
"presets": [path.join(__dirname, "fixtures/option-manager/presets", name)],
|
() =>
|
||||||
}), msg);
|
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_function");
|
||||||
presetTest("es2015_default_object");
|
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("es2015_invalid", /Unsupported format: string/);
|
||||||
presetThrowsTest("es5_invalid", /Unsupported format: string/);
|
presetThrowsTest("es5_invalid", /Unsupported format: string/);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,13 +7,15 @@ describe("traversal path", function () {
|
|||||||
const expectCode = "function foo() {}";
|
const expectCode = "function foo() {}";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
FunctionDeclaration: function(path) {
|
FunctionDeclaration: function(path) {
|
||||||
path.replaceWithSourceString("console.whatever()");
|
path.replaceWithSourceString("console.whatever()");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("console.whatever();");
|
chai.expect(actualCode).to.be.equal("console.whatever();");
|
||||||
@ -23,22 +25,26 @@ describe("traversal path", function () {
|
|||||||
const expectCode = "var fn = () => true;";
|
const expectCode = "var fn = () => true;";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ArrowFunctionExpression: function(path) {
|
ArrowFunctionExpression: function(path) {
|
||||||
path.get("body").replaceWith({
|
path.get("body").replaceWith({
|
||||||
type: "BlockStatement",
|
type: "BlockStatement",
|
||||||
body: [{
|
body: [
|
||||||
|
{
|
||||||
type: "ReturnStatement",
|
type: "ReturnStatement",
|
||||||
argument: {
|
argument: {
|
||||||
type: "BooleanLiteral",
|
type: "BooleanLiteral",
|
||||||
value: true,
|
value: true,
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("var fn = () => {\n return true;\n};");
|
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 expectCode = "var fn = () => { return true; }";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ArrowFunctionExpression: function(path) {
|
ArrowFunctionExpression: function(path) {
|
||||||
path.get("body").replaceWith({
|
path.get("body").replaceWith({
|
||||||
@ -57,7 +64,8 @@ describe("traversal path", function () {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("var fn = () => true;");
|
chai.expect(actualCode).to.be.equal("var fn = () => true;");
|
||||||
@ -67,23 +75,27 @@ describe("traversal path", function () {
|
|||||||
const expectCode = "for (KEY in right);";
|
const expectCode = "for (KEY in right);";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ForInStatement: function(path) {
|
ForInStatement: function(path) {
|
||||||
path.get("left").replaceWith({
|
path.get("left").replaceWith({
|
||||||
type: "VariableDeclaration",
|
type: "VariableDeclaration",
|
||||||
kind: "var",
|
kind: "var",
|
||||||
declarations: [{
|
declarations: [
|
||||||
|
{
|
||||||
type: "VariableDeclarator",
|
type: "VariableDeclarator",
|
||||||
id: {
|
id: {
|
||||||
type: "Identifier",
|
type: "Identifier",
|
||||||
name: "KEY",
|
name: "KEY",
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("for (var KEY in right);");
|
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 expectCode = "for (var KEY in right);";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ForInStatement: function(path) {
|
ForInStatement: function(path) {
|
||||||
path.get("left").replaceWith({
|
path.get("left").replaceWith({
|
||||||
@ -102,7 +115,8 @@ describe("traversal path", function () {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("for (KEY in right);");
|
chai.expect(actualCode).to.be.equal("for (KEY in right);");
|
||||||
@ -112,23 +126,27 @@ describe("traversal path", function () {
|
|||||||
const expectCode = "for (KEY;;);";
|
const expectCode = "for (KEY;;);";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ForStatement: function(path) {
|
ForStatement: function(path) {
|
||||||
path.get("init").replaceWith({
|
path.get("init").replaceWith({
|
||||||
type: "VariableDeclaration",
|
type: "VariableDeclaration",
|
||||||
kind: "var",
|
kind: "var",
|
||||||
declarations: [{
|
declarations: [
|
||||||
|
{
|
||||||
type: "VariableDeclarator",
|
type: "VariableDeclarator",
|
||||||
id: {
|
id: {
|
||||||
type: "Identifier",
|
type: "Identifier",
|
||||||
name: "KEY",
|
name: "KEY",
|
||||||
},
|
},
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("for (var KEY;;);");
|
chai.expect(actualCode).to.be.equal("for (var KEY;;);");
|
||||||
@ -138,7 +156,8 @@ describe("traversal path", function () {
|
|||||||
const expectCode = "for (var KEY;;);";
|
const expectCode = "for (var KEY;;);";
|
||||||
|
|
||||||
const actualCode = transform(expectCode, {
|
const actualCode = transform(expectCode, {
|
||||||
plugins: [new Plugin({
|
plugins: [
|
||||||
|
new Plugin({
|
||||||
visitor: {
|
visitor: {
|
||||||
ForStatement: function(path) {
|
ForStatement: function(path) {
|
||||||
path.get("init").replaceWith({
|
path.get("init").replaceWith({
|
||||||
@ -147,7 +166,8 @@ describe("traversal path", function () {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})],
|
}),
|
||||||
|
],
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
chai.expect(actualCode).to.be.equal("for (KEY;;);");
|
chai.expect(actualCode).to.be.equal("for (KEY;;);");
|
||||||
|
|||||||
@ -20,9 +20,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["module:preset"],
|
||||||
"module:preset",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -32,9 +30,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["module:plugin"],
|
||||||
"module:plugin",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,9 +40,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["mod"],
|
||||||
"mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -56,9 +50,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["mod"],
|
||||||
"mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,9 +60,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["babel-preset-mod"],
|
||||||
"babel-preset-mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,9 +70,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["babel-plugin-mod"],
|
||||||
"babel-plugin-mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,9 +80,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@babel/foo"],
|
||||||
"@babel/foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,9 +90,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@babel/foo"],
|
||||||
"@babel/foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -116,9 +100,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@babel/preset-foo"],
|
||||||
"@babel/preset-foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,9 +110,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@babel/plugin-foo"],
|
||||||
"@babel/plugin-foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -140,9 +120,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@foo/mod"],
|
||||||
"@foo/mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -152,9 +130,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@foo/mod"],
|
||||||
"@foo/mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -164,9 +140,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@foo/babel-preset-mod"],
|
||||||
"@foo/babel-preset-mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -176,9 +150,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@foo/babel-plugin-mod"],
|
||||||
"@foo/babel-plugin-mod",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -188,9 +160,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["./dir/preset.js"],
|
||||||
"./dir/preset.js",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -200,9 +170,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["./dir/plugin.js"],
|
||||||
"./dir/plugin.js",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -212,9 +180,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["mod/preset"],
|
||||||
"mod/preset",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -224,9 +190,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["mod/plugin"],
|
||||||
"mod/plugin",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -236,9 +200,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@foo/mod/preset"],
|
||||||
"@foo/mod/preset",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -248,9 +210,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@foo/mod/plugin"],
|
||||||
"@foo/mod/plugin",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -260,9 +220,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["@babel/mod/preset"],
|
||||||
"@babel/mod/preset",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -272,9 +230,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["@babel/mod/plugin"],
|
||||||
"@babel/mod/plugin",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -285,9 +241,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-preset-foo'.*\n- If you want to resolve "foo", use "module:foo"/);
|
}, /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("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-plugin-foo'.*\n- If you want to resolve "foo", use "module:foo"/);
|
}, /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("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-preset-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
}, /Cannot find module 'babel-preset-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
||||||
@ -330,9 +280,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-plugin-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
}, /Cannot find module 'babel-plugin-foo'.*\n- Did you mean "@babel\/foo"\?/);
|
||||||
@ -345,9 +293,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["testplugin"],
|
||||||
"testplugin",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-preset-testplugin'.*\n- Did you accidentally pass a preset as a plugin\?/);
|
}, /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("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["testpreset"],
|
||||||
"testpreset",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
}, /Cannot find module 'babel-plugin-testpreset'.*\n- Did you accidentally pass a plugin as a preset\?/);
|
}, /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("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
presets: [
|
presets: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
}, /Cannot find module 'babel-preset-foo'/);
|
}, /Cannot find module 'babel-preset-foo'/);
|
||||||
});
|
});
|
||||||
@ -389,9 +331,7 @@ describe("addon resolution", function () {
|
|||||||
babel.transform("", {
|
babel.transform("", {
|
||||||
filename: "filename.js",
|
filename: "filename.js",
|
||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [
|
plugins: ["foo"],
|
||||||
"foo",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
}, /Cannot find module 'babel-plugin-foo'/);
|
}, /Cannot find module 'babel-plugin-foo'/);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -54,7 +54,7 @@ export default class Buffer {
|
|||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get() {
|
get() {
|
||||||
return this.map = map.get();
|
return (this.map = map.get());
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
Object.defineProperty(this, "map", { value, writable: true });
|
Object.defineProperty(this, "map", { value, writable: true });
|
||||||
@ -81,7 +81,11 @@ export default class Buffer {
|
|||||||
|
|
||||||
queue(str: string): void {
|
queue(str: string): void {
|
||||||
// Drop trailing spaces when a newline is inserted.
|
// 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;
|
const { line, column, filename, identifierName } = this._sourcePosition;
|
||||||
this._queue.unshift([str, line, column, identifierName, filename]);
|
this._queue.unshift([str, line, column, identifierName, filename]);
|
||||||
@ -89,13 +93,26 @@ export default class Buffer {
|
|||||||
|
|
||||||
_flush(): void {
|
_flush(): void {
|
||||||
let item;
|
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 there the line is ending, adding a new mapping marker is redundant
|
||||||
if (this._map && str[0] !== "\n") {
|
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);
|
this._buf.push(str);
|
||||||
@ -112,11 +129,15 @@ export default class Buffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeTrailingNewline(): void {
|
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 {
|
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 {
|
endsWith(suffix: string): boolean {
|
||||||
@ -133,7 +154,8 @@ export default class Buffer {
|
|||||||
return last === suffix;
|
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) {
|
if (suffix.length <= end.length) {
|
||||||
return end.slice(-suffix.length) === suffix;
|
return end.slice(-suffix.length) === suffix;
|
||||||
}
|
}
|
||||||
@ -157,10 +179,10 @@ export default class Buffer {
|
|||||||
|
|
||||||
const pos = loc ? loc[prop] : null;
|
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.line = pos ? pos.line : null;
|
||||||
this._sourcePosition.column = pos ? pos.column : 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 extra = this._queue.reduce((acc, item) => item[0] + acc, "");
|
||||||
const lastIndex = extra.lastIndexOf("\n");
|
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 {
|
getCurrentLine(): number {
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
import * as n from "../node";
|
import * as n from "../node";
|
||||||
|
|
||||||
|
|
||||||
export function UnaryExpression(node: Object) {
|
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.word(node.operator);
|
||||||
this.space();
|
this.space();
|
||||||
} else {
|
} else {
|
||||||
@ -51,12 +54,16 @@ export function NewExpression(node: Object, parent: Object) {
|
|||||||
this.word("new");
|
this.word("new");
|
||||||
this.space();
|
this.space();
|
||||||
this.print(node.callee, node);
|
this.print(node.callee, node);
|
||||||
if (this.format.minified &&
|
if (
|
||||||
|
this.format.minified &&
|
||||||
node.arguments.length === 0 &&
|
node.arguments.length === 0 &&
|
||||||
!node.optional &&
|
!node.optional &&
|
||||||
!t.isCallExpression(parent, { callee: node }) &&
|
!t.isCallExpression(parent, { callee: node }) &&
|
||||||
!t.isMemberExpression(parent) &&
|
!t.isMemberExpression(parent) &&
|
||||||
!t.isNewExpression(parent)) return;
|
!t.isNewExpression(parent)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (node.optional) {
|
if (node.optional) {
|
||||||
this.token("?.");
|
this.token("?.");
|
||||||
@ -164,7 +171,9 @@ export function AssignmentPattern(node: Object) {
|
|||||||
export function AssignmentExpression(node: Object, parent: Object) {
|
export function AssignmentExpression(node: Object, parent: Object) {
|
||||||
// Somewhere inside a for statement `init` node but doesn't usually
|
// Somewhere inside a for statement `init` node but doesn't usually
|
||||||
// needs a paren except for `in` expressions: `for (a in b ? a : b;;)`
|
// 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);
|
!n.needsParens(node, parent);
|
||||||
|
|
||||||
if (parens) {
|
if (parens) {
|
||||||
|
|||||||
@ -159,7 +159,10 @@ export function FunctionTypeAnnotation(node: Object, parent: Object) {
|
|||||||
this.token(")");
|
this.token(")");
|
||||||
|
|
||||||
// this node type is overloaded, not sure why but it makes it EXTREMELY annoying
|
// 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(":");
|
this.token(":");
|
||||||
} else {
|
} else {
|
||||||
this.space();
|
this.space();
|
||||||
@ -183,7 +186,10 @@ export function InterfaceExtends(node: Object) {
|
|||||||
this.print(node.typeParameters, node);
|
this.print(node.typeParameters, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation };
|
export {
|
||||||
|
InterfaceExtends as ClassImplements,
|
||||||
|
InterfaceExtends as GenericTypeAnnotation,
|
||||||
|
};
|
||||||
|
|
||||||
export function _interfaceish(node: Object) {
|
export function _interfaceish(node: Object) {
|
||||||
this.print(node.id, node);
|
this.print(node.id, node);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ export function _params(node: Object) {
|
|||||||
this.print(node.typeParameters, node);
|
this.print(node.typeParameters, node);
|
||||||
this.token("(");
|
this.token("(");
|
||||||
this.printList(node.params, node, {
|
this.printList(node.params, node, {
|
||||||
iterator: (node) => {
|
iterator: node => {
|
||||||
if (node.optional) this.token("?");
|
if (node.optional) this.token("?");
|
||||||
this.print(node.typeAnnotation, node);
|
this.print(node.typeAnnotation, node);
|
||||||
},
|
},
|
||||||
@ -79,7 +79,11 @@ export function ArrowFunctionExpression(node: Object) {
|
|||||||
|
|
||||||
const firstParam = node.params[0];
|
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);
|
this.print(firstParam, node);
|
||||||
} else {
|
} else {
|
||||||
this._params(node);
|
this._params(node);
|
||||||
@ -93,6 +97,11 @@ export function ArrowFunctionExpression(node: Object) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function hasTypes(node, param) {
|
function hasTypes(node, param) {
|
||||||
return node.typeParameters || node.returnType || param.typeAnnotation || param.optional ||
|
return (
|
||||||
param.trailingComments;
|
node.typeParameters ||
|
||||||
|
node.returnType ||
|
||||||
|
param.typeAnnotation ||
|
||||||
|
param.optional ||
|
||||||
|
param.trailingComments
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,7 +91,10 @@ function ExportDeclaration(node: Object) {
|
|||||||
let hasSpecial = false;
|
let hasSpecial = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
const first = specifiers[0];
|
const first = specifiers[0];
|
||||||
if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) {
|
if (
|
||||||
|
t.isExportDefaultSpecifier(first) ||
|
||||||
|
t.isExportNamespaceSpecifier(first)
|
||||||
|
) {
|
||||||
hasSpecial = true;
|
hasSpecial = true;
|
||||||
this.print(specifiers.shift(), node);
|
this.print(specifiers.shift(), node);
|
||||||
if (specifiers.length) {
|
if (specifiers.length) {
|
||||||
@ -138,7 +141,10 @@ export function ImportDeclaration(node: Object) {
|
|||||||
// print "special" specifiers first
|
// print "special" specifiers first
|
||||||
while (true) {
|
while (true) {
|
||||||
const first = specifiers[0];
|
const first = specifiers[0];
|
||||||
if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) {
|
if (
|
||||||
|
t.isImportDefaultSpecifier(first) ||
|
||||||
|
t.isImportNamespaceSpecifier(first)
|
||||||
|
) {
|
||||||
this.print(specifiers.shift(), node);
|
this.print(specifiers.shift(), node);
|
||||||
if (specifiers.length) {
|
if (specifiers.length) {
|
||||||
this.token(",");
|
this.token(",");
|
||||||
|
|||||||
@ -17,7 +17,8 @@ export function IfStatement(node: Object) {
|
|||||||
this.token(")");
|
this.token(")");
|
||||||
this.space();
|
this.space();
|
||||||
|
|
||||||
const needsBlock = node.alternate && t.isIfStatement(getLastStatement(node.consequent));
|
const needsBlock =
|
||||||
|
node.alternate && t.isIfStatement(getLastStatement(node.consequent));
|
||||||
if (needsBlock) {
|
if (needsBlock) {
|
||||||
this.token("{");
|
this.token("{");
|
||||||
this.newline();
|
this.newline();
|
||||||
@ -261,7 +262,10 @@ export function VariableDeclaration(node: Object, parent: Object) {
|
|||||||
|
|
||||||
let separator;
|
let separator;
|
||||||
if (hasInits) {
|
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);
|
this.print(node.argument, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export { RestElement as SpreadElement };
|
||||||
RestElement as SpreadElement,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function ObjectExpression(node: Object) {
|
export function ObjectExpression(node: Object) {
|
||||||
const props = node.properties;
|
const props = node.properties;
|
||||||
@ -45,8 +43,11 @@ export function ObjectProperty(node: Object) {
|
|||||||
this.token("]");
|
this.token("]");
|
||||||
} else {
|
} else {
|
||||||
// print `({ foo: foo = 5 } = {})` as `({ foo = 5 } = {});`
|
// print `({ foo: foo = 5 } = {})` as `({ foo = 5 } = {});`
|
||||||
if (t.isAssignmentPattern(node.value) && t.isIdentifier(node.key) &&
|
if (
|
||||||
node.key.name === node.value.left.name) {
|
t.isAssignmentPattern(node.value) &&
|
||||||
|
t.isIdentifier(node.key) &&
|
||||||
|
node.key.name === node.value.left.name
|
||||||
|
) {
|
||||||
this.print(node.value, node);
|
this.print(node.value, node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -54,10 +55,12 @@ export function ObjectProperty(node: Object) {
|
|||||||
this.print(node.key, node);
|
this.print(node.key, node);
|
||||||
|
|
||||||
// shorthand!
|
// shorthand!
|
||||||
if (node.shorthand &&
|
if (
|
||||||
|
node.shorthand &&
|
||||||
(t.isIdentifier(node.key) &&
|
(t.isIdentifier(node.key) &&
|
||||||
t.isIdentifier(node.value) &&
|
t.isIdentifier(node.value) &&
|
||||||
node.key.name === node.value.name)) {
|
node.key.name === node.value.name)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,9 +61,13 @@ function normalizeOptions(code, opts): Format {
|
|||||||
if (format.minified) {
|
if (format.minified) {
|
||||||
format.compact = true;
|
format.compact = true;
|
||||||
|
|
||||||
format.shouldPrintComment = format.shouldPrintComment || (() => format.comments);
|
format.shouldPrintComment =
|
||||||
|
format.shouldPrintComment || (() => format.comments);
|
||||||
} else {
|
} else {
|
||||||
format.shouldPrintComment = format.shouldPrintComment || ((value) => format.comments ||
|
format.shouldPrintComment =
|
||||||
|
format.shouldPrintComment ||
|
||||||
|
(value =>
|
||||||
|
format.comments ||
|
||||||
(value.indexOf("@license") >= 0 || value.indexOf("@preserve") >= 0));
|
(value.indexOf("@license") >= 0 || value.indexOf("@preserve") >= 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +75,9 @@ function normalizeOptions(code, opts): Format {
|
|||||||
format.compact = code.length > 500_000; // 500KB
|
format.compact = code.length > 500_000; // 500KB
|
||||||
|
|
||||||
if (format.compact) {
|
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) {
|
function add(type, func) {
|
||||||
const fn = newObj[type];
|
const fn = newObj[type];
|
||||||
newObj[type] = fn ? function(node, parent, stack) {
|
newObj[type] = fn
|
||||||
|
? function(node, parent, stack) {
|
||||||
const result = fn(node, parent, stack);
|
const result = fn(node, parent, stack);
|
||||||
|
|
||||||
return result == null ? func(node, parent, stack) : result;
|
return result == null ? func(node, parent, stack) : result;
|
||||||
} : func;
|
}
|
||||||
|
: func;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const type of Object.keys(obj)) {
|
for (const type of Object.keys(obj)) {
|
||||||
|
|
||||||
const aliases = t.FLIPPED_ALIAS_KEYS[type];
|
const aliases = t.FLIPPED_ALIAS_KEYS[type];
|
||||||
if (aliases) {
|
if (aliases) {
|
||||||
for (const alias of aliases) {
|
for (const alias of aliases) {
|
||||||
@ -46,8 +47,10 @@ function isOrHasCallExpression(node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t.isMemberExpression(node)) {
|
if (t.isMemberExpression(node)) {
|
||||||
return isOrHasCallExpression(node.object) ||
|
return (
|
||||||
(!node.computed && isOrHasCallExpression(node.property));
|
isOrHasCallExpression(node.object) ||
|
||||||
|
(!node.computed && isOrHasCallExpression(node.property))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,11 +38,19 @@ export function UpdateExpression(node: Object, parent: Object): boolean {
|
|||||||
return t.isMemberExpression(parent) && parent.object === node;
|
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 });
|
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);
|
return isFirstInStatement(printStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +63,8 @@ export function Binary(node: Object, parent: Object): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) ||
|
((t.isCallExpression(parent) || t.isNewExpression(parent)) &&
|
||||||
|
parent.callee === node) ||
|
||||||
t.isUnaryLike(parent) ||
|
t.isUnaryLike(parent) ||
|
||||||
(t.isMemberExpression(parent) && parent.object === node) ||
|
(t.isMemberExpression(parent) && parent.object === node) ||
|
||||||
t.isAwaitExpression(parent)
|
t.isAwaitExpression(parent)
|
||||||
@ -72,7 +81,9 @@ export function Binary(node: Object, parent: Object): boolean {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
// Logical expressions with the same precedence don't need parens.
|
// 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
|
parentPos > nodePos
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
@ -85,11 +96,13 @@ export function Binary(node: Object, parent: Object): boolean {
|
|||||||
export function BinaryExpression(node: Object, parent: Object): boolean {
|
export function BinaryExpression(node: Object, parent: Object): boolean {
|
||||||
// let i = (1 in []);
|
// let i = (1 in []);
|
||||||
// for ((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 {
|
export function SequenceExpression(node: Object, parent: Object): boolean {
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// Although parentheses wouldn"t hurt around sequence
|
// Although parentheses wouldn"t hurt around sequence
|
||||||
// expressions in the head of for loops, traditional style
|
// 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 {
|
export function YieldExpression(node: Object, parent: Object): boolean {
|
||||||
return t.isBinary(parent) ||
|
return (
|
||||||
|
t.isBinary(parent) ||
|
||||||
t.isUnaryLike(parent) ||
|
t.isUnaryLike(parent) ||
|
||||||
t.isCallExpression(parent) ||
|
t.isCallExpression(parent) ||
|
||||||
t.isMemberExpression(parent) ||
|
t.isMemberExpression(parent) ||
|
||||||
t.isNewExpression(parent) ||
|
t.isNewExpression(parent) ||
|
||||||
(t.isConditionalExpression(parent) && node === parent.test);
|
(t.isConditionalExpression(parent) && node === parent.test)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { YieldExpression as AwaitExpression };
|
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 });
|
return isFirstInStatement(printStack, { considerDefaultExports: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function UnaryLike(node: Object, parent: Object): boolean {
|
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.isCallExpression(parent, { callee: node }) ||
|
||||||
t.isNewExpression(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 });
|
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
|
// Walk up the print stack to deterimine if our node can come first
|
||||||
// in statement.
|
// in statement.
|
||||||
function isFirstInStatement(printStack: Array<Object>, {
|
function isFirstInStatement(
|
||||||
considerArrow = false,
|
printStack: Array<Object>,
|
||||||
considerDefaultExports = false,
|
{ considerArrow = false, considerDefaultExports = false } = {},
|
||||||
} = {}): boolean {
|
): boolean {
|
||||||
let i = printStack.length - 1;
|
let i = printStack.length - 1;
|
||||||
let node = printStack[i];
|
let node = printStack[i];
|
||||||
i--;
|
i--;
|
||||||
@ -179,8 +203,9 @@ function isFirstInStatement(printStack: Array<Object>, {
|
|||||||
if (
|
if (
|
||||||
t.isExpressionStatement(parent, { expression: node }) ||
|
t.isExpressionStatement(parent, { expression: node }) ||
|
||||||
t.isTaggedTemplateExpression(parent) ||
|
t.isTaggedTemplateExpression(parent) ||
|
||||||
considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node }) ||
|
(considerDefaultExports &&
|
||||||
considerArrow && t.isArrowFunctionExpression(parent, { body: node })
|
t.isExportDefaultDeclaration(parent, { declaration: node })) ||
|
||||||
|
(considerArrow && t.isArrowFunctionExpression(parent, { body: node }))
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import * as t from "babel-types";
|
|||||||
|
|
||||||
type WhitespaceObject = {
|
type WhitespaceObject = {
|
||||||
before?: boolean,
|
before?: boolean,
|
||||||
after?: boolean
|
after?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,15 +45,22 @@ function isHelper(node) {
|
|||||||
} else if (t.isCallExpression(node)) {
|
} else if (t.isCallExpression(node)) {
|
||||||
return isHelper(node.callee);
|
return isHelper(node.callee);
|
||||||
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
|
} 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 {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isType(node) {
|
function isType(node) {
|
||||||
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
|
return (
|
||||||
t.isIdentifier(node) || t.isMemberExpression(node);
|
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 = {
|
export const nodes = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if AssignmentExpression needs whitespace.
|
* Test if AssignmentExpression needs whitespace.
|
||||||
*/
|
*/
|
||||||
@ -164,9 +170,10 @@ export const nodes = {
|
|||||||
* Test if Property needs whitespace.
|
* Test if Property needs whitespace.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nodes.ObjectProperty =
|
nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function(
|
||||||
nodes.ObjectTypeProperty =
|
node: Object,
|
||||||
nodes.ObjectMethod = function (node: Object, parent): ?WhitespaceObject {
|
parent,
|
||||||
|
): ?WhitespaceObject {
|
||||||
if (parent.properties[0] === node) {
|
if (parent.properties[0] === node) {
|
||||||
return {
|
return {
|
||||||
before: true,
|
before: true,
|
||||||
@ -179,7 +186,6 @@ nodes.ObjectMethod = function (node: Object, parent): ?WhitespaceObject {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const list = {
|
export const list = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return VariableDeclaration declarations init properties.
|
* Return VariableDeclaration declarations init properties.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -14,21 +14,21 @@ const ZERO_DECIMAL_INTEGER = /\.0+$/;
|
|||||||
const NON_DECIMAL_LITERAL = /^0[box]/;
|
const NON_DECIMAL_LITERAL = /^0[box]/;
|
||||||
|
|
||||||
export type Format = {
|
export type Format = {
|
||||||
shouldPrintComment: (comment: string) => boolean;
|
shouldPrintComment: (comment: string) => boolean,
|
||||||
retainLines: boolean;
|
retainLines: boolean,
|
||||||
retainFunctionParens: boolean;
|
retainFunctionParens: boolean,
|
||||||
comments: boolean;
|
comments: boolean,
|
||||||
auxiliaryCommentBefore: string;
|
auxiliaryCommentBefore: string,
|
||||||
auxiliaryCommentAfter: string;
|
auxiliaryCommentAfter: string,
|
||||||
compact: boolean | "auto";
|
compact: boolean | "auto",
|
||||||
minified: boolean;
|
minified: boolean,
|
||||||
quotes: "single" | "double";
|
quotes: "single" | "double",
|
||||||
concise: boolean;
|
concise: boolean,
|
||||||
indent: {
|
indent: {
|
||||||
adjustMultilineComment: boolean;
|
adjustMultilineComment: boolean,
|
||||||
style: string;
|
style: string,
|
||||||
base: number;
|
base: number,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class Printer {
|
export default class Printer {
|
||||||
@ -107,7 +107,10 @@ export default class Printer {
|
|||||||
space(force: boolean = false): void {
|
space(force: boolean = false): void {
|
||||||
if (this.format.compact) return;
|
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();
|
this._space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,14 +152,14 @@ export default class Printer {
|
|||||||
token(str: string): void {
|
token(str: string): void {
|
||||||
// space is mandatory to avoid outputting <!--
|
// space is mandatory to avoid outputting <!--
|
||||||
// http://javascript.spec.whatwg.org/#comment-syntax
|
// 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`
|
// Need spaces for operators of the same kind to avoid: `a+++b`
|
||||||
(str[0] === "+" && this.endsWith("+")) ||
|
(str[0] === "+" && this.endsWith("+")) ||
|
||||||
(str[0] === "-" && this.endsWith("-")) ||
|
(str[0] === "-" && this.endsWith("-")) ||
|
||||||
|
|
||||||
// Needs spaces to avoid changing '34' to '34.', which would still be a valid number.
|
// 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();
|
this._space();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,9 +297,9 @@ export default class Printer {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
startTerminatorless(): Object {
|
startTerminatorless(): Object {
|
||||||
return this._parenPushNewlineState = {
|
return (this._parenPushNewlineState = {
|
||||||
printed: false,
|
printed: false,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -322,7 +325,11 @@ export default class Printer {
|
|||||||
const printMethod = this[node.type];
|
const printMethod = this[node.type];
|
||||||
if (!printMethod) {
|
if (!printMethod) {
|
||||||
// eslint-disable-next-line max-len
|
// 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);
|
this._printStack.push(node);
|
||||||
@ -335,7 +342,8 @@ export default class Printer {
|
|||||||
if (
|
if (
|
||||||
this.format.retainFunctionParens &&
|
this.format.retainFunctionParens &&
|
||||||
node.type === "FunctionExpression" &&
|
node.type === "FunctionExpression" &&
|
||||||
node.extra && node.extra.parenthesized
|
node.extra &&
|
||||||
|
node.extra.parenthesized
|
||||||
) {
|
) {
|
||||||
needsParens = true;
|
needsParens = true;
|
||||||
}
|
}
|
||||||
@ -343,7 +351,7 @@ export default class Printer {
|
|||||||
|
|
||||||
this._printLeadingComments(node, parent);
|
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.withSource("start", loc, () => {
|
||||||
this[node.type](node, parent);
|
this[node.type](node, parent);
|
||||||
});
|
});
|
||||||
@ -392,7 +400,12 @@ export default class Printer {
|
|||||||
|
|
||||||
getPossibleRaw(node) {
|
getPossibleRaw(node) {
|
||||||
const extra = node.extra;
|
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;
|
return extra.raw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,14 +503,24 @@ export default class Printer {
|
|||||||
// user node
|
// user node
|
||||||
if (leading) {
|
if (leading) {
|
||||||
const comments = node.leadingComments;
|
const comments = node.leadingComments;
|
||||||
const comment = comments && find(comments, (comment) =>
|
const comment =
|
||||||
!!comment.loc && this.format.shouldPrintComment(comment.value));
|
comments &&
|
||||||
|
find(
|
||||||
|
comments,
|
||||||
|
comment =>
|
||||||
|
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||||
|
);
|
||||||
|
|
||||||
lines = this._whitespace.getNewlinesBefore(comment || node);
|
lines = this._whitespace.getNewlinesBefore(comment || node);
|
||||||
} else {
|
} else {
|
||||||
const comments = node.trailingComments;
|
const comments = node.trailingComments;
|
||||||
const comment = comments && findLast(comments, (comment) =>
|
const comment =
|
||||||
!!comment.loc && this.format.shouldPrintComment(comment.value));
|
comments &&
|
||||||
|
findLast(
|
||||||
|
comments,
|
||||||
|
comment =>
|
||||||
|
!!comment.loc && this.format.shouldPrintComment(comment.value),
|
||||||
|
);
|
||||||
|
|
||||||
lines = this._whitespace.getNewlinesAfter(comment || node);
|
lines = this._whitespace.getNewlinesAfter(comment || node);
|
||||||
}
|
}
|
||||||
@ -520,7 +543,9 @@ export default class Printer {
|
|||||||
_getComments(leading, node) {
|
_getComments(leading, node) {
|
||||||
// Note, we use a boolean flag here instead of passing in the attribute name as it is faster
|
// Note, we use a boolean flag here instead of passing in the attribute name as it is faster
|
||||||
// because this is called extremely frequently.
|
// because this is called extremely frequently.
|
||||||
return (node && (leading ? node.leadingComments : node.trailingComments)) || [];
|
return (
|
||||||
|
(node && (leading ? node.leadingComments : node.trailingComments)) || []
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_printComment(comment) {
|
_printComment(comment) {
|
||||||
@ -539,21 +564,32 @@ export default class Printer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// whitespace before
|
// 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();
|
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;
|
const offset = comment.loc && comment.loc.start.column;
|
||||||
if (offset) {
|
if (offset) {
|
||||||
const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
const newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||||
val = val.replace(newlineRegex, "\n");
|
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)}`);
|
val = val.replace(/\n(?!$)/g, `\n${repeat(" ", indentSize)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,9 +601,11 @@ export default class Printer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// whitespace after
|
// 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.
|
// Subtract one to account for the line force-added above.
|
||||||
(comment.type === "CommentLine" ? -1 : 0));
|
(comment.type === "CommentLine" ? -1 : 0),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_printComments(comments?: Array<Object>) {
|
_printComments(comments?: Array<Object>) {
|
||||||
|
|||||||
@ -18,16 +18,16 @@ export default class SourceMap {
|
|||||||
|
|
||||||
get() {
|
get() {
|
||||||
if (!this._cachedMap) {
|
if (!this._cachedMap) {
|
||||||
const map = this._cachedMap = new sourceMap.SourceMapGenerator({
|
const map = (this._cachedMap = new sourceMap.SourceMapGenerator({
|
||||||
file: this._opts.sourceMapTarget,
|
file: this._opts.sourceMapTarget,
|
||||||
sourceRoot: this._opts.sourceRoot,
|
sourceRoot: this._opts.sourceRoot,
|
||||||
});
|
}));
|
||||||
|
|
||||||
const code = this._code;
|
const code = this._code;
|
||||||
if (typeof code === "string") {
|
if (typeof code === "string") {
|
||||||
map.setSourceContent(this._opts.sourceFileName, code);
|
map.setSourceContent(this._opts.sourceFileName, code);
|
||||||
} else if (typeof code === "object") {
|
} else if (typeof code === "object") {
|
||||||
Object.keys(code).forEach((sourceFileName) => {
|
Object.keys(code).forEach(sourceFileName => {
|
||||||
map.setSourceContent(sourceFileName, code[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
|
// If this mapping points to the same source location as the last one, we can ignore it since
|
||||||
// the previous one covers it.
|
// the previous one covers it.
|
||||||
if (this._lastGenLine === generatedLine && this._lastSourceLine === line &&
|
if (
|
||||||
this._lastSourceColumn === column) {
|
this._lastGenLine === generatedLine &&
|
||||||
|
this._lastSourceLine === line &&
|
||||||
|
this._lastSourceColumn === column
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +83,10 @@ export default class SourceMap {
|
|||||||
column: generatedColumn,
|
column: generatedColumn,
|
||||||
},
|
},
|
||||||
source: line == null ? undefined : filename || this._opts.sourceFileName,
|
source: line == null ? undefined : filename || this._opts.sourceFileName,
|
||||||
original: line == null ? undefined : {
|
original:
|
||||||
|
line == null
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
line: line,
|
line: line,
|
||||||
column: column,
|
column: column,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -17,7 +17,11 @@ export default class Whitespace {
|
|||||||
let endToken;
|
let endToken;
|
||||||
const tokens = this.tokens;
|
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) {
|
if (index >= 0) {
|
||||||
while (index && node.start === tokens[index - 1].start) --index;
|
while (index && node.start === tokens[index - 1].start) --index;
|
||||||
startToken = tokens[index - 1];
|
startToken = tokens[index - 1];
|
||||||
@ -36,7 +40,11 @@ export default class Whitespace {
|
|||||||
let endToken;
|
let endToken;
|
||||||
const tokens = this.tokens;
|
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) {
|
if (index >= 0) {
|
||||||
while (index && node.end === tokens[index - 1].end) --index;
|
while (index && node.end === tokens[index - 1].end) --index;
|
||||||
startToken = tokens[index];
|
startToken = tokens[index];
|
||||||
|
|||||||
@ -27,103 +27,142 @@ describe("generation", function () {
|
|||||||
"b.js": "hi('hello');\n",
|
"b.js": "hi('hello');\n",
|
||||||
};
|
};
|
||||||
const parsed = Object.keys(sources).reduce(function(_parsed, filename) {
|
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;
|
return _parsed;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const combinedAst = {
|
const combinedAst = {
|
||||||
"type": "File",
|
type: "File",
|
||||||
"program": {
|
program: {
|
||||||
"type": "Program",
|
type: "Program",
|
||||||
"sourceType": "module",
|
sourceType: "module",
|
||||||
"body": [].concat(parsed["a.js"].program.body, parsed["b.js"].program.body),
|
body: [].concat(
|
||||||
|
parsed["a.js"].program.body,
|
||||||
|
parsed["b.js"].program.body,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const generated = generate(combinedAst, { sourceMaps: true }, sources);
|
const generated = generate(combinedAst, { sourceMaps: true }, sources);
|
||||||
|
|
||||||
chai.expect(generated.map).to.deep.equal({
|
chai.expect(generated.map).to.deep.equal(
|
||||||
|
{
|
||||||
version: 3,
|
version: 3,
|
||||||
sources: ["a.js", "b.js"],
|
sources: ["a.js", "b.js"],
|
||||||
mappings: "AAAA,SAASA,EAAT,CAAaC,GAAb,EAAkB;AAAEC,UAAQC,GAAR,CAAYF,GAAZ;AAAmB;;ACAvCD,GAAG,OAAH",
|
mappings:
|
||||||
names: [
|
"AAAA,SAASA,EAAT,CAAaC,GAAb,EAAkB;AAAEC,UAAQC,GAAR,CAAYF,GAAZ;AAAmB;;ACAvCD,GAAG,OAAH",
|
||||||
"hi",
|
names: ["hi", "msg", "console", "log"],
|
||||||
"msg",
|
|
||||||
"console",
|
|
||||||
"log",
|
|
||||||
],
|
|
||||||
sourcesContent: [
|
sourcesContent: [
|
||||||
"function hi (msg) { console.log(msg); }\n",
|
"function hi (msg) { console.log(msg); }\n",
|
||||||
"hi('hello');\n",
|
"hi('hello');\n",
|
||||||
],
|
],
|
||||||
}, "sourcemap was incorrectly generated");
|
},
|
||||||
|
"sourcemap was incorrectly generated",
|
||||||
|
);
|
||||||
|
|
||||||
chai.expect(generated.rawMappings).to.deep.equal([
|
chai.expect(generated.rawMappings).to.deep.equal(
|
||||||
{ name: undefined,
|
[
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 0 },
|
generated: { line: 1, column: 0 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: "hi",
|
},
|
||||||
|
{
|
||||||
|
name: "hi",
|
||||||
generated: { line: 1, column: 9 },
|
generated: { line: 1, column: 9 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 9 } },
|
original: { line: 1, column: 9 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 11 },
|
generated: { line: 1, column: 11 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: "msg",
|
},
|
||||||
|
{
|
||||||
|
name: "msg",
|
||||||
generated: { line: 1, column: 12 },
|
generated: { line: 1, column: 12 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 13 } },
|
original: { line: 1, column: 13 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 15 },
|
generated: { line: 1, column: 15 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 17 },
|
generated: { line: 1, column: 17 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 18 } },
|
original: { line: 1, column: 18 },
|
||||||
{ name: "console",
|
},
|
||||||
|
{
|
||||||
|
name: "console",
|
||||||
generated: { line: 2, column: 0 },
|
generated: { line: 2, column: 0 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 20 } },
|
original: { line: 1, column: 20 },
|
||||||
{ name: "log",
|
},
|
||||||
|
{
|
||||||
|
name: "log",
|
||||||
generated: { line: 2, column: 10 },
|
generated: { line: 2, column: 10 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 28 } },
|
original: { line: 1, column: 28 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 2, column: 13 },
|
generated: { line: 2, column: 13 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 20 } },
|
original: { line: 1, column: 20 },
|
||||||
{ name: "msg",
|
},
|
||||||
|
{
|
||||||
|
name: "msg",
|
||||||
generated: { line: 2, column: 14 },
|
generated: { line: 2, column: 14 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 32 } },
|
original: { line: 1, column: 32 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 2, column: 17 },
|
generated: { line: 2, column: 17 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 20 } },
|
original: { line: 1, column: 20 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 3, column: 0 },
|
generated: { line: 3, column: 0 },
|
||||||
source: "a.js",
|
source: "a.js",
|
||||||
original: { line: 1, column: 39 } },
|
original: { line: 1, column: 39 },
|
||||||
{ name: "hi",
|
},
|
||||||
|
{
|
||||||
|
name: "hi",
|
||||||
generated: { line: 5, column: 0 },
|
generated: { line: 5, column: 0 },
|
||||||
source: "b.js",
|
source: "b.js",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 5, column: 3 },
|
generated: { line: 5, column: 3 },
|
||||||
source: "b.js",
|
source: "b.js",
|
||||||
original: { line: 1, column: 3 } },
|
original: { line: 1, column: 3 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 5, column: 10 },
|
generated: { line: 5, column: 10 },
|
||||||
source: "b.js",
|
source: "b.js",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
], "raw mappings were incorrectly generated");
|
},
|
||||||
|
],
|
||||||
|
"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');",
|
"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.name += "2";
|
||||||
id2.loc.identiferName = "bar";
|
id2.loc.identiferName = "bar";
|
||||||
|
|
||||||
const generated = generate(ast, {
|
const generated = generate(
|
||||||
|
ast,
|
||||||
|
{
|
||||||
filename: "inline",
|
filename: "inline",
|
||||||
sourceFileName: "inline",
|
sourceFileName: "inline",
|
||||||
sourceMaps: true,
|
sourceMaps: true,
|
||||||
}, code);
|
},
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
chai.expect(generated.map).to.deep.equal({
|
chai.expect(generated.map).to.deep.equal(
|
||||||
|
{
|
||||||
version: 3,
|
version: 3,
|
||||||
sources: ["inline"],
|
sources: ["inline"],
|
||||||
names: ["foo", "bar"],
|
names: ["foo", "bar"],
|
||||||
mappings: "AAAA,SAASA,IAAT,GAAe;AAAEC;AAAM",
|
mappings: "AAAA,SAASA,IAAT,GAAe;AAAEC;AAAM",
|
||||||
sourcesContent: ["function foo() { bar; }\n"],
|
sourcesContent: ["function foo() { bar; }\n"],
|
||||||
}, "sourcemap was incorrectly generated");
|
},
|
||||||
|
"sourcemap was incorrectly generated",
|
||||||
|
);
|
||||||
|
|
||||||
chai.expect(generated.rawMappings).to.deep.equal([
|
chai.expect(generated.rawMappings).to.deep.equal(
|
||||||
{ name: undefined,
|
[
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 0 },
|
generated: { line: 1, column: 0 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: "foo",
|
},
|
||||||
|
{
|
||||||
|
name: "foo",
|
||||||
generated: { line: 1, column: 9 },
|
generated: { line: 1, column: 9 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 9 } },
|
original: { line: 1, column: 9 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 13 },
|
generated: { line: 1, column: 13 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 0 } },
|
original: { line: 1, column: 0 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 1, column: 16 },
|
generated: { line: 1, column: 16 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 15 } },
|
original: { line: 1, column: 15 },
|
||||||
{ name: "bar",
|
},
|
||||||
|
{
|
||||||
|
name: "bar",
|
||||||
generated: { line: 2, column: 0 },
|
generated: { line: 2, column: 0 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 17 } },
|
original: { line: 1, column: 17 },
|
||||||
{ name: undefined,
|
},
|
||||||
|
{
|
||||||
|
name: undefined,
|
||||||
generated: { line: 3, column: 0 },
|
generated: { line: 3, column: 0 },
|
||||||
source: "inline",
|
source: "inline",
|
||||||
original: { line: 1, column: 23 } },
|
original: { line: 1, column: 23 },
|
||||||
], "raw mappings were incorrectly generated");
|
},
|
||||||
|
],
|
||||||
|
"raw mappings were incorrectly generated",
|
||||||
|
);
|
||||||
|
|
||||||
chai.expect(generated.code).to.equal(
|
chai
|
||||||
|
.expect(generated.code)
|
||||||
|
.to.equal(
|
||||||
"function foo2() {\n bar2;\n}",
|
"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.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");
|
chai.expect(generated.map).to.be.an("object");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("programmatic generation", function() {
|
describe("programmatic generation", function() {
|
||||||
it("numeric member expression", function() {
|
it("numeric member expression", function() {
|
||||||
// Should not generate `0.foo`
|
// 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);
|
new Function(generate(mem).code);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -220,10 +288,10 @@ describe("programmatic generation", function() {
|
|||||||
t.stringLiteral("while cond"),
|
t.stringLiteral("while cond"),
|
||||||
t.ifStatement(
|
t.ifStatement(
|
||||||
t.stringLiteral("nested"),
|
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);
|
const ast = parse(generate(ifStatement).code);
|
||||||
@ -233,35 +301,22 @@ describe("programmatic generation", function() {
|
|||||||
it("prints directives in block with empty body", function() {
|
it("prints directives in block with empty body", function() {
|
||||||
const blockStatement = t.blockStatement(
|
const blockStatement = t.blockStatement(
|
||||||
[],
|
[],
|
||||||
[t.directive(t.directiveLiteral("use strict"))]
|
[t.directive(t.directiveLiteral("use strict"))],
|
||||||
);
|
);
|
||||||
|
|
||||||
const output = generate(blockStatement).code;
|
const output = generate(blockStatement).code;
|
||||||
assert.equal(output, [
|
assert.equal(output, ["{", ' "use strict";', "}"].join("\n"));
|
||||||
"{",
|
|
||||||
" \"use strict\";",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("flow object indentation", function() {
|
it("flow object indentation", function() {
|
||||||
const objectStatement = t.objectTypeAnnotation(
|
const objectStatement = t.objectTypeAnnotation(
|
||||||
[
|
[t.objectTypeProperty(t.identifier("bar"), t.stringTypeAnnotation())],
|
||||||
t.objectTypeProperty(
|
null,
|
||||||
t.identifier("bar"),
|
|
||||||
t.stringTypeAnnotation()
|
|
||||||
),
|
|
||||||
],
|
|
||||||
null,
|
null,
|
||||||
null
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const output = generate(objectStatement).code;
|
const output = generate(objectStatement).code;
|
||||||
assert.equal(output, [
|
assert.equal(output, ["{", " bar: string,", "}"].join("\n"));
|
||||||
"{",
|
|
||||||
" bar: string,",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("flow object indentation with empty leading ObjectTypeProperty", function() {
|
it("flow object indentation with empty leading ObjectTypeProperty", function() {
|
||||||
@ -273,16 +328,12 @@ describe("programmatic generation", function() {
|
|||||||
t.anyTypeAnnotation(),
|
t.anyTypeAnnotation(),
|
||||||
t.identifier("Test"),
|
t.identifier("Test"),
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const output = generate(objectStatement).code;
|
const output = generate(objectStatement).code;
|
||||||
|
|
||||||
assert.equal(output, [
|
assert.equal(output, ["{", " [key: any]: Test,", "}"].join("\n"));
|
||||||
"{",
|
|
||||||
" [key: any]: Test,",
|
|
||||||
"}",
|
|
||||||
].join("\n"));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -298,7 +349,10 @@ const suites = fixtures(`${__dirname}/fixtures`);
|
|||||||
suites.forEach(function(testSuite) {
|
suites.forEach(function(testSuite) {
|
||||||
describe("generation/" + testSuite.title, function() {
|
describe("generation/" + testSuite.title, function() {
|
||||||
testSuite.tests.forEach(function(task) {
|
testSuite.tests.forEach(function(task) {
|
||||||
it(task.title, !task.disabled && function () {
|
it(
|
||||||
|
task.title,
|
||||||
|
!task.disabled &&
|
||||||
|
function() {
|
||||||
const expect = task.expect;
|
const expect = task.expect;
|
||||||
const actual = task.actual;
|
const actual = task.actual;
|
||||||
const actualCode = actual.code;
|
const actualCode = actual.code;
|
||||||
@ -326,16 +380,21 @@ suites.forEach(function (testSuite) {
|
|||||||
const result = generate(actualAst, task.options, actualCode);
|
const result = generate(actualAst, task.options, actualCode);
|
||||||
|
|
||||||
if (
|
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
|
!process.env.CI
|
||||||
) {
|
) {
|
||||||
console.log(`New test file created: ${expect.loc}`);
|
console.log(`New test file created: ${expect.loc}`);
|
||||||
fs.writeFileSync(expect.loc, result.code);
|
fs.writeFileSync(expect.loc, result.code);
|
||||||
} else {
|
} 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 type { NodePath } from "babel-traverse";
|
||||||
import * as t from "babel-types";
|
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) {
|
for (const decoratorPath of decorators) {
|
||||||
const decorator = decoratorPath.node;
|
const decorator = decoratorPath.node;
|
||||||
const expression = decorator.expression;
|
const expression = decorator.expression;
|
||||||
@ -19,13 +21,15 @@ export default function bindifyDecorators(decorators: Array<NodePath>): Array<No
|
|||||||
ref = expression.object;
|
ref = expression.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.push(t.callExpression(
|
nodes.push(
|
||||||
|
t.callExpression(
|
||||||
t.memberExpression(
|
t.memberExpression(
|
||||||
t.memberExpression(ref, expression.property, expression.computed),
|
t.memberExpression(ref, expression.property, expression.computed),
|
||||||
t.identifier("bind")
|
t.identifier("bind"),
|
||||||
),
|
),
|
||||||
[ref]
|
[ref],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (nodes.length === 1) {
|
if (nodes.length === 1) {
|
||||||
decorator.expression = nodes[0];
|
decorator.expression = nodes[0];
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
import explode from "babel-helper-explode-assignable-expression";
|
import explode from "babel-helper-explode-assignable-expression";
|
||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
|
|
||||||
export default function (opts: {
|
export default function(opts: { build: Function, operator: string }): Object {
|
||||||
build: Function;
|
|
||||||
operator: string;
|
|
||||||
}): Object {
|
|
||||||
const visitor = {};
|
const visitor = {};
|
||||||
|
|
||||||
function isAssignment(node) {
|
function isAssignment(node) {
|
||||||
@ -25,9 +22,11 @@ export default function (opts: {
|
|||||||
const nodes = [];
|
const nodes = [];
|
||||||
const exploded = explode(expr.left, nodes, file, path.scope, true);
|
const exploded = explode(expr.left, nodes, file, path.scope, true);
|
||||||
|
|
||||||
nodes.push(t.expressionStatement(
|
nodes.push(
|
||||||
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right))
|
t.expressionStatement(
|
||||||
));
|
buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
path.replaceWithMultiple(nodes);
|
path.replaceWithMultiple(nodes);
|
||||||
};
|
};
|
||||||
@ -38,7 +37,9 @@ export default function (opts: {
|
|||||||
|
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
const exploded = explode(node.left, nodes, file, scope);
|
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);
|
path.replaceWithMultiple(nodes);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -2,19 +2,21 @@ import esutils from "esutils";
|
|||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
|
|
||||||
type ElementState = {
|
type ElementState = {
|
||||||
tagExpr: Object; // tag node
|
tagExpr: Object, // tag node
|
||||||
tagName: string; // raw string tag name
|
tagName: string, // raw string tag name
|
||||||
args: Array<Object>; // array of call arguments
|
args: Array<Object>, // array of call arguments
|
||||||
call?: Object; // optional call property that can be set to override the call expression returned
|
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
|
pre?: Function, // function called with (state: ElementState) before building attribs
|
||||||
post?: Function; // function called with (state: ElementState) after building attribs
|
post?: Function, // function called with (state: ElementState) after building attribs
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function(opts) {
|
export default function(opts) {
|
||||||
const visitor = {};
|
const visitor = {};
|
||||||
|
|
||||||
visitor.JSXNamespacedName = function(path) {
|
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 = {
|
visitor.JSXElement = {
|
||||||
@ -45,7 +47,7 @@ export default function (opts) {
|
|||||||
} else if (t.isJSXMemberExpression(node)) {
|
} else if (t.isJSXMemberExpression(node)) {
|
||||||
return t.memberExpression(
|
return t.memberExpression(
|
||||||
convertJSXIdentifier(node.object, node),
|
convertJSXIdentifier(node.object, node),
|
||||||
convertJSXIdentifier(node.property, node)
|
convertJSXIdentifier(node.property, node),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +129,6 @@ export default function (opts) {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logic for this is quite terse. It's because we need to
|
* The logic for this is quite terse. It's because we need to
|
||||||
* support spread elements. We loop over all attributes,
|
* support spread elements. We loop over all attributes,
|
||||||
@ -141,8 +142,10 @@ export default function (opts) {
|
|||||||
|
|
||||||
const useBuiltIns = file.opts.useBuiltIns || false;
|
const useBuiltIns = file.opts.useBuiltIns || false;
|
||||||
if (typeof useBuiltIns !== "boolean") {
|
if (typeof useBuiltIns !== "boolean") {
|
||||||
throw new Error("transform-react-jsx currently only accepts a boolean option for " +
|
throw new Error(
|
||||||
"useBuiltIns (defaults to false)");
|
"transform-react-jsx currently only accepts a boolean option for " +
|
||||||
|
"useBuiltIns (defaults to false)",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (attribs.length) {
|
while (attribs.length) {
|
||||||
@ -166,9 +169,9 @@ export default function (opts) {
|
|||||||
objs.unshift(t.objectExpression([]));
|
objs.unshift(t.objectExpression([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const helper = useBuiltIns ?
|
const helper = useBuiltIns
|
||||||
t.memberExpression(t.identifier("Object"), t.identifier("assign")) :
|
? t.memberExpression(t.identifier("Object"), t.identifier("assign"))
|
||||||
file.addHelper("extends");
|
: file.addHelper("extends");
|
||||||
|
|
||||||
// spread it
|
// spread it
|
||||||
attribs = t.callExpression(helper, objs);
|
attribs = t.callExpression(helper, objs);
|
||||||
|
|||||||
@ -20,13 +20,19 @@ const visitor = {
|
|||||||
|
|
||||||
export default function(path: NodePath, scope = path.scope) {
|
export default function(path: NodePath, scope = path.scope) {
|
||||||
const { node } = path;
|
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 callee = container;
|
||||||
let args = [];
|
let args = [];
|
||||||
|
|
||||||
// todo: only hoist if necessary
|
// todo: only hoist if necessary
|
||||||
hoistVariables(path, (id) => scope.push({ id }));
|
hoistVariables(path, id => scope.push({ id }));
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
foundThis: false,
|
foundThis: false,
|
||||||
|
|||||||
@ -12,7 +12,13 @@ function toKind(node: Object) {
|
|||||||
return "value";
|
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);
|
const alias = t.toKeyAlias(node);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -33,9 +39,11 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.decorators) {
|
if (node.decorators) {
|
||||||
const decorators = map.decorators = map.decorators || t.arrayExpression([]);
|
const decorators = (map.decorators =
|
||||||
|
map.decorators || t.arrayExpression([]));
|
||||||
decorators.elements = decorators.elements.concat(
|
decorators.elements = decorators.elements.concat(
|
||||||
node.decorators.map((dec) => dec.expression).reverse());
|
node.decorators.map(dec => dec.expression).reverse(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map.value || map.initializer) {
|
if (map.value || map.initializer) {
|
||||||
@ -45,14 +53,24 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
|||||||
let key, value;
|
let key, value;
|
||||||
|
|
||||||
// save the key so we can possibly do function name inferences
|
// 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);
|
key = t.toComputedKey(node, node.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.isObjectProperty(node) || t.isClassProperty(node)) {
|
if (t.isObjectProperty(node) || t.isClassProperty(node)) {
|
||||||
value = node.value;
|
value = node.value;
|
||||||
} else if (t.isObjectMethod(node) || t.isClassMethod(node)) {
|
} 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;
|
value.returnType = node.returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +80,12 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
// infer function name
|
// infer function name
|
||||||
if (scope && t.isStringLiteral(key) && (kind === "value" || kind === "initializer") &&
|
if (
|
||||||
t.isFunctionExpression(value)) {
|
scope &&
|
||||||
|
t.isStringLiteral(key) &&
|
||||||
|
(kind === "value" || kind === "initializer") &&
|
||||||
|
t.isFunctionExpression(value)
|
||||||
|
) {
|
||||||
value = nameFunction({ id: key, node: value, scope });
|
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++) {
|
for (let i = 0; i < obj.properties.length; i++) {
|
||||||
const prop = obj.properties[i];
|
const prop = obj.properties[i];
|
||||||
const val = prop.value;
|
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);
|
objExpr.elements.push(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ function getObjRef(node, nodes, file, scope) {
|
|||||||
} else if (t.isMemberExpression(node)) {
|
} else if (t.isMemberExpression(node)) {
|
||||||
ref = node.object;
|
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
|
// the object reference that we need to save is locally declared
|
||||||
// so as per the previous comment we can be 100% sure evaluating
|
// so as per the previous comment we can be 100% sure evaluating
|
||||||
// it multiple times will be safe
|
// it multiple times will be safe
|
||||||
@ -32,9 +32,7 @@ function getObjRef(node, nodes, file, scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const temp = scope.generateUidIdentifierBasedOnNode(ref);
|
const temp = scope.generateUidIdentifierBasedOnNode(ref);
|
||||||
nodes.push(t.variableDeclaration("var", [
|
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, ref)]));
|
||||||
t.variableDeclarator(temp, ref),
|
|
||||||
]));
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +42,7 @@ function getPropRef(node, nodes, file, scope) {
|
|||||||
if (t.isLiteral(key) && t.isPureish(key)) return key;
|
if (t.isLiteral(key) && t.isPureish(key)) return key;
|
||||||
|
|
||||||
const temp = scope.generateUidIdentifierBasedOnNode(prop);
|
const temp = scope.generateUidIdentifierBasedOnNode(prop);
|
||||||
nodes.push(t.variableDeclaration("var", [
|
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, prop)]));
|
||||||
t.variableDeclarator(temp, prop),
|
|
||||||
]));
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +53,8 @@ export default function (
|
|||||||
scope: Scope,
|
scope: Scope,
|
||||||
allowedSingleIdent?: boolean,
|
allowedSingleIdent?: boolean,
|
||||||
): {
|
): {
|
||||||
uid: Object;
|
uid: Object,
|
||||||
ref: Object;
|
ref: Object,
|
||||||
} {
|
} {
|
||||||
let obj;
|
let obj;
|
||||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||||
|
|||||||
@ -44,6 +44,8 @@ export default function (classPath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (memoisedExpressions) {
|
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 = {
|
type TestFile = {
|
||||||
loc: string;
|
loc: string,
|
||||||
code: string;
|
code: string,
|
||||||
filename: string;
|
filename: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Test = {
|
type Test = {
|
||||||
title: string;
|
title: string,
|
||||||
disabled: boolean;
|
disabled: boolean,
|
||||||
options: Object;
|
options: Object,
|
||||||
exec: TestFile;
|
exec: TestFile,
|
||||||
actual: TestFile;
|
actual: TestFile,
|
||||||
expected: TestFile;
|
expected: TestFile,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Suite = {
|
type Suite = {
|
||||||
options: Object;
|
options: Object,
|
||||||
tests: Array<Test>;
|
tests: Array<Test>,
|
||||||
title: string;
|
title: string,
|
||||||
filename: string;
|
filename: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function assertDirectory(loc) {
|
function assertDirectory(loc) {
|
||||||
@ -50,7 +50,9 @@ function shouldIgnore(name, blacklist?: Array<string>) {
|
|||||||
const ext = path.extname(name);
|
const ext = path.extname(name);
|
||||||
const base = path.basename(name, ext);
|
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> {
|
export default function get(entryLoc): Array<Suite> {
|
||||||
@ -133,7 +135,9 @@ export default function get(entryLoc): Array<Suite> {
|
|||||||
const minimumVersion = semver.clean(taskOpts.minNodeVersion);
|
const minimumVersion = semver.clean(taskOpts.minNodeVersion);
|
||||||
|
|
||||||
if (minimumVersion == null) {
|
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)) {
|
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
|
// need to add a wrapper since we can't change the references
|
||||||
let build = buildPropertyMethodAssignmentWrapper;
|
let build = buildPropertyMethodAssignmentWrapper;
|
||||||
if (method.generator) build = buildGeneratorPropertyMethodAssignmentWrapper;
|
if (method.generator) {
|
||||||
|
build = buildGeneratorPropertyMethodAssignmentWrapper;
|
||||||
|
}
|
||||||
const template = build({
|
const template = build({
|
||||||
FUNCTION: method,
|
FUNCTION: method,
|
||||||
FUNCTION_ID: id,
|
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
|
// has an `id` so we don't need to infer one
|
||||||
if (node.id) return;
|
if (node.id) return;
|
||||||
|
|
||||||
if ((t.isObjectProperty(parent) || t.isObjectMethod(parent, { kind: "method" })) &&
|
if (
|
||||||
(!parent.computed || t.isLiteral(parent.key))) {
|
(t.isObjectProperty(parent) ||
|
||||||
|
t.isObjectMethod(parent, { kind: "method" })) &&
|
||||||
|
(!parent.computed || t.isLiteral(parent.key))
|
||||||
|
) {
|
||||||
// { foo() {} };
|
// { foo() {} };
|
||||||
id = parent.key;
|
id = parent.key;
|
||||||
} else if (t.isVariableDeclarator(parent)) {
|
} else if (t.isVariableDeclarator(parent)) {
|
||||||
@ -139,7 +144,11 @@ export default function ({ node, parent, scope, id }) {
|
|||||||
|
|
||||||
if (t.isIdentifier(id)) {
|
if (t.isIdentifier(id)) {
|
||||||
const binding = scope.parent.getBinding(id.name);
|
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
|
// always going to reference this method
|
||||||
node.id = id;
|
node.id = id;
|
||||||
node.id[t.NOT_LOCAL_BINDING] = true;
|
node.id[t.NOT_LOCAL_BINDING] = true;
|
||||||
|
|||||||
@ -21,9 +21,11 @@ const visitor = {
|
|||||||
firstId = declar.node.id;
|
firstId = declar.node.id;
|
||||||
|
|
||||||
if (declar.node.init) {
|
if (declar.node.init) {
|
||||||
nodes.push(t.expressionStatement(
|
nodes.push(
|
||||||
t.assignmentExpression("=", declar.node.id, declar.node.init)
|
t.expressionStatement(
|
||||||
));
|
t.assignmentExpression("=", declar.node.id, declar.node.init),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name in declar.getBindingIdentifiers()) {
|
for (const name in declar.getBindingIdentifiers()) {
|
||||||
|
|||||||
@ -1,17 +1,20 @@
|
|||||||
import * as t from "babel-types";
|
import * as t from "babel-types";
|
||||||
|
|
||||||
export default function(callee, thisNode, args) {
|
export default function(callee, thisNode, args) {
|
||||||
if (args.length === 1 && t.isSpreadElement(args[0]) &&
|
if (
|
||||||
t.isIdentifier(args[0].argument, { name: "arguments" })) {
|
args.length === 1 &&
|
||||||
|
t.isSpreadElement(args[0]) &&
|
||||||
|
t.isIdentifier(args[0].argument, { name: "arguments" })
|
||||||
|
) {
|
||||||
// eg. super(...arguments);
|
// eg. super(...arguments);
|
||||||
return t.callExpression(
|
return t.callExpression(t.memberExpression(callee, t.identifier("apply")), [
|
||||||
t.memberExpression(callee, t.identifier("apply")),
|
thisNode,
|
||||||
[thisNode, args[0].argument]
|
args[0].argument,
|
||||||
);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return t.callExpression(
|
return t.callExpression(t.memberExpression(callee, t.identifier("call")), [
|
||||||
t.memberExpression(callee, t.identifier("call")),
|
thisNode,
|
||||||
[thisNode, ...args]
|
...args,
|
||||||
);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,11 @@ const forAwaitVisitor = {
|
|||||||
const callee = path.node.callee;
|
const callee = path.node.callee;
|
||||||
|
|
||||||
// if no await wrapping is being applied, unwrap the call expression
|
// 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]);
|
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)) {
|
if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) {
|
||||||
// for await (i of test), for await ({ i } of test)
|
// 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)) {
|
} else if (t.isVariableDeclaration(left)) {
|
||||||
// for await (let i of test)
|
// for await (let i of test)
|
||||||
declar = t.variableDeclaration(left.kind, [
|
declar = t.variableDeclaration(left.kind, [
|
||||||
@ -76,7 +82,9 @@ export default function (path, helpers) {
|
|||||||
|
|
||||||
traverse(template, forAwaitVisitor, null, {
|
traverse(template, forAwaitVisitor, null, {
|
||||||
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
||||||
ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
|
ITERATOR_COMPLETION: scope.generateUidIdentifier(
|
||||||
|
"iteratorNormalCompletion",
|
||||||
|
),
|
||||||
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
||||||
ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
|
ITERATOR_KEY: scope.generateUidIdentifier("iterator"),
|
||||||
GET_ITERATOR: helpers.getAsyncIterator,
|
GET_ITERATOR: helpers.getAsyncIterator,
|
||||||
|
|||||||
@ -70,7 +70,6 @@ const awaitVisitor = {
|
|||||||
path.replaceWithMultiple(build.node);
|
path.replaceWithMultiple(build.node);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function classOrObjectMethod(path: NodePath, callId: Object) {
|
function classOrObjectMethod(path: NodePath, callId: Object) {
|
||||||
@ -79,12 +78,16 @@ function classOrObjectMethod(path: NodePath, callId: Object) {
|
|||||||
|
|
||||||
node.async = false;
|
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 = [
|
body.body = [
|
||||||
t.returnStatement(t.callExpression(
|
t.returnStatement(
|
||||||
t.callExpression(callId, [container]),
|
t.callExpression(t.callExpression(callId, [container]), []),
|
||||||
[]
|
),
|
||||||
)),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Regardless of whether or not the wrapped function is a an async method
|
// 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;
|
node.generator = false;
|
||||||
|
|
||||||
// Unwrap the wrapper IIFE's environment so super and this and such still work.
|
// 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) {
|
function plainFunction(path: NodePath, callId: Object) {
|
||||||
@ -121,25 +126,29 @@ function plainFunction(path: NodePath, callId: Object) {
|
|||||||
NAME: asyncFnId || null,
|
NAME: asyncFnId || null,
|
||||||
REF: path.scope.generateUidIdentifier("ref"),
|
REF: path.scope.generateUidIdentifier("ref"),
|
||||||
FUNCTION: built,
|
FUNCTION: built,
|
||||||
PARAMS: node.params.reduce((acc, param) => {
|
PARAMS: node.params.reduce(
|
||||||
acc.done = acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
|
(acc, param) => {
|
||||||
|
acc.done =
|
||||||
|
acc.done || t.isAssignmentPattern(param) || t.isRestElement(param);
|
||||||
|
|
||||||
if (!acc.done) {
|
if (!acc.done) {
|
||||||
acc.params.push(path.scope.generateUidIdentifier("x"));
|
acc.params.push(path.scope.generateUidIdentifier("x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
params: [],
|
params: [],
|
||||||
done: false,
|
done: false,
|
||||||
}).params,
|
},
|
||||||
|
).params,
|
||||||
}).expression;
|
}).expression;
|
||||||
|
|
||||||
if (isDeclaration) {
|
if (isDeclaration) {
|
||||||
const declar = t.variableDeclaration("let", [
|
const declar = t.variableDeclaration("let", [
|
||||||
t.variableDeclarator(
|
t.variableDeclarator(
|
||||||
t.identifier(asyncFnId.name),
|
t.identifier(asyncFnId.name),
|
||||||
t.callExpression(container, [])
|
t.callExpression(container, []),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
declar._blockHoist = true;
|
declar._blockHoist = true;
|
||||||
@ -149,14 +158,12 @@ function plainFunction(path: NodePath, callId: Object) {
|
|||||||
// the identifier into an expressionStatement
|
// the identifier into an expressionStatement
|
||||||
path.parentPath.insertBefore(declar);
|
path.parentPath.insertBefore(declar);
|
||||||
path.parentPath.replaceWith(
|
path.parentPath.replaceWith(
|
||||||
t.exportNamedDeclaration(null,
|
t.exportNamedDeclaration(null, [
|
||||||
[
|
|
||||||
t.exportSpecifier(
|
t.exportSpecifier(
|
||||||
t.identifier(asyncFnId.name),
|
t.identifier(asyncFnId.name),
|
||||||
t.identifier("default")
|
t.identifier("default"),
|
||||||
),
|
),
|
||||||
]
|
]),
|
||||||
)
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,16 +30,19 @@ function isMemberExpressionSuper(node) {
|
|||||||
* CLASS.prototype.__proto__ || Object.getPrototypeOf(CLASS.prototype)
|
* CLASS.prototype.__proto__ || Object.getPrototypeOf(CLASS.prototype)
|
||||||
*/
|
*/
|
||||||
function getPrototypeOfExpression(objectRef, isStatic) {
|
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(
|
return t.logicalExpression(
|
||||||
"||",
|
"||",
|
||||||
t.memberExpression(targetRef, t.identifier("__proto__")),
|
t.memberExpression(targetRef, t.identifier("__proto__")),
|
||||||
t.callExpression(
|
t.callExpression(
|
||||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
t.memberExpression(
|
||||||
[
|
t.identifier("Object"),
|
||||||
targetRef,
|
t.identifier("getPrototypeOf"),
|
||||||
]
|
),
|
||||||
|
[targetRef],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -119,14 +122,14 @@ export default class ReplaceSupers {
|
|||||||
scope: Scope;
|
scope: Scope;
|
||||||
file;
|
file;
|
||||||
opts: {
|
opts: {
|
||||||
forceSuperMemoisation: boolean;
|
forceSuperMemoisation: boolean,
|
||||||
getObjetRef: Function;
|
getObjetRef: Function,
|
||||||
methodPath: NodePath;
|
methodPath: NodePath,
|
||||||
methodNode: Object;
|
methodNode: Object,
|
||||||
superRef: Object;
|
superRef: Object,
|
||||||
isStatic: boolean;
|
isStatic: boolean,
|
||||||
isLoose: boolean;
|
isLoose: boolean,
|
||||||
file: any;
|
file: any,
|
||||||
};
|
};
|
||||||
|
|
||||||
getObjectRef() {
|
getObjectRef() {
|
||||||
@ -143,16 +146,17 @@ export default class ReplaceSupers {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setSuperProperty(property: Object, value: Object, isComputed: boolean): Object {
|
setSuperProperty(
|
||||||
return t.callExpression(
|
property: Object,
|
||||||
this.file.addHelper("set"),
|
value: Object,
|
||||||
[
|
isComputed: boolean,
|
||||||
|
): Object {
|
||||||
|
return t.callExpression(this.file.addHelper("set"), [
|
||||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
||||||
isComputed ? property : t.stringLiteral(property.name),
|
isComputed ? property : t.stringLiteral(property.name),
|
||||||
value,
|
value,
|
||||||
t.thisExpression(),
|
t.thisExpression(),
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,14 +169,11 @@ export default class ReplaceSupers {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
getSuperProperty(property: Object, isComputed: boolean): Object {
|
getSuperProperty(property: Object, isComputed: boolean): Object {
|
||||||
return t.callExpression(
|
return t.callExpression(this.file.addHelper("get"), [
|
||||||
this.file.addHelper("get"),
|
|
||||||
[
|
|
||||||
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
getPrototypeOfExpression(this.getObjectRef(), this.isStatic),
|
||||||
isComputed ? property : t.stringLiteral(property.name),
|
isComputed ? property : t.stringLiteral(property.name),
|
||||||
t.thisExpression(),
|
t.thisExpression(),
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
replace() {
|
replace() {
|
||||||
@ -214,16 +215,23 @@ export default class ReplaceSupers {
|
|||||||
specHandleAssignmentExpression(ref, path, node) {
|
specHandleAssignmentExpression(ref, path, node) {
|
||||||
if (node.operator === "=") {
|
if (node.operator === "=") {
|
||||||
// super.name = "val"; -> _set(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
// 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 {
|
} else {
|
||||||
// super.age += 2; -> let _ref = super.age; super.age = _ref + 2;
|
// super.age += 2; -> let _ref = super.age; super.age = _ref + 2;
|
||||||
ref = ref || path.scope.generateUidIdentifier("ref");
|
ref = ref || path.scope.generateUidIdentifier("ref");
|
||||||
return [
|
return [
|
||||||
t.variableDeclaration("var", [
|
t.variableDeclaration("var", [t.variableDeclarator(ref, node.left)]),
|
||||||
t.variableDeclarator(ref, node.left),
|
t.expressionStatement(
|
||||||
]),
|
t.assignmentExpression(
|
||||||
t.expressionStatement(t.assignmentExpression("=", node.left,
|
"=",
|
||||||
t.binaryExpression(node.operator.slice(0, -1), ref, node.right))),
|
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);
|
// _get(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
||||||
property = node.property;
|
property = node.property;
|
||||||
computed = node.computed;
|
computed = node.computed;
|
||||||
} else if (t.isUpdateExpression(node) && isMemberExpressionSuper(node.argument)) {
|
} else if (
|
||||||
const binary = t.assignmentExpression(node.operator[0] + "=", node.argument, t.numericLiteral(1));
|
t.isUpdateExpression(node) &&
|
||||||
|
isMemberExpressionSuper(node.argument)
|
||||||
|
) {
|
||||||
|
const binary = t.assignmentExpression(
|
||||||
|
node.operator[0] + "=",
|
||||||
|
node.argument,
|
||||||
|
t.numericLiteral(1),
|
||||||
|
);
|
||||||
if (node.prefix) {
|
if (node.prefix) {
|
||||||
// ++super.foo;
|
// ++super.foo;
|
||||||
// to
|
// to
|
||||||
@ -270,9 +285,14 @@ export default class ReplaceSupers {
|
|||||||
// to
|
// to
|
||||||
// let _ref = super.foo; super.foo = _ref + 1;
|
// let _ref = super.foo; super.foo = _ref + 1;
|
||||||
const ref = path.scope.generateUidIdentifier("ref");
|
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);
|
return this.specHandleAssignmentExpression(null, path, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,13 +4,9 @@ export function assertNoOwnProperties(obj) {
|
|||||||
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
|
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertHasOwnProperty() {
|
export function assertHasOwnProperty() {}
|
||||||
|
|
||||||
}
|
export function assertLacksOwnProperty() {}
|
||||||
|
|
||||||
export function assertLacksOwnProperty() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function multiline(arr) {
|
export function multiline(arr) {
|
||||||
return arr.join("\n");
|
return arr.join("\n");
|
||||||
|
|||||||
@ -38,7 +38,9 @@ runCodeInTestContext(buildExternalHelpers());
|
|||||||
* This allows us to run our unittests
|
* This allows us to run our unittests
|
||||||
*/
|
*/
|
||||||
function runModuleInTestContext(id: string, relativeFilename: string) {
|
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
|
// Expose Node-internal modules if the tests want them. Note, this will not execute inside
|
||||||
// the context's global scope.
|
// the context's global scope.
|
||||||
@ -46,20 +48,22 @@ function runModuleInTestContext(id: string, relativeFilename: string) {
|
|||||||
|
|
||||||
if (moduleCache[filename]) return moduleCache[filename].exports;
|
if (moduleCache[filename]) return moduleCache[filename].exports;
|
||||||
|
|
||||||
const module = moduleCache[filename] = {
|
const module = (moduleCache[filename] = {
|
||||||
id: filename,
|
id: filename,
|
||||||
exports: {},
|
exports: {},
|
||||||
};
|
});
|
||||||
const dirname = path.dirname(filename);
|
const dirname = path.dirname(filename);
|
||||||
const req = (id) => runModuleInTestContext(id, filename);
|
const req = id => runModuleInTestContext(id, filename);
|
||||||
|
|
||||||
const src = fs.readFileSync(filename, "utf8");
|
const src = fs.readFileSync(filename, "utf8");
|
||||||
const code = `(function (exports, require, module, __filename, __dirname) {${src}\n});`;
|
const code = `(function (exports, require, module, __filename, __dirname) {${src}\n});`;
|
||||||
|
|
||||||
vm.runInContext(code, testContext, {
|
vm
|
||||||
|
.runInContext(code, testContext, {
|
||||||
filename,
|
filename,
|
||||||
displayErrors: true,
|
displayErrors: true,
|
||||||
}).call(module.exports, module.exports, req, module, filename, dirname);
|
})
|
||||||
|
.call(module.exports, module.exports, req, module, filename, dirname);
|
||||||
|
|
||||||
return module.exports;
|
return module.exports;
|
||||||
}
|
}
|
||||||
@ -69,10 +73,13 @@ function runModuleInTestContext(id: string, relativeFilename: string) {
|
|||||||
*
|
*
|
||||||
* Exposed for unit tests, not for use as an API.
|
* 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 filename = opts.filename || null;
|
||||||
const dirname = filename ? path.dirname(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 = {
|
const module = {
|
||||||
id: filename,
|
id: filename,
|
||||||
@ -95,16 +102,16 @@ function wrapPackagesArray(type, names, optionsDir) {
|
|||||||
|
|
||||||
// relative path (outside of monorepo)
|
// relative path (outside of monorepo)
|
||||||
if (val[0][0] === ".") {
|
if (val[0][0] === ".") {
|
||||||
|
|
||||||
if (!optionsDir) {
|
if (!optionsDir) {
|
||||||
throw new Error("Please provide an options.json in test dir when using a " +
|
throw new Error(
|
||||||
"relative plugin path.");
|
"Please provide an options.json in test dir when using a " +
|
||||||
|
"relative plugin path.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
val[0] = path.resolve(optionsDir, val[0]);
|
val[0] = path.resolve(optionsDir, val[0]);
|
||||||
}
|
} else {
|
||||||
// check node_modules/babel-x-y
|
// check node_modules/babel-x-y
|
||||||
else {
|
|
||||||
val[0] = __dirname + "/../../babel-" + type + "-" + val[0];
|
val[0] = __dirname + "/../../babel-" + type + "-" + val[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,15 +127,25 @@ function run(task) {
|
|||||||
const optionsDir = task.optionsDir;
|
const optionsDir = task.optionsDir;
|
||||||
|
|
||||||
function getOpts(self) {
|
function getOpts(self) {
|
||||||
const newOpts = merge({
|
const newOpts = merge(
|
||||||
|
{
|
||||||
filename: self.loc,
|
filename: self.loc,
|
||||||
}, opts);
|
},
|
||||||
|
opts,
|
||||||
|
);
|
||||||
|
|
||||||
newOpts.plugins = wrapPackagesArray("plugin", newOpts.plugins, optionsDir);
|
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) {
|
if (val.length > 2) {
|
||||||
throw new Error("Unexpected extra options " + JSON.stringify(val.slice(2)) +
|
throw new Error(
|
||||||
" passed to preset.");
|
"Unexpected extra options " +
|
||||||
|
JSON.stringify(val.slice(2)) +
|
||||||
|
" passed to preset.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -160,14 +177,19 @@ function run(task) {
|
|||||||
if (!execCode || actualCode) {
|
if (!execCode || actualCode) {
|
||||||
result = babel.transform(actualCode, getOpts(actual));
|
result = babel.transform(actualCode, getOpts(actual));
|
||||||
if (
|
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
|
!process.env.CI
|
||||||
) {
|
) {
|
||||||
console.log(`New test file created: ${expect.loc}`);
|
console.log(`New test file created: ${expect.loc}`);
|
||||||
fs.writeFileSync(expect.loc, result.code);
|
fs.writeFileSync(expect.loc, result.code);
|
||||||
} else {
|
} else {
|
||||||
actualCode = result.code.trim();
|
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 actual = mapping.original;
|
||||||
|
|
||||||
const expect = consumer.originalPositionFor(mapping.generated);
|
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() {
|
describe(name + "/" + testSuite.title, function() {
|
||||||
for (const task of testSuite.tests) {
|
for (const task of testSuite.tests) {
|
||||||
if (includes(suiteOpts.ignoreTasks, task.title) ||
|
if (
|
||||||
includes(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)) continue;
|
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() {
|
function runTask() {
|
||||||
run(task);
|
run(task);
|
||||||
}
|
}
|
||||||
@ -233,7 +264,9 @@ export default function (
|
|||||||
delete task.options.throws;
|
delete task.options.throws;
|
||||||
|
|
||||||
assert.throws(runTask, function(err) {
|
assert.throws(runTask, function(err) {
|
||||||
return throwMsg === true || err.message.indexOf(throwMsg) >= 0;
|
return (
|
||||||
|
throwMsg === true || err.message.indexOf(throwMsg) >= 0
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (task.exec.code) {
|
if (task.exec.code) {
|
||||||
@ -245,7 +278,8 @@ export default function (
|
|||||||
runTask();
|
runTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -359,7 +359,6 @@ helpers.get = template(`
|
|||||||
});
|
});
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
||||||
helpers.inherits = template(`
|
helpers.inherits = template(`
|
||||||
(function (subClass, superClass) {
|
(function (subClass, superClass) {
|
||||||
if (typeof superClass !== "function" && superClass !== null) {
|
if (typeof superClass !== "function" && superClass !== null) {
|
||||||
@ -395,7 +394,6 @@ helpers.instanceof = template(`
|
|||||||
});
|
});
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
||||||
helpers.interopRequireDefault = template(`
|
helpers.interopRequireDefault = template(`
|
||||||
(function (obj) {
|
(function (obj) {
|
||||||
return obj && obj.__esModule ? obj : { default: obj };
|
return obj && obj.__esModule ? obj : { default: obj };
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export function get(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const list = Object.keys(helpers)
|
export const list = Object.keys(helpers)
|
||||||
.map((name) => name.replace(/^_/, ""))
|
.map(name => name.replace(/^_/, ""))
|
||||||
.filter((name) => name !== "__esModule");
|
.filter(name => name !== "__esModule");
|
||||||
|
|
||||||
export default get;
|
export default get;
|
||||||
|
|||||||
@ -8,38 +8,55 @@ import * as util from "util";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const MESSAGES = {
|
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",
|
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",
|
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
||||||
settersNoRest: "Setters aren't allowed to have a rest",
|
settersNoRest: "Setters aren't allowed to have a rest",
|
||||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||||
expectedMemberExpressionOrIdentifier: "Expected type MemberExpression or Identifier",
|
expectedMemberExpressionOrIdentifier:
|
||||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
"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",
|
readOnly: "$1 is read-only",
|
||||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||||
didYouMean: "Did you mean $1?",
|
didYouMean: "Did you mean $1?",
|
||||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
codeGeneratorDeopt:
|
||||||
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
"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",
|
unsupportedOutputType: "Unsupported output type $1",
|
||||||
illegalMethodName: "Illegal method name $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",
|
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",
|
undeclaredVariable: "Reference to undeclared variable $1",
|
||||||
undeclaredVariableType: "Referencing a type alias outside of a type annotation",
|
undeclaredVariableType:
|
||||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
"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.",
|
traverseNeedsParent:
|
||||||
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
"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.",
|
||||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
traverseVerifyRootFunction:
|
||||||
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
|
"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",
|
pluginNotObject:
|
||||||
pluginNotFunction: "Plugin $2 specified in $1 was expected to return a function but returned $3",
|
"Plugin $2 specified in $1 was expected to return an object when invoked but returned $3",
|
||||||
pluginUnknown: "Unknown plugin $1 specified in $2 at $3, attempted to resolve relative to $4",
|
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",
|
pluginInvalidProperty: "Plugin $1 provided an invalid property of $2",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,10 @@ export default function ({ types: t }) {
|
|||||||
const callee = state.addHelper("asyncGeneratorDelegate");
|
const callee = state.addHelper("asyncGeneratorDelegate");
|
||||||
node.argument = t.callExpression(callee, [
|
node.argument = t.callExpression(callee, [
|
||||||
t.callExpression(state.addHelper("asyncIterator"), [node.argument]),
|
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, {
|
remapAsyncToGenerator(path, state.file, {
|
||||||
wrapAsync: t.memberExpression(
|
wrapAsync: t.memberExpression(
|
||||||
state.addHelper("asyncGenerator"), t.identifier("wrap")),
|
state.addHelper("asyncGenerator"),
|
||||||
|
t.identifier("wrap"),
|
||||||
|
),
|
||||||
wrapAwait: t.memberExpression(
|
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,
|
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"),
|
VALUE: value ? value : t.identifier("undefined"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const buildClassPropertyNonSpec = (ref, { key, value, computed }) => t.expressionStatement(
|
const buildClassPropertyNonSpec = (ref, { key, value, computed }) =>
|
||||||
t.assignmentExpression("=", t.memberExpression(ref, key, computed || t.isLiteral(key)), value)
|
t.expressionStatement(
|
||||||
|
t.assignmentExpression(
|
||||||
|
"=",
|
||||||
|
t.memberExpression(ref, key, computed || t.isLiteral(key)),
|
||||||
|
value,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -44,8 +50,9 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
visitor: {
|
visitor: {
|
||||||
Class(path, state) {
|
Class(path, state) {
|
||||||
const buildClassProperty = state.opts.spec ? buildClassPropertySpec :
|
const buildClassProperty = state.opts.spec
|
||||||
buildClassPropertyNonSpec;
|
? buildClassPropertySpec
|
||||||
|
: buildClassPropertyNonSpec;
|
||||||
const isDerived = !!path.node.superClass;
|
const isDerived = !!path.node.superClass;
|
||||||
let constructor;
|
let constructor;
|
||||||
const props = [];
|
const props = [];
|
||||||
@ -67,7 +74,8 @@ export default function ({ types: t }) {
|
|||||||
if (path.isClassExpression() || !path.node.id) {
|
if (path.isClassExpression() || !path.node.id) {
|
||||||
nameFunction(path);
|
nameFunction(path);
|
||||||
ref = path.scope.generateUidIdentifier("class");
|
ref = path.scope.generateUidIdentifier("class");
|
||||||
} else { // path.isClassDeclaration() && path.node.id
|
} else {
|
||||||
|
// path.isClassDeclaration() && path.node.id
|
||||||
ref = path.node.id;
|
ref = path.node.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,17 +101,20 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
if (instanceBody.length) {
|
if (instanceBody.length) {
|
||||||
if (!constructor) {
|
if (!constructor) {
|
||||||
const newConstructor = t.classMethod("constructor", t.identifier("constructor"), [],
|
const newConstructor = t.classMethod(
|
||||||
t.blockStatement([]));
|
"constructor",
|
||||||
|
t.identifier("constructor"),
|
||||||
|
[],
|
||||||
|
t.blockStatement([]),
|
||||||
|
);
|
||||||
if (isDerived) {
|
if (isDerived) {
|
||||||
newConstructor.params = [t.restElement(t.identifier("args"))];
|
newConstructor.params = [t.restElement(t.identifier("args"))];
|
||||||
newConstructor.body.body.push(
|
newConstructor.body.body.push(
|
||||||
t.returnStatement(
|
t.returnStatement(
|
||||||
t.callExpression(
|
t.callExpression(t.super(), [
|
||||||
t.super(),
|
t.spreadElement(t.identifier("args")),
|
||||||
[t.spreadElement(t.identifier("args"))]
|
]),
|
||||||
)
|
),
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
[constructor] = body.unshiftContainer("body", newConstructor);
|
[constructor] = body.unshiftContainer("body", newConstructor);
|
||||||
@ -120,19 +131,29 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (collisionState.collision) {
|
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(
|
t.variableDeclarator(
|
||||||
initialisePropsRef,
|
initialisePropsRef,
|
||||||
t.functionExpression(null, [], t.blockStatement(instanceBody))
|
t.functionExpression(
|
||||||
|
null,
|
||||||
|
[],
|
||||||
|
t.blockStatement(instanceBody),
|
||||||
),
|
),
|
||||||
]));
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
instanceBody = [
|
instanceBody = [
|
||||||
t.expressionStatement(
|
t.expressionStatement(
|
||||||
t.callExpression(t.memberExpression(initialisePropsRef, t.identifier("call")), [
|
t.callExpression(
|
||||||
t.thisExpression()])
|
t.memberExpression(initialisePropsRef, t.identifier("call")),
|
||||||
|
[t.thisExpression()],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -159,7 +180,8 @@ export default function ({ types: t }) {
|
|||||||
if (path.isClassExpression()) {
|
if (path.isClassExpression()) {
|
||||||
path.scope.push({ id: ref });
|
path.scope.push({ id: ref });
|
||||||
path.replaceWith(t.assignmentExpression("=", ref, path.node));
|
path.replaceWith(t.assignmentExpression("=", ref, path.node));
|
||||||
} else { // path.isClassDeclaration()
|
} else {
|
||||||
|
// path.isClassDeclaration()
|
||||||
if (!path.node.id) {
|
if (!path.node.id) {
|
||||||
path.node.id = ref;
|
path.node.id = ref;
|
||||||
}
|
}
|
||||||
@ -177,7 +199,7 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
const body = classExp.get("body");
|
const body = classExp.get("body");
|
||||||
const members = body.get("body");
|
const members = body.get("body");
|
||||||
if (members.some((member) => member.isClassProperty())) {
|
if (members.some(member => member.isClassProperty())) {
|
||||||
path.ensureBlock();
|
path.ensureBlock();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -15,7 +15,6 @@ const buildGetDescriptor = template(`
|
|||||||
Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
|
Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
||||||
const buildGetObjectInitializer = template(`
|
const buildGetObjectInitializer = template(`
|
||||||
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
|
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
@ -88,7 +87,9 @@ export default function({ types: t }) {
|
|||||||
*/
|
*/
|
||||||
function ensureApplyDecoratedDescriptorHelper(path, state) {
|
function ensureApplyDecoratedDescriptorHelper(path, state) {
|
||||||
if (!state.applyDecoratedDescriptor) {
|
if (!state.applyDecoratedDescriptor) {
|
||||||
state.applyDecoratedDescriptor = path.scope.generateUidIdentifier("applyDecoratedDescriptor");
|
state.applyDecoratedDescriptor = path.scope.generateUidIdentifier(
|
||||||
|
"applyDecoratedDescriptor",
|
||||||
|
);
|
||||||
const helper = buildApplyDecoratedDescriptor({
|
const helper = buildApplyDecoratedDescriptor({
|
||||||
NAME: state.applyDecoratedDescriptor,
|
NAME: state.applyDecoratedDescriptor,
|
||||||
});
|
});
|
||||||
@ -103,7 +104,9 @@ export default function({ types: t }) {
|
|||||||
*/
|
*/
|
||||||
function ensureInitializerDefineProp(path, state) {
|
function ensureInitializerDefineProp(path, state) {
|
||||||
if (!state.initializerDefineProp) {
|
if (!state.initializerDefineProp) {
|
||||||
state.initializerDefineProp = path.scope.generateUidIdentifier("initDefineProp");
|
state.initializerDefineProp = path.scope.generateUidIdentifier(
|
||||||
|
"initDefineProp",
|
||||||
|
);
|
||||||
const helper = buildInitializerDefineProperty({
|
const helper = buildInitializerDefineProperty({
|
||||||
NAME: state.initializerDefineProp,
|
NAME: state.initializerDefineProp,
|
||||||
});
|
});
|
||||||
@ -119,7 +122,9 @@ export default function({ types: t }) {
|
|||||||
*/
|
*/
|
||||||
function ensureInitializerWarning(path, state) {
|
function ensureInitializerWarning(path, state) {
|
||||||
if (!state.initializerWarningHelper) {
|
if (!state.initializerWarningHelper) {
|
||||||
state.initializerWarningHelper = path.scope.generateUidIdentifier("initializerWarningHelper");
|
state.initializerWarningHelper = path.scope.generateUidIdentifier(
|
||||||
|
"initializerWarningHelper",
|
||||||
|
);
|
||||||
const helper = buildInitializerWarningHelper({
|
const helper = buildInitializerWarningHelper({
|
||||||
NAME: state.initializerWarningHelper,
|
NAME: state.initializerWarningHelper,
|
||||||
});
|
});
|
||||||
@ -135,20 +140,29 @@ export default function({ types: t }) {
|
|||||||
*/
|
*/
|
||||||
function applyEnsureOrdering(path) {
|
function applyEnsureOrdering(path) {
|
||||||
// TODO: This should probably also hoist computed properties.
|
// TODO: This should probably also hoist computed properties.
|
||||||
const decorators = (
|
const decorators = (path.isClass()
|
||||||
path.isClass()
|
|
||||||
? [path].concat(path.get("body.body"))
|
? [path].concat(path.get("body.body"))
|
||||||
: path.get("properties")
|
: path.get("properties")).reduce(
|
||||||
).reduce((acc, prop) => acc.concat(prop.node.decorators || []), []);
|
(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;
|
if (identDecorators.length === 0) return;
|
||||||
|
|
||||||
return t.sequenceExpression(identDecorators.map((decorator) => {
|
return t.sequenceExpression(
|
||||||
|
identDecorators
|
||||||
|
.map(decorator => {
|
||||||
const expression = decorator.expression;
|
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);
|
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");
|
const name = classPath.scope.generateDeclaredUidIdentifier("class");
|
||||||
|
|
||||||
return decorators
|
return decorators
|
||||||
.map((dec) => dec.expression)
|
.map(dec => dec.expression)
|
||||||
.reverse()
|
.reverse()
|
||||||
.reduce(function(acc, decorator) {
|
.reduce(function(acc, decorator) {
|
||||||
return buildClassDecorator({
|
return buildClassDecorator({
|
||||||
@ -207,7 +221,9 @@ export default function({ types: t }) {
|
|||||||
* A helper to pull out property decorators into a sequence expression.
|
* A helper to pull out property decorators into a sequence expression.
|
||||||
*/
|
*/
|
||||||
function applyTargetDecorators(path, state, decoratedProps) {
|
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 exprs = decoratedProps.reduce(function(acc, node) {
|
||||||
const decorators = node.decorators || [];
|
const decorators = node.decorators || [];
|
||||||
@ -216,36 +232,58 @@ export default function({ types: t }) {
|
|||||||
if (decorators.length === 0) return acc;
|
if (decorators.length === 0) return acc;
|
||||||
|
|
||||||
if (node.computed) {
|
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,
|
CLASS_REF: name,
|
||||||
}).expression : name;
|
}).expression
|
||||||
|
: name;
|
||||||
|
|
||||||
if (t.isClassProperty(node, { static: false })) {
|
if (t.isClassProperty(node, { static: false })) {
|
||||||
const descriptor = path.scope.generateDeclaredUidIdentifier("descriptor");
|
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 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([
|
acc = acc.concat([
|
||||||
t.assignmentExpression(
|
t.assignmentExpression(
|
||||||
"=", descriptor, t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
|
"=",
|
||||||
|
descriptor,
|
||||||
|
t.callExpression(
|
||||||
|
ensureApplyDecoratedDescriptorHelper(path, state),
|
||||||
|
[
|
||||||
target,
|
target,
|
||||||
property,
|
property,
|
||||||
t.arrayExpression(decorators.map((dec) => dec.expression)),
|
t.arrayExpression(decorators.map(dec => dec.expression)),
|
||||||
t.objectExpression([
|
t.objectExpression([
|
||||||
t.objectProperty(t.identifier("enumerable"), t.booleanLiteral(true)),
|
t.objectProperty(
|
||||||
|
t.identifier("enumerable"),
|
||||||
|
t.booleanLiteral(true),
|
||||||
|
),
|
||||||
t.objectProperty(t.identifier("initializer"), initializer),
|
t.objectProperty(t.identifier("initializer"), initializer),
|
||||||
]),
|
]),
|
||||||
])
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
@ -253,21 +291,20 @@ export default function({ types: t }) {
|
|||||||
t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
|
t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
|
||||||
target,
|
target,
|
||||||
property,
|
property,
|
||||||
t.arrayExpression(decorators.map((dec) => dec.expression)),
|
t.arrayExpression(decorators.map(dec => dec.expression)),
|
||||||
(
|
|
||||||
t.isObjectProperty(node) ||
|
t.isObjectProperty(node) ||
|
||||||
t.isClassProperty(node, { static: true })) ?
|
t.isClassProperty(node, { static: true })
|
||||||
buildGetObjectInitializer({
|
? buildGetObjectInitializer({
|
||||||
TEMP: path.scope.generateDeclaredUidIdentifier("init"),
|
TEMP: path.scope.generateDeclaredUidIdentifier("init"),
|
||||||
TARGET: target,
|
TARGET: target,
|
||||||
PROPERTY: property,
|
PROPERTY: property,
|
||||||
}).expression : buildGetDescriptor({
|
}).expression
|
||||||
|
: buildGetDescriptor({
|
||||||
TARGET: target,
|
TARGET: target,
|
||||||
PROPERTY: property,
|
PROPERTY: property,
|
||||||
}
|
}).expression,
|
||||||
).expression,
|
|
||||||
target,
|
target,
|
||||||
])
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,35 +326,42 @@ export default function({ types: t }) {
|
|||||||
if (!path.get("declaration").isClassDeclaration()) return;
|
if (!path.get("declaration").isClassDeclaration()) return;
|
||||||
|
|
||||||
const { node } = path;
|
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;
|
node.declaration.id = ref;
|
||||||
|
|
||||||
// Split the class declaration and the export into two separate statements.
|
// Split the class declaration and the export into two separate statements.
|
||||||
path.replaceWith(node.declaration);
|
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) {
|
ClassDeclaration(path) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
|
|
||||||
const ref = node.id || path.scope.generateUidIdentifier("class");
|
const ref = node.id || path.scope.generateUidIdentifier("class");
|
||||||
|
|
||||||
path.replaceWith(t.variableDeclaration("let", [
|
path.replaceWith(
|
||||||
|
t.variableDeclaration("let", [
|
||||||
t.variableDeclarator(ref, t.toExpression(node)),
|
t.variableDeclarator(ref, t.toExpression(node)),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
ClassExpression(path, state) {
|
ClassExpression(path, state) {
|
||||||
// Create a replacement for the class node if there is one. We do one pass to replace classes with
|
// 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.
|
// class decorators, and a second pass to process method decorators.
|
||||||
const decoratedClass = (
|
const decoratedClass =
|
||||||
applyEnsureOrdering(path) ||
|
applyEnsureOrdering(path) ||
|
||||||
applyClassDecorators(path, state) ||
|
applyClassDecorators(path, state) ||
|
||||||
applyMethodDecorators(path, state)
|
applyMethodDecorators(path, state);
|
||||||
);
|
|
||||||
|
|
||||||
if (decoratedClass) path.replaceWith(decoratedClass);
|
if (decoratedClass) path.replaceWith(decoratedClass);
|
||||||
},
|
},
|
||||||
ObjectExpression(path, state) {
|
ObjectExpression(path, state) {
|
||||||
const decoratedObject = applyEnsureOrdering(path) || applyObjectDecorators(path, state);
|
const decoratedObject =
|
||||||
|
applyEnsureOrdering(path) || applyObjectDecorators(path, state);
|
||||||
|
|
||||||
if (decoratedObject) path.replaceWith(decoratedObject);
|
if (decoratedObject) path.replaceWith(decoratedObject);
|
||||||
},
|
},
|
||||||
@ -328,14 +372,22 @@ export default function({ types: t }) {
|
|||||||
if (!path.get("left").isMemberExpression()) return;
|
if (!path.get("left").isMemberExpression()) return;
|
||||||
if (!path.get("left.property").isIdentifier()) return;
|
if (!path.get("left.property").isIdentifier()) return;
|
||||||
if (!path.get("right").isCallExpression()) 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,
|
path.get("left.object").node,
|
||||||
t.stringLiteral(path.get("left.property").node.name),
|
t.stringLiteral(path.get("left.property").node.name),
|
||||||
path.get("right.arguments")[0].node,
|
path.get("right.arguments")[0].node,
|
||||||
path.get("right.arguments")[1].node,
|
path.get("right.arguments")[1].node,
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,7 +5,10 @@ import type NodePath from "babel-traverse";
|
|||||||
export default function() {
|
export default function() {
|
||||||
return {
|
return {
|
||||||
visitor: {
|
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
|
// In some conversion cases, it may have already been converted to a function while this callback
|
||||||
// was queued up.
|
// was queued up.
|
||||||
if (!path.isArrowFunctionExpression()) return;
|
if (!path.isArrowFunctionExpression()) return;
|
||||||
|
|||||||
@ -24,7 +24,10 @@ export default function ({ types: t }) {
|
|||||||
visitor: {
|
visitor: {
|
||||||
BlockStatement(path) {
|
BlockStatement(path) {
|
||||||
const { node, parent } = path;
|
const { node, parent } = path;
|
||||||
if (t.isFunction(parent, { body: node }) || t.isExportDeclaration(parent)) {
|
if (
|
||||||
|
t.isFunction(parent, { body: node }) ||
|
||||||
|
t.isExportDeclaration(parent)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,20 +44,38 @@ export default function () {
|
|||||||
Loop(path, file) {
|
Loop(path, file) {
|
||||||
const { node, parent, scope } = path;
|
const { node, parent, scope } = path;
|
||||||
t.ensureBlock(node);
|
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();
|
const replace = blockScoping.run();
|
||||||
if (replace) path.replaceWith(replace);
|
if (replace) path.replaceWith(replace);
|
||||||
},
|
},
|
||||||
|
|
||||||
CatchClause(path, file) {
|
CatchClause(path, file) {
|
||||||
const { parent, scope } = path;
|
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();
|
blockScoping.run();
|
||||||
},
|
},
|
||||||
|
|
||||||
"BlockStatement|SwitchStatement|Program"(path, file) {
|
"BlockStatement|SwitchStatement|Program"(path, file) {
|
||||||
if (!ignoreBlock(path)) {
|
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();
|
blockScoping.run();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -80,7 +98,13 @@ function isBlockScoped(node) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertBlockScopedToVar(path, node, parent, scope, moveBindingsToParent = false) {
|
function convertBlockScopedToVar(
|
||||||
|
path,
|
||||||
|
node,
|
||||||
|
parent,
|
||||||
|
scope,
|
||||||
|
moveBindingsToParent = false,
|
||||||
|
) {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
node = path.node;
|
node = path.node;
|
||||||
}
|
}
|
||||||
@ -111,7 +135,8 @@ function isVar(node) {
|
|||||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isBlockScoped(node);
|
return t.isVariableDeclaration(node, { kind: "var" }) && !isBlockScoped(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
const letReferenceBlockVisitor = traverse.visitors.merge([{
|
const letReferenceBlockVisitor = traverse.visitors.merge([
|
||||||
|
{
|
||||||
Loop: {
|
Loop: {
|
||||||
enter(path, state) {
|
enter(path, state) {
|
||||||
state.loopDepth++;
|
state.loopDepth++;
|
||||||
@ -129,9 +154,12 @@ const letReferenceBlockVisitor = traverse.visitors.merge([{
|
|||||||
}
|
}
|
||||||
return path.skip();
|
return path.skip();
|
||||||
},
|
},
|
||||||
}, tdzVisitor]);
|
},
|
||||||
|
tdzVisitor,
|
||||||
|
]);
|
||||||
|
|
||||||
const letReferenceFunctionVisitor = traverse.visitors.merge([{
|
const letReferenceFunctionVisitor = traverse.visitors.merge([
|
||||||
|
{
|
||||||
ReferencedIdentifier(path, state) {
|
ReferencedIdentifier(path, state) {
|
||||||
const ref = state.letReferences[path.node.name];
|
const ref = state.letReferences[path.node.name];
|
||||||
|
|
||||||
@ -145,7 +173,9 @@ const letReferenceFunctionVisitor = traverse.visitors.merge([{
|
|||||||
|
|
||||||
state.closurify = true;
|
state.closurify = true;
|
||||||
},
|
},
|
||||||
}, tdzVisitor]);
|
},
|
||||||
|
tdzVisitor,
|
||||||
|
]);
|
||||||
|
|
||||||
const hoistVarDeclarationsVisitor = {
|
const hoistVarDeclarationsVisitor = {
|
||||||
enter(path, self) {
|
enter(path, self) {
|
||||||
@ -166,7 +196,9 @@ const hoistVarDeclarationsVisitor = {
|
|||||||
node.left = node.left.declarations[0].id;
|
node.left = node.left.declarations[0].id;
|
||||||
}
|
}
|
||||||
} else if (isVar(node, parent)) {
|
} 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()) {
|
} else if (path.isFunction()) {
|
||||||
return path.skip();
|
return path.skip();
|
||||||
}
|
}
|
||||||
@ -184,7 +216,12 @@ const continuationVisitor = {
|
|||||||
if (path.isAssignmentExpression() || path.isUpdateExpression()) {
|
if (path.isAssignmentExpression() || path.isUpdateExpression()) {
|
||||||
const bindings = path.getBindingIdentifiers();
|
const bindings = path.getBindingIdentifiers();
|
||||||
for (const name in bindings) {
|
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;
|
state.reassignments[name] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +289,10 @@ const loopVisitor = {
|
|||||||
if (path.isReturnStatement()) {
|
if (path.isReturnStatement()) {
|
||||||
state.hasReturn = true;
|
state.hasReturn = true;
|
||||||
replace = t.objectExpression([
|
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 {
|
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.parent = parent;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
@ -281,7 +327,8 @@ class BlockScoping {
|
|||||||
|
|
||||||
if (loopPath) {
|
if (loopPath) {
|
||||||
this.loopParent = loopPath.parent;
|
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.loopPath = loopPath;
|
||||||
this.loop = loopPath.node;
|
this.loop = loopPath.node;
|
||||||
}
|
}
|
||||||
@ -360,11 +407,13 @@ class BlockScoping {
|
|||||||
// The same identifier might have been bound separately in the block scope and
|
// 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
|
// the enclosing scope (e.g. loop or catch statement), so we should handle both
|
||||||
// individually
|
// individually
|
||||||
if (scope.hasOwnBinding(key))
|
if (scope.hasOwnBinding(key)) {
|
||||||
{scope.rename(ref.name);}
|
scope.rename(ref.name);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.blockPath.scope.hasOwnBinding(key))
|
if (this.blockPath.scope.hasOwnBinding(key)) {
|
||||||
{this.blockPath.scope.rename(ref.name);}
|
this.blockPath.scope.rename(ref.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,7 +422,7 @@ class BlockScoping {
|
|||||||
if (this.file.opts.throwIfClosureRequired) {
|
if (this.file.opts.throwIfClosureRequired) {
|
||||||
throw this.blockPath.buildCodeFrameError(
|
throw this.blockPath.buildCodeFrameError(
|
||||||
"Compiling let/const in this block would add a closure " +
|
"Compiling let/const in this block would add a closure " +
|
||||||
"(throwIfClosureRequired)."
|
"(throwIfClosureRequired).",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const block = this.block;
|
const block = this.block;
|
||||||
@ -385,7 +434,10 @@ class BlockScoping {
|
|||||||
for (const name in outsideRefs) {
|
for (const name in outsideRefs) {
|
||||||
const id = outsideRefs[name];
|
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 outsideRefs[id.name];
|
||||||
delete this.letReferences[id.name];
|
delete this.letReferences[id.name];
|
||||||
|
|
||||||
@ -411,8 +463,11 @@ class BlockScoping {
|
|||||||
const isSwitch = this.blockPath.isSwitchStatement();
|
const isSwitch = this.blockPath.isSwitchStatement();
|
||||||
|
|
||||||
// build the closure that we're going to wrap the block with, possible wrapping switch(){}
|
// build the closure that we're going to wrap the block with, possible wrapping switch(){}
|
||||||
const fn = t.functionExpression(null, params,
|
const fn = t.functionExpression(
|
||||||
t.blockStatement(isSwitch ? [block] : block.body));
|
null,
|
||||||
|
params,
|
||||||
|
t.blockStatement(isSwitch ? [block] : block.body),
|
||||||
|
);
|
||||||
|
|
||||||
// continuation
|
// continuation
|
||||||
this.addContinuations(fn);
|
this.addContinuations(fn);
|
||||||
@ -421,7 +476,12 @@ class BlockScoping {
|
|||||||
let basePath = ".callee";
|
let basePath = ".callee";
|
||||||
|
|
||||||
// handle generators
|
// 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) {
|
if (hasYield) {
|
||||||
fn.generator = true;
|
fn.generator = true;
|
||||||
call = t.yieldExpression(call, true);
|
call = t.yieldExpression(call, true);
|
||||||
@ -429,7 +489,12 @@ class BlockScoping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handlers async functions
|
// 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) {
|
if (hasAsync) {
|
||||||
fn.async = true;
|
fn.async = true;
|
||||||
call = t.awaitExpression(call);
|
call = t.awaitExpression(call);
|
||||||
@ -441,9 +506,9 @@ class BlockScoping {
|
|||||||
if (this.has.hasReturn || this.has.hasBreakContinue) {
|
if (this.has.hasReturn || this.has.hasBreakContinue) {
|
||||||
const ret = this.scope.generateUidIdentifier("ret");
|
const ret = this.scope.generateUidIdentifier("ret");
|
||||||
|
|
||||||
this.body.push(t.variableDeclaration("var", [
|
this.body.push(
|
||||||
t.variableDeclarator(ret, call),
|
t.variableDeclaration("var", [t.variableDeclarator(ret, call)]),
|
||||||
]));
|
);
|
||||||
placeholderPath = "declarations.0.init" + basePath;
|
placeholderPath = "declarations.0.init" + basePath;
|
||||||
index = this.body.length - 1;
|
index = this.body.length - 1;
|
||||||
|
|
||||||
@ -471,9 +536,9 @@ class BlockScoping {
|
|||||||
let fnPath;
|
let fnPath;
|
||||||
if (this.loop) {
|
if (this.loop) {
|
||||||
const ref = this.scope.generateUidIdentifier("loop");
|
const ref = this.scope.generateUidIdentifier("loop");
|
||||||
const p = this.loopPath.insertBefore(t.variableDeclaration("var", [
|
const p = this.loopPath.insertBefore(
|
||||||
t.variableDeclarator(ref, fn),
|
t.variableDeclaration("var", [t.variableDeclarator(ref, fn)]),
|
||||||
]));
|
);
|
||||||
|
|
||||||
placeholder.replaceWith(ref);
|
placeholder.replaceWith(ref);
|
||||||
fnPath = p[0].get("declarations.0.init");
|
fnPath = p[0].get("declarations.0.init");
|
||||||
@ -512,7 +577,9 @@ class BlockScoping {
|
|||||||
this.scope.rename(param.name, newParam.name, fn);
|
this.scope.rename(param.name, newParam.name, fn);
|
||||||
|
|
||||||
// assign outer reference as it's been modified internally and needs to be retained
|
// 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) => {
|
const addDeclarationsFromChild = (path, node) => {
|
||||||
node = node || 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)) {
|
if (isBlockScoped(node)) {
|
||||||
convertBlockScopedToVar(path, node, block, this.scope);
|
convertBlockScopedToVar(path, node, block, this.scope);
|
||||||
}
|
}
|
||||||
@ -585,7 +656,7 @@ class BlockScoping {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loopOrFunctionParent = this.blockPath.find(
|
const loopOrFunctionParent = this.blockPath.find(
|
||||||
(path) => path.isLoop() || path.isFunction()
|
path => path.isLoop() || path.isFunction(),
|
||||||
);
|
);
|
||||||
if (loopOrFunctionParent && loopOrFunctionParent.isLoop()) {
|
if (loopOrFunctionParent && loopOrFunctionParent.isLoop()) {
|
||||||
// There is a loop ancestor closer than the closest function, so we
|
// There is a loop ancestor closer than the closest function, so we
|
||||||
@ -686,18 +757,20 @@ class BlockScoping {
|
|||||||
|
|
||||||
if (cases.length === 1) {
|
if (cases.length === 1) {
|
||||||
const single = cases[0];
|
const single = cases[0];
|
||||||
body.push(t.ifStatement(
|
body.push(
|
||||||
|
t.ifStatement(
|
||||||
t.binaryExpression("===", ret, single.test),
|
t.binaryExpression("===", ret, single.test),
|
||||||
single.consequent[0]
|
single.consequent[0],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (this.loop) {
|
if (this.loop) {
|
||||||
// https://github.com/babel/babel/issues/998
|
// https://github.com/babel/babel/issues/998
|
||||||
for (let i = 0; i < cases.length; i++) {
|
for (let i = 0; i < cases.length; i++) {
|
||||||
const caseConsequent = cases[i].consequent[0];
|
const caseConsequent = cases[i].consequent[0];
|
||||||
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
|
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
|
||||||
caseConsequent.label = this.loopLabel = this.loopLabel ||
|
caseConsequent.label = this.loopLabel =
|
||||||
this.scope.generateUidIdentifier("loop");
|
this.loopLabel || this.scope.generateUidIdentifier("loop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,11 @@ function getTDZStatus(refPath, bindingPath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildTDZAssert(node, file) {
|
function buildTDZAssert(node, file) {
|
||||||
return t.callExpression(
|
return t.callExpression(file.addHelper("temporalRef"), [
|
||||||
file.addHelper("temporalRef"),
|
node,
|
||||||
[node, t.stringLiteral(node.name), file.addHelper("temporalUndefined")]
|
t.stringLiteral(node.name),
|
||||||
);
|
file.addHelper("temporalUndefined"),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isReference(node, scope, state) {
|
function isReference(node, scope, state) {
|
||||||
@ -56,12 +57,18 @@ export const visitor = {
|
|||||||
path.replaceWith(assert);
|
path.replaceWith(assert);
|
||||||
}
|
}
|
||||||
} else if (status === "outside") {
|
} else if (status === "outside") {
|
||||||
path.replaceWith(t.throwStatement(t.inherits(
|
path.replaceWith(
|
||||||
|
t.throwStatement(
|
||||||
|
t.inherits(
|
||||||
t.newExpression(t.identifier("ReferenceError"), [
|
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;
|
if (!path.get("declaration").isClassDeclaration()) return;
|
||||||
|
|
||||||
const { node } = path;
|
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;
|
node.declaration.id = ref;
|
||||||
|
|
||||||
// Split the class declaration and the export into two separate statements.
|
// Split the class declaration and the export into two separate statements.
|
||||||
path.replaceWith(node.declaration);
|
path.replaceWith(node.declaration);
|
||||||
path.insertAfter(t.exportNamedDeclaration(
|
path.insertAfter(
|
||||||
null,
|
t.exportNamedDeclaration(null, [
|
||||||
[t.exportSpecifier(ref, t.identifier("default"))]
|
t.exportSpecifier(ref, t.identifier("default")),
|
||||||
));
|
]),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
ClassDeclaration(path) {
|
ClassDeclaration(path) {
|
||||||
@ -28,9 +30,11 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
const ref = node.id || path.scope.generateUidIdentifier("class");
|
const ref = node.id || path.scope.generateUidIdentifier("class");
|
||||||
|
|
||||||
path.replaceWith(t.variableDeclaration("let", [
|
path.replaceWith(
|
||||||
|
t.variableDeclaration("let", [
|
||||||
t.variableDeclarator(ref, t.toExpression(node)),
|
t.variableDeclarator(ref, t.toExpression(node)),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
ClassExpression(path, state) {
|
ClassExpression(path, state) {
|
||||||
@ -47,7 +51,10 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
path.replaceWith(new Constructor(path, state.file).run());
|
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();
|
path.get("callee").arrowFunctionToExpression();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import type { Scope } from "babel-traverse";
|
import type { Scope } from "babel-traverse";
|
||||||
import * as t from "babel-types";
|
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) {
|
for (const decorator of decorators) {
|
||||||
const expression = decorator.expression;
|
const expression = decorator.expression;
|
||||||
if (!t.isMemberExpression(expression)) continue;
|
if (!t.isMemberExpression(expression)) continue;
|
||||||
@ -18,13 +21,15 @@ export default function (decorators: Array<Object>, scope: Scope): Array<Object>
|
|||||||
ref = expression.object;
|
ref = expression.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.push(t.callExpression(
|
nodes.push(
|
||||||
|
t.callExpression(
|
||||||
t.memberExpression(
|
t.memberExpression(
|
||||||
t.memberExpression(ref, expression.property, expression.computed),
|
t.memberExpression(ref, expression.property, expression.computed),
|
||||||
t.identifier("bind")
|
t.identifier("bind"),
|
||||||
),
|
),
|
||||||
[ref]
|
[ref],
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (nodes.length === 1) {
|
if (nodes.length === 1) {
|
||||||
decorator.expression = nodes[0];
|
decorator.expression = nodes[0];
|
||||||
|
|||||||
@ -13,10 +13,22 @@ export default class LooseClassTransformer extends VanillaTransformer {
|
|||||||
// use assignments instead of define properties for loose classes
|
// use assignments instead of define properties for loose classes
|
||||||
|
|
||||||
let classRef = this.classRef;
|
let classRef = this.classRef;
|
||||||
if (!node.static) classRef = t.memberExpression(classRef, t.identifier("prototype"));
|
if (!node.static) {
|
||||||
const methodName = t.memberExpression(classRef, node.key, node.computed || t.isLiteral(node.key));
|
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;
|
func.returnType = node.returnType;
|
||||||
const key = t.toComputedKey(node, node.key);
|
const key = t.toComputedKey(node, node.key);
|
||||||
if (t.isStringLiteral(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);
|
t.inheritsComments(expr, node);
|
||||||
this.body.push(expr);
|
this.body.push(expr);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -22,14 +22,20 @@ const noMethodVisitor = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const verifyConstructorVisitor = visitors.merge([noMethodVisitor, {
|
const verifyConstructorVisitor = visitors.merge([
|
||||||
|
noMethodVisitor,
|
||||||
|
{
|
||||||
MemberExpression: {
|
MemberExpression: {
|
||||||
exit(path) {
|
exit(path) {
|
||||||
const objectPath = path.get("object");
|
const objectPath = path.get("object");
|
||||||
if (this.isDerived && !this.hasBareSuper && objectPath.isSuper()) {
|
if (this.isDerived && !this.hasBareSuper && objectPath.isSuper()) {
|
||||||
const hasArrowFunctionParent = path.findParent((p) => p.isArrowFunctionExpression());
|
const hasArrowFunctionParent = path.findParent(p =>
|
||||||
|
p.isArrowFunctionExpression(),
|
||||||
|
);
|
||||||
if (!hasArrowFunctionParent) {
|
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;
|
this.hasBareSuper = true;
|
||||||
|
|
||||||
if (!this.isDerived) {
|
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) {
|
ThisExpression(path) {
|
||||||
if (this.isDerived && !this.hasBareSuper) {
|
if (this.isDerived && !this.hasBareSuper) {
|
||||||
const fn = path.find((p) => p.isFunction());
|
const fn = path.find(p => p.isFunction());
|
||||||
|
|
||||||
if (!fn || !fn.isArrowFunctionExpression()) {
|
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) {
|
ThisExpression(path) {
|
||||||
this.superThises.push(path);
|
this.superThises.push(path);
|
||||||
},
|
},
|
||||||
}]);
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
export default class ClassTransformer {
|
export default class ClassTransformer {
|
||||||
constructor(path: NodePath, file) {
|
constructor(path: NodePath, file) {
|
||||||
@ -92,8 +106,9 @@ export default class ClassTransformer {
|
|||||||
this.classId = this.node.id;
|
this.classId = this.node.id;
|
||||||
|
|
||||||
// this is the name of the binding that will **always** reference the class we've constructed
|
// 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.classRef = this.node.id
|
||||||
this.scope.generateUidIdentifier("class");
|
? t.identifier(this.node.id.name)
|
||||||
|
: this.scope.generateUidIdentifier("class");
|
||||||
|
|
||||||
this.superName = this.node.superClass || t.identifier("Function");
|
this.superName = this.node.superClass || t.identifier("Function");
|
||||||
this.isDerived = !!this.node.superClass;
|
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();
|
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())
|
// make sure this class isn't directly called (with A() instead new A())
|
||||||
if (!this.isLoose) {
|
if (!this.isLoose) {
|
||||||
constructorBody.body.unshift(t.expressionStatement(t.callExpression(
|
constructorBody.body.unshift(
|
||||||
file.addHelper("classCallCheck"), [
|
t.expressionStatement(
|
||||||
|
t.callExpression(file.addHelper("classCallCheck"), [
|
||||||
t.thisExpression(),
|
t.thisExpression(),
|
||||||
this.classRef,
|
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) {
|
if (this.classId) {
|
||||||
// named class with only a constructor
|
// named class with only a constructor
|
||||||
@ -147,7 +164,10 @@ export default class ClassTransformer {
|
|||||||
//
|
//
|
||||||
body.push(t.returnStatement(this.classRef));
|
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);
|
return t.callExpression(container, closureArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,12 +221,12 @@ export default class ClassTransformer {
|
|||||||
body = t.blockStatement([]);
|
body = t.blockStatement([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.path.get("body").unshiftContainer("body", t.classMethod(
|
this.path
|
||||||
"constructor",
|
.get("body")
|
||||||
t.identifier("constructor"),
|
.unshiftContainer(
|
||||||
params,
|
"body",
|
||||||
body
|
t.classMethod("constructor", t.identifier("constructor"), params, body),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildBody() {
|
buildBody() {
|
||||||
@ -216,7 +236,9 @@ export default class ClassTransformer {
|
|||||||
|
|
||||||
if (this.userConstructor) {
|
if (this.userConstructor) {
|
||||||
const constructorBody = this.constructorBody;
|
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(this.constructor, this.userConstructor);
|
||||||
t.inherits(constructorBody, this.userConstructor.body);
|
t.inherits(constructorBody, this.userConstructor.body);
|
||||||
}
|
}
|
||||||
@ -236,7 +258,8 @@ export default class ClassTransformer {
|
|||||||
|
|
||||||
if (node.decorators) {
|
if (node.decorators) {
|
||||||
throw path.buildCodeFrameError(
|
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)) {
|
if (t.isClassMethod(node)) {
|
||||||
@ -246,11 +269,14 @@ export default class ClassTransformer {
|
|||||||
path.traverse(verifyConstructorVisitor, this);
|
path.traverse(verifyConstructorVisitor, this);
|
||||||
|
|
||||||
if (!this.hasBareSuper && this.isDerived) {
|
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,
|
forceSuperMemoisation: isConstructor,
|
||||||
methodPath: path,
|
methodPath: path,
|
||||||
methodNode: node,
|
methodNode: node,
|
||||||
@ -260,7 +286,9 @@ export default class ClassTransformer {
|
|||||||
isLoose: this.isLoose,
|
isLoose: this.isLoose,
|
||||||
scope: this.scope,
|
scope: this.scope,
|
||||||
file: this.file,
|
file: this.file,
|
||||||
}, true);
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
replaceSupers.replace();
|
replaceSupers.replace();
|
||||||
|
|
||||||
@ -298,8 +326,12 @@ export default class ClassTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (instanceProps || staticProps) {
|
if (instanceProps || staticProps) {
|
||||||
if (instanceProps) instanceProps = defineMap.toComputedObjectFromClass(instanceProps);
|
if (instanceProps) {
|
||||||
if (staticProps) staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
instanceProps = defineMap.toComputedObjectFromClass(instanceProps);
|
||||||
|
}
|
||||||
|
if (staticProps) {
|
||||||
|
staticProps = defineMap.toComputedObjectFromClass(staticProps);
|
||||||
|
}
|
||||||
|
|
||||||
const nullNode = t.nullLiteral();
|
const nullNode = t.nullLiteral();
|
||||||
|
|
||||||
@ -330,10 +362,11 @@ export default class ClassTransformer {
|
|||||||
}
|
}
|
||||||
args = args.slice(0, lastNonNullIndex + 1);
|
args = args.slice(0, lastNonNullIndex + 1);
|
||||||
|
|
||||||
|
body.push(
|
||||||
body.push(t.expressionStatement(
|
t.expressionStatement(
|
||||||
t.callExpression(this.file.addHelper("createClass"), args)
|
t.callExpression(this.file.addHelper("createClass"), args),
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clearDescriptors();
|
this.clearDescriptors();
|
||||||
@ -353,13 +386,21 @@ export default class ClassTransformer {
|
|||||||
if (
|
if (
|
||||||
bareSuperNode.arguments.length === 2 &&
|
bareSuperNode.arguments.length === 2 &&
|
||||||
t.isSpreadElement(bareSuperNode.arguments[1]) &&
|
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
|
// special case single arguments spread
|
||||||
bareSuperNode.arguments[1] = bareSuperNode.arguments[1].argument;
|
bareSuperNode.arguments[1] = bareSuperNode.arguments[1].argument;
|
||||||
bareSuperNode.callee = t.memberExpression(superRef, t.identifier("apply"));
|
bareSuperNode.callee = t.memberExpression(
|
||||||
|
superRef,
|
||||||
|
t.identifier("apply"),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
bareSuperNode.callee = t.memberExpression(superRef, t.identifier("call"));
|
bareSuperNode.callee = t.memberExpression(
|
||||||
|
superRef,
|
||||||
|
t.identifier("call"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bareSuperNode = optimiseCall(
|
bareSuperNode = optimiseCall(
|
||||||
@ -367,12 +408,15 @@ export default class ClassTransformer {
|
|||||||
"||",
|
"||",
|
||||||
t.memberExpression(this.classRef, t.identifier("__proto__")),
|
t.memberExpression(this.classRef, t.identifier("__proto__")),
|
||||||
t.callExpression(
|
t.callExpression(
|
||||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
t.memberExpression(
|
||||||
[this.classRef]
|
t.identifier("Object"),
|
||||||
)
|
t.identifier("getPrototypeOf"),
|
||||||
|
),
|
||||||
|
[this.classRef],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
t.thisExpression(),
|
t.thisExpression(),
|
||||||
bareSuperNode.arguments
|
bareSuperNode.arguments,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,11 +427,11 @@ export default class ClassTransformer {
|
|||||||
} else {
|
} else {
|
||||||
call = t.callExpression(
|
call = t.callExpression(
|
||||||
this.file.addHelper("possibleConstructorReturn"),
|
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 (
|
if (
|
||||||
bareSuper.parentPath.isExpressionStatement() &&
|
bareSuper.parentPath.isExpressionStatement() &&
|
||||||
@ -409,14 +453,11 @@ export default class ClassTransformer {
|
|||||||
bareSuper.parentPath.replaceWith(t.returnStatement(call));
|
bareSuper.parentPath.replaceWith(t.returnStatement(call));
|
||||||
} else {
|
} else {
|
||||||
bareSuper.replaceWithMultiple([
|
bareSuper.replaceWithMultiple([
|
||||||
t.variableDeclaration("var", [
|
t.variableDeclaration("var", [t.variableDeclarator(thisRef, call)]),
|
||||||
t.variableDeclarator(thisRef, call),
|
|
||||||
]),
|
|
||||||
...bareSuperAfter,
|
...bareSuperAfter,
|
||||||
t.expressionStatement(thisRef),
|
t.expressionStatement(thisRef),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyConstructor() {
|
verifyConstructor() {
|
||||||
@ -457,13 +498,16 @@ export default class ClassTransformer {
|
|||||||
let wrapReturn;
|
let wrapReturn;
|
||||||
|
|
||||||
if (this.isLoose) {
|
if (this.isLoose) {
|
||||||
wrapReturn = (returnArg) => {
|
wrapReturn = returnArg => {
|
||||||
return returnArg ? t.logicalExpression("||", returnArg, thisRef) : thisRef;
|
return returnArg
|
||||||
|
? t.logicalExpression("||", returnArg, thisRef)
|
||||||
|
: thisRef;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
wrapReturn = (returnArg) => t.callExpression(
|
wrapReturn = returnArg =>
|
||||||
|
t.callExpression(
|
||||||
this.file.addHelper("possibleConstructorReturn"),
|
this.file.addHelper("possibleConstructorReturn"),
|
||||||
[thisRef].concat(returnArg || [])
|
[thisRef].concat(returnArg || []),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,14 +515,18 @@ export default class ClassTransformer {
|
|||||||
// return
|
// return
|
||||||
const bodyPaths = body.get("body");
|
const bodyPaths = body.get("body");
|
||||||
if (bodyPaths.length && !bodyPaths.pop().isReturnStatement()) {
|
if (bodyPaths.length && !bodyPaths.pop().isReturnStatement()) {
|
||||||
body.pushContainer("body", t.returnStatement(
|
body.pushContainer(
|
||||||
guaranteedSuperBeforeFinish ? thisRef : wrapReturn()));
|
"body",
|
||||||
|
t.returnStatement(guaranteedSuperBeforeFinish ? thisRef : wrapReturn()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const returnPath of this.superReturns) {
|
for (const returnPath of this.superReturns) {
|
||||||
if (returnPath.node.argument) {
|
if (returnPath.node.argument) {
|
||||||
const ref = returnPath.scope.generateDeclaredUidIdentifier("ret");
|
const ref = returnPath.scope.generateDeclaredUidIdentifier("ret");
|
||||||
returnPath.get("argument").replaceWithMultiple([
|
returnPath
|
||||||
|
.get("argument")
|
||||||
|
.replaceWithMultiple([
|
||||||
t.assignmentExpression("=", ref, returnPath.node.argument),
|
t.assignmentExpression("=", ref, returnPath.node.argument),
|
||||||
wrapReturn(ref),
|
wrapReturn(ref),
|
||||||
]);
|
]);
|
||||||
@ -510,7 +558,11 @@ export default class ClassTransformer {
|
|||||||
* Replace the constructor body of our class.
|
* 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.bareSupers = replaceSupers.bareSupers;
|
||||||
this.superReturns = replaceSupers.returns;
|
this.superReturns = replaceSupers.returns;
|
||||||
|
|
||||||
@ -561,9 +613,15 @@ export default class ClassTransformer {
|
|||||||
// Unshift to ensure that the constructor inheritance is set up before
|
// Unshift to ensure that the constructor inheritance is set up before
|
||||||
// any properties can be assigned to the prototype.
|
// any properties can be assigned to the prototype.
|
||||||
this.pushedInherits = true;
|
this.pushedInherits = true;
|
||||||
this.body.unshift(t.expressionStatement(t.callExpression(
|
this.body.unshift(
|
||||||
this.isLoose ? this.file.addHelper("inheritsLoose") : this.file.addHelper("inherits"),
|
t.expressionStatement(
|
||||||
[this.classRef, this.superName]
|
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)) {
|
if (t.isObjectProperty(prop)) {
|
||||||
return prop.value;
|
return prop.value;
|
||||||
} else if (t.isObjectMethod(prop)) {
|
} 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") {
|
if (prop.kind === "get" && prop.kind === "set") {
|
||||||
pushMutatorDefine(objId, prop, body);
|
pushMutatorDefine(objId, prop, body);
|
||||||
} else {
|
} else {
|
||||||
body.push(t.expressionStatement(
|
body.push(
|
||||||
|
t.expressionStatement(
|
||||||
t.assignmentExpression(
|
t.assignmentExpression(
|
||||||
"=",
|
"=",
|
||||||
t.memberExpression(objId, prop.key, prop.computed || t.isLiteral(prop.key)),
|
t.memberExpression(
|
||||||
getValue(prop)
|
objId,
|
||||||
)
|
prop.key,
|
||||||
));
|
prop.computed || t.isLiteral(prop.key),
|
||||||
|
),
|
||||||
|
getValue(prop),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushMutatorDefine({ objId, body, getMutatorId, scope }, 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);
|
const maybeMemoise = scope.maybeGenerateMemoised(key);
|
||||||
if (maybeMemoise) {
|
if (maybeMemoise) {
|
||||||
body.push(t.expressionStatement(t.assignmentExpression("=", maybeMemoise, key)));
|
body.push(
|
||||||
|
t.expressionStatement(t.assignmentExpression("=", maybeMemoise, key)),
|
||||||
|
);
|
||||||
key = maybeMemoise;
|
key = maybeMemoise;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.push(...buildMutatorMapAssign({
|
body.push(
|
||||||
|
...buildMutatorMapAssign({
|
||||||
MUTATOR_MAP_REF: getMutatorId(),
|
MUTATOR_MAP_REF: getMutatorId(),
|
||||||
KEY: key,
|
KEY: key,
|
||||||
VALUE: getValue(prop),
|
VALUE: getValue(prop),
|
||||||
KIND: t.identifier(prop.kind),
|
KIND: t.identifier(prop.kind),
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loose(info) {
|
function loose(info) {
|
||||||
@ -71,13 +90,15 @@ export default function ({ types: t, template }) {
|
|||||||
getValue(prop),
|
getValue(prop),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
body.push(t.expressionStatement(
|
body.push(
|
||||||
|
t.expressionStatement(
|
||||||
t.callExpression(state.addHelper("defineProperty"), [
|
t.callExpression(state.addHelper("defineProperty"), [
|
||||||
objId,
|
objId,
|
||||||
key,
|
key,
|
||||||
getValue(prop),
|
getValue(prop),
|
||||||
])
|
]),
|
||||||
));
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,9 +139,11 @@ export default function ({ types: t, template }) {
|
|||||||
const initPropExpression = t.objectExpression(initProps);
|
const initPropExpression = t.objectExpression(initProps);
|
||||||
const body = [];
|
const body = [];
|
||||||
|
|
||||||
body.push(t.variableDeclaration("var", [
|
body.push(
|
||||||
|
t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(objId, initPropExpression),
|
t.variableDeclarator(objId, initPropExpression),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
let callback = spec;
|
let callback = spec;
|
||||||
if (state.opts.loose) callback = loose;
|
if (state.opts.loose) callback = loose;
|
||||||
@ -131,9 +154,11 @@ export default function ({ types: t, template }) {
|
|||||||
if (!mutatorRef) {
|
if (!mutatorRef) {
|
||||||
mutatorRef = scope.generateUidIdentifier("mutatorMap");
|
mutatorRef = scope.generateUidIdentifier("mutatorMap");
|
||||||
|
|
||||||
body.push(t.variableDeclaration("var", [
|
body.push(
|
||||||
|
t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(mutatorRef, t.objectExpression([])),
|
t.variableDeclarator(mutatorRef, t.objectExpression([])),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mutatorRef;
|
return mutatorRef;
|
||||||
@ -150,10 +175,14 @@ export default function ({ types: t, template }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (mutatorRef) {
|
if (mutatorRef) {
|
||||||
body.push(t.expressionStatement(t.callExpression(
|
body.push(
|
||||||
|
t.expressionStatement(
|
||||||
|
t.callExpression(
|
||||||
state.addHelper("defineEnumerableProperties"),
|
state.addHelper("defineEnumerableProperties"),
|
||||||
[objId, mutatorRef]
|
[objId, mutatorRef],
|
||||||
)));
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (single) {
|
if (single) {
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
export default function({ types: t }) {
|
export default function({ types: t }) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if a VariableDeclaration's declarations contains any Patterns.
|
* Test if a VariableDeclaration's declarations contains any Patterns.
|
||||||
*/
|
*/
|
||||||
@ -86,7 +85,10 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toArray(node, count) {
|
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;
|
return node;
|
||||||
} else {
|
} else {
|
||||||
return this.scope.toArray(node, count);
|
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
|
// we need to assign the current value of the assignment to avoid evaluating
|
||||||
// it more than once
|
// it more than once
|
||||||
|
|
||||||
const tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
|
const tempValueRef = this.scope.generateUidIdentifierBasedOnNode(
|
||||||
|
valueRef,
|
||||||
|
);
|
||||||
|
|
||||||
const declar = t.variableDeclaration("var", [
|
const declar = t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(tempValueRef, valueRef),
|
t.variableDeclarator(tempValueRef, valueRef),
|
||||||
@ -110,13 +114,13 @@ export default function ({ types: t }) {
|
|||||||
const tempConditional = t.conditionalExpression(
|
const tempConditional = t.conditionalExpression(
|
||||||
t.binaryExpression("===", tempValueRef, t.identifier("undefined")),
|
t.binaryExpression("===", tempValueRef, t.identifier("undefined")),
|
||||||
pattern.right,
|
pattern.right,
|
||||||
tempValueRef
|
tempValueRef,
|
||||||
);
|
);
|
||||||
|
|
||||||
const left = pattern.left;
|
const left = pattern.left;
|
||||||
if (t.isPattern(left)) {
|
if (t.isPattern(left)) {
|
||||||
const tempValueDefault = t.expressionStatement(
|
const tempValueDefault = t.expressionStatement(
|
||||||
t.assignmentExpression("=", tempValueRef, tempConditional)
|
t.assignmentExpression("=", tempValueRef, tempConditional),
|
||||||
);
|
);
|
||||||
tempValueDefault._blockHoist = this.blockHoist;
|
tempValueDefault._blockHoist = this.blockHoist;
|
||||||
|
|
||||||
@ -143,7 +147,9 @@ export default function ({ types: t }) {
|
|||||||
if (t.isRestElement(prop)) continue;
|
if (t.isRestElement(prop)) continue;
|
||||||
|
|
||||||
let key = prop.key;
|
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);
|
keys.push(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +158,9 @@ export default function ({ types: t }) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
const value = t.callExpression(
|
const value = t.callExpression(
|
||||||
this.file.addHelper("objectWithoutProperties"), [objRef, keys]);
|
this.file.addHelper("objectWithoutProperties"),
|
||||||
|
[objRef, keys],
|
||||||
|
);
|
||||||
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
|
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +181,13 @@ export default function ({ types: t }) {
|
|||||||
// https://github.com/babel/babel/issues/681
|
// https://github.com/babel/babel/issues/681
|
||||||
|
|
||||||
if (!pattern.properties.length) {
|
if (!pattern.properties.length) {
|
||||||
this.nodes.push(t.expressionStatement(
|
this.nodes.push(
|
||||||
t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [objRef])
|
t.expressionStatement(
|
||||||
));
|
t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [
|
||||||
|
objRef,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have more than one properties in this pattern and the objectRef is a
|
// 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
|
// pattern has less elements than the array and doesn't have a rest so some
|
||||||
// elements wont be evaluated
|
// elements wont be evaluated
|
||||||
if (pattern.elements.length > arr.elements.length) return;
|
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)) {
|
for (const elem of (pattern.elements: Array)) {
|
||||||
// deopt on holes
|
// deopt on holes
|
||||||
@ -293,8 +307,10 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
if (t.isRestElement(elem)) {
|
if (t.isRestElement(elem)) {
|
||||||
elemRef = this.toArray(arrayRef);
|
elemRef = this.toArray(arrayRef);
|
||||||
elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")),
|
elemRef = t.callExpression(
|
||||||
[t.numericLiteral(i)]);
|
t.memberExpression(elemRef, t.identifier("slice")),
|
||||||
|
[t.numericLiteral(i)],
|
||||||
|
);
|
||||||
|
|
||||||
// set the element to the rest element argument since we've dealt with it
|
// set the element to the rest element argument since we've dealt with it
|
||||||
// being a rest already
|
// being a rest already
|
||||||
@ -327,7 +343,6 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
ExportNamedDeclaration(path) {
|
ExportNamedDeclaration(path) {
|
||||||
@ -364,9 +379,9 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
path.ensureBlock();
|
path.ensureBlock();
|
||||||
|
|
||||||
node.body.body.unshift(t.variableDeclaration("var", [
|
node.body.body.unshift(
|
||||||
t.variableDeclarator(left, temp),
|
t.variableDeclaration("var", [t.variableDeclarator(left, temp)]),
|
||||||
]));
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -432,12 +447,17 @@ export default function ({ types: t }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let ref;
|
let ref;
|
||||||
if (path.isCompletionRecord() || !path.parentPath.isExpressionStatement()) {
|
if (
|
||||||
|
path.isCompletionRecord() ||
|
||||||
|
!path.parentPath.isExpressionStatement()
|
||||||
|
) {
|
||||||
ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
|
ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
|
||||||
|
|
||||||
nodes.push(t.variableDeclaration("var", [
|
nodes.push(
|
||||||
|
t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(ref, node.right),
|
t.variableDeclarator(ref, node.right),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
if (t.isArrayExpression(node.right)) {
|
if (t.isArrayExpression(node.right)) {
|
||||||
destructuring.arrays[ref.name] = true;
|
destructuring.arrays[ref.name] = true;
|
||||||
@ -486,15 +506,23 @@ export default function ({ types: t }) {
|
|||||||
t.inherits(nodes[nodes.length - 1], declar);
|
t.inherits(nodes[nodes.length - 1], declar);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nodes.push(t.inherits(
|
nodes.push(
|
||||||
destructuring.buildVariableAssignment(declar.id, declar.init), declar));
|
t.inherits(
|
||||||
|
destructuring.buildVariableAssignment(declar.id, declar.init),
|
||||||
|
declar,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodesOut = [];
|
const nodesOut = [];
|
||||||
for (const node of nodes) {
|
for (const node of nodes) {
|
||||||
const tail = nodesOut[nodesOut.length - 1];
|
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
|
// Create a single compound declarations
|
||||||
tail.declarations.push(...node.declarations);
|
tail.declarations.push(...node.declarations);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -12,7 +12,9 @@ export default function() {
|
|||||||
visitor: {
|
visitor: {
|
||||||
ObjectExpression(path) {
|
ObjectExpression(path) {
|
||||||
const { node } = 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:
|
// A property is a duplicate key if:
|
||||||
// * the property is a data property, and is preceeded by a data,
|
// * the property is a data property, and is preceeded by a data,
|
||||||
@ -43,7 +45,11 @@ export default function() {
|
|||||||
alreadySeenSetters[name] = true;
|
alreadySeenSetters[name] = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (alreadySeenData[name] || alreadySeenGetters[name] || alreadySeenSetters[name]) {
|
if (
|
||||||
|
alreadySeenData[name] ||
|
||||||
|
alreadySeenGetters[name] ||
|
||||||
|
alreadySeenSetters[name]
|
||||||
|
) {
|
||||||
isDuplicate = true;
|
isDuplicate = true;
|
||||||
}
|
}
|
||||||
alreadySeenData[name] = true;
|
alreadySeenData[name] = true;
|
||||||
|
|||||||
@ -57,9 +57,9 @@ export default function ({ messages, template, types: t }) {
|
|||||||
|
|
||||||
if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) {
|
if (!t.isIdentifier(right) || !scope.hasBinding(right.name)) {
|
||||||
const uid = scope.generateUidIdentifier("arr");
|
const uid = scope.generateUidIdentifier("arr");
|
||||||
nodes.push(t.variableDeclaration("var", [
|
nodes.push(
|
||||||
t.variableDeclarator(uid, right),
|
t.variableDeclaration("var", [t.variableDeclarator(uid, right)]),
|
||||||
]));
|
);
|
||||||
right = uid;
|
right = uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +81,11 @@ export default function ({ messages, template, types: t }) {
|
|||||||
left.declarations[0].init = iterationValue;
|
left.declarations[0].init = iterationValue;
|
||||||
loop.body.body.unshift(left);
|
loop.body.body.unshift(left);
|
||||||
} else {
|
} else {
|
||||||
loop.body.body.unshift(t.expressionStatement(
|
loop.body.body.unshift(
|
||||||
t.assignmentExpression("=", left, iterationValue)));
|
t.expressionStatement(
|
||||||
|
t.assignmentExpression("=", left, iterationValue),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.parentPath.isLabeledStatement()) {
|
if (path.parentPath.isLabeledStatement()) {
|
||||||
@ -111,19 +114,18 @@ export default function ({ messages, template, types: t }) {
|
|||||||
} else if (right.isIdentifier() && right.isPure()) {
|
} else if (right.isIdentifier() && right.isPure()) {
|
||||||
const binding = path.scope.getBinding(right.node.name);
|
const binding = path.scope.getBinding(right.node.name);
|
||||||
return optimize(path, binding.path.get("init"));
|
return optimize(path, binding.path.get("init"));
|
||||||
} else if (right.isCallExpression() && (
|
} else if (
|
||||||
isArrayFrom(right.get("callee").node) ||
|
right.isCallExpression() &&
|
||||||
|
(isArrayFrom(right.get("callee").node) ||
|
||||||
isObjectKeys(right.get("callee").node) ||
|
isObjectKeys(right.get("callee").node) ||
|
||||||
isObjectValues(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);
|
const uid = path.scope.generateUidIdentifierBasedOnNode(right.node);
|
||||||
initPath.insertBefore(
|
initPath.insertBefore(
|
||||||
t.variableDeclaration("const", [
|
t.variableDeclaration("const", [t.variableDeclarator(uid, right.node)]),
|
||||||
t.variableDeclarator(uid, right.node),
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
right.replaceWith(uid);
|
right.replaceWith(uid);
|
||||||
return replaceWithArray(path);
|
return replaceWithArray(path);
|
||||||
@ -176,7 +178,11 @@ export default function ({ messages, template, types: t }) {
|
|||||||
const { left } = node;
|
const { left } = node;
|
||||||
let declar, id;
|
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)
|
// for (i of test), for ({ i } of test)
|
||||||
id = left;
|
id = left;
|
||||||
} else if (t.isVariableDeclaration(left)) {
|
} else if (t.isVariableDeclaration(left)) {
|
||||||
@ -186,7 +192,10 @@ export default function ({ messages, template, types: t }) {
|
|||||||
t.variableDeclarator(left.declarations[0].id, id),
|
t.variableDeclarator(left.declarations[0].id, id),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
throw file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));
|
throw file.buildCodeFrameError(
|
||||||
|
left,
|
||||||
|
messages.get("unknownForHead", left.type),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const iteratorKey = scope.generateUidIdentifier("iterator");
|
const iteratorKey = scope.generateUidIdentifier("iterator");
|
||||||
@ -230,16 +239,25 @@ export default function ({ messages, template, types: t }) {
|
|||||||
const stepKey = scope.generateUidIdentifier("step");
|
const stepKey = scope.generateUidIdentifier("step");
|
||||||
const stepValue = t.memberExpression(stepKey, t.identifier("value"));
|
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)
|
// 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)) {
|
} else if (t.isVariableDeclaration(left)) {
|
||||||
// for (let i of test)
|
// for (let i of test)
|
||||||
declar = t.variableDeclaration(left.kind, [
|
declar = t.variableDeclaration(left.kind, [
|
||||||
t.variableDeclarator(left.declarations[0].id, stepValue),
|
t.variableDeclarator(left.declarations[0].id, stepValue),
|
||||||
]);
|
]);
|
||||||
} else {
|
} 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({
|
const template = buildForOf({
|
||||||
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
|
||||||
ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
|
ITERATOR_COMPLETION: scope.generateUidIdentifier(
|
||||||
|
"iteratorNormalCompletion",
|
||||||
|
),
|
||||||
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
|
||||||
ITERATOR_KEY: iteratorKey,
|
ITERATOR_KEY: iteratorKey,
|
||||||
STEP_KEY: stepKey,
|
STEP_KEY: stepKey,
|
||||||
|
|||||||
@ -4,7 +4,12 @@ export default function ({ types: t }) {
|
|||||||
BinaryExpression(path) {
|
BinaryExpression(path) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
if (node.operator === "instanceof") {
|
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) {
|
CallExpression(path) {
|
||||||
if (!isValidRequireCall(path)) return;
|
if (!isValidRequireCall(path)) return;
|
||||||
const source = path.node.arguments[0];
|
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]);
|
this.sources.push([ref, source, true]);
|
||||||
path.remove();
|
path.remove();
|
||||||
},
|
},
|
||||||
@ -126,11 +128,13 @@ export default function ({ types: t }) {
|
|||||||
factory.expression.body.directives = node.directives;
|
factory.expression.body.directives = node.directives;
|
||||||
node.directives = [];
|
node.directives = [];
|
||||||
|
|
||||||
node.body = [buildDefine({
|
node.body = [
|
||||||
|
buildDefine({
|
||||||
MODULE_NAME: moduleName,
|
MODULE_NAME: moduleName,
|
||||||
SOURCES: sources,
|
SOURCES: sources,
|
||||||
FACTORY: factory,
|
FACTORY: factory,
|
||||||
})];
|
}),
|
||||||
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -42,8 +42,13 @@ const buildExportAll = template(`
|
|||||||
});
|
});
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassProperty",
|
const THIS_BREAK_KEYS = [
|
||||||
"ClassMethod", "ObjectMethod"];
|
"FunctionExpression",
|
||||||
|
"FunctionDeclaration",
|
||||||
|
"ClassProperty",
|
||||||
|
"ClassMethod",
|
||||||
|
"ObjectMethod",
|
||||||
|
];
|
||||||
|
|
||||||
export default function() {
|
export default function() {
|
||||||
const REASSIGN_REMAP_SKIP = Symbol();
|
const REASSIGN_REMAP_SKIP = Symbol();
|
||||||
@ -61,8 +66,12 @@ export default function () {
|
|||||||
path.replaceWith(t.sequenceExpression([t.numericLiteral(0), remap]));
|
path.replaceWith(t.sequenceExpression([t.numericLiteral(0), remap]));
|
||||||
} else if (path.isJSXIdentifier() && t.isMemberExpression(remap)) {
|
} else if (path.isJSXIdentifier() && t.isMemberExpression(remap)) {
|
||||||
const { object, property } = remap;
|
const { object, property } = remap;
|
||||||
path.replaceWith(t.JSXMemberExpression(t.JSXIdentifier(object.name),
|
path.replaceWith(
|
||||||
t.JSXIdentifier(property.name)));
|
t.JSXMemberExpression(
|
||||||
|
t.JSXIdentifier(object.name),
|
||||||
|
t.JSXIdentifier(property.name),
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
path.replaceWith(remap);
|
path.replaceWith(remap);
|
||||||
}
|
}
|
||||||
@ -104,9 +113,17 @@ export default function () {
|
|||||||
// redeclared in this scope
|
// redeclared in this scope
|
||||||
if (this.scope.getBinding(name) !== path.scope.getBinding(name)) return;
|
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);
|
path.replaceWith(node);
|
||||||
this.requeueInParent(path);
|
this.requeueInParent(path);
|
||||||
return;
|
return;
|
||||||
@ -118,7 +135,8 @@ export default function () {
|
|||||||
let operator;
|
let operator;
|
||||||
if (path.node.operator === "--") {
|
if (path.node.operator === "--") {
|
||||||
operator = "+";
|
operator = "+";
|
||||||
} else { // "++"
|
} else {
|
||||||
|
// "++"
|
||||||
operator = "-";
|
operator = "-";
|
||||||
}
|
}
|
||||||
nodes.push(t.binaryExpression(operator, arg.node, t.numericLiteral(1)));
|
nodes.push(t.binaryExpression(operator, arg.node, t.numericLiteral(1)));
|
||||||
@ -139,7 +157,7 @@ export default function () {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
state.opts.allowTopLevelThis !== true &&
|
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"));
|
path.replaceWith(t.identifier("undefined"));
|
||||||
}
|
}
|
||||||
@ -177,12 +195,15 @@ export default function () {
|
|||||||
const cached = requires[source];
|
const cached = requires[source];
|
||||||
if (cached) return cached;
|
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", [
|
const varDecl = t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(ref, buildRequire(
|
t.variableDeclarator(
|
||||||
t.stringLiteral(source)
|
ref,
|
||||||
).expression),
|
buildRequire(t.stringLiteral(source)).expression,
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Copy location from the original import statement for sourcemap
|
// Copy location from the original import statement for sourcemap
|
||||||
@ -197,7 +218,7 @@ export default function () {
|
|||||||
|
|
||||||
topNodes.push(varDecl);
|
topNodes.push(varDecl);
|
||||||
|
|
||||||
return requires[source] = ref;
|
return (requires[source] = ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTo(obj, key, arr) {
|
function addTo(obj, key, arr) {
|
||||||
@ -209,11 +230,16 @@ export default function () {
|
|||||||
if (path.isExportDeclaration()) {
|
if (path.isExportDeclaration()) {
|
||||||
hasExports = true;
|
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) {
|
for (const specifier of specifiers) {
|
||||||
const ids = specifier.getBindingIdentifiers();
|
const ids = specifier.getBindingIdentifiers();
|
||||||
if (ids.__esModule) {
|
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") {
|
if (typeof path.node._blockHoist === "number") {
|
||||||
importsEntry.maxBlockHoist = Math.max(
|
importsEntry.maxBlockHoist = Math.max(
|
||||||
path.node._blockHoist,
|
path.node._blockHoist,
|
||||||
importsEntry.maxBlockHoist
|
importsEntry.maxBlockHoist,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +276,12 @@ export default function () {
|
|||||||
topNodes.push(buildExportsAssignment(defNode, id));
|
topNodes.push(buildExportsAssignment(defNode, id));
|
||||||
path.replaceWith(declaration.node);
|
path.replaceWith(declaration.node);
|
||||||
} else {
|
} else {
|
||||||
topNodes.push(buildExportsAssignment(defNode, t.toExpression(declaration.node)));
|
topNodes.push(
|
||||||
|
buildExportsAssignment(
|
||||||
|
defNode,
|
||||||
|
t.toExpression(declaration.node),
|
||||||
|
),
|
||||||
|
);
|
||||||
path.remove();
|
path.remove();
|
||||||
}
|
}
|
||||||
} else if (declaration.isClassDeclaration()) {
|
} else if (declaration.isClassDeclaration()) {
|
||||||
@ -263,7 +294,12 @@ export default function () {
|
|||||||
buildExportsAssignment(defNode, id),
|
buildExportsAssignment(defNode, id),
|
||||||
]);
|
]);
|
||||||
} else {
|
} 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
|
// 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
|
// 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"));
|
path.parentPath.requeue(path.get("expression.left"));
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
// 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
|
// has an opportunity to convert them. Ideally this would happen automatically from the
|
||||||
@ -306,7 +347,9 @@ export default function () {
|
|||||||
|
|
||||||
if (id.isIdentifier()) {
|
if (id.isIdentifier()) {
|
||||||
addTo(exports, id.node.name, id.node);
|
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;
|
nonHoistedExportNames[id.node.name] = true;
|
||||||
} else if (id.isObjectPattern()) {
|
} else if (id.isObjectPattern()) {
|
||||||
for (let i = 0; i < id.node.properties.length; i++) {
|
for (let i = 0; i < id.node.properties.length; i++) {
|
||||||
@ -318,7 +361,9 @@ export default function () {
|
|||||||
propValue = prop.argument;
|
propValue = prop.argument;
|
||||||
}
|
}
|
||||||
addTo(exports, propValue.name, propValue);
|
addTo(exports, propValue.name, propValue);
|
||||||
exportsToInsert.push(buildExportsAssignment(propValue, propValue));
|
exportsToInsert.push(
|
||||||
|
buildExportsAssignment(propValue, propValue),
|
||||||
|
);
|
||||||
nonHoistedExportNames[propValue.name] = true;
|
nonHoistedExportNames[propValue.name] = true;
|
||||||
}
|
}
|
||||||
} else if (id.isArrayPattern() && id.node.elements) {
|
} else if (id.isArrayPattern() && id.node.elements) {
|
||||||
@ -332,7 +377,9 @@ export default function () {
|
|||||||
}
|
}
|
||||||
const name = elem.name;
|
const name = elem.name;
|
||||||
addTo(exports, name, elem);
|
addTo(exports, name, elem);
|
||||||
exportsToInsert.push(buildExportsAssignment(elem, elem));
|
exportsToInsert.push(
|
||||||
|
buildExportsAssignment(elem, elem),
|
||||||
|
);
|
||||||
nonHoistedExportNames[name] = true;
|
nonHoistedExportNames[name] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -356,15 +403,25 @@ export default function () {
|
|||||||
// todo
|
// todo
|
||||||
} else if (specifier.isExportSpecifier()) {
|
} else if (specifier.isExportSpecifier()) {
|
||||||
if (!noInterop && specifier.node.local.name === "default") {
|
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.memberExpression(
|
||||||
t.callExpression(this.addHelper("interopRequireDefault"), [ref]),
|
t.callExpression(
|
||||||
specifier.node.local
|
this.addHelper("interopRequireDefault"),
|
||||||
)
|
[ref],
|
||||||
));
|
),
|
||||||
|
specifier.node.local,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name),
|
topNodes.push(
|
||||||
t.memberExpression(ref, specifier.node.local)));
|
buildExportsFrom(
|
||||||
|
t.stringLiteral(specifier.node.exported.name),
|
||||||
|
t.memberExpression(ref, specifier.node.local),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
nonHoistedExportNames[specifier.node.exported.name] = true;
|
nonHoistedExportNames[specifier.node.exported.name] = true;
|
||||||
}
|
}
|
||||||
@ -372,16 +429,28 @@ export default function () {
|
|||||||
} else {
|
} else {
|
||||||
for (const specifier of specifiers) {
|
for (const specifier of specifiers) {
|
||||||
if (specifier.isExportSpecifier()) {
|
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;
|
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);
|
path.replaceWithMultiple(nodes);
|
||||||
} else if (path.isExportAllDeclaration()) {
|
} else if (path.isExportAllDeclaration()) {
|
||||||
const exportNode = buildExportAll({
|
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;
|
exportNode.loc = path.node.loc;
|
||||||
topNodes.push(exportNode);
|
topNodes.push(exportNode);
|
||||||
@ -407,8 +476,8 @@ export default function () {
|
|||||||
specifier.local,
|
specifier.local,
|
||||||
t.callExpression(
|
t.callExpression(
|
||||||
this.addHelper("interopRequireWildcard"),
|
this.addHelper("interopRequireWildcard"),
|
||||||
[uid]
|
[uid],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -420,7 +489,10 @@ export default function () {
|
|||||||
}
|
}
|
||||||
wildcard = specifier.local;
|
wildcard = specifier.local;
|
||||||
} else if (t.isImportDefaultSpecifier(specifier)) {
|
} 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) {
|
if (wildcard) {
|
||||||
target = wildcard;
|
target = wildcard;
|
||||||
} else if (!noInterop) {
|
} else if (!noInterop) {
|
||||||
target = wildcard = path.scope.generateUidIdentifier(uid.name);
|
target = wildcard = path.scope.generateUidIdentifier(
|
||||||
|
uid.name,
|
||||||
|
);
|
||||||
const varDecl = t.variableDeclaration("var", [
|
const varDecl = t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(
|
t.variableDeclarator(
|
||||||
target,
|
target,
|
||||||
t.callExpression(
|
t.callExpression(
|
||||||
this.addHelper("interopRequireDefault"),
|
this.addHelper("interopRequireDefault"),
|
||||||
[uid]
|
[uid],
|
||||||
)
|
),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -449,8 +523,10 @@ export default function () {
|
|||||||
topNodes.push(varDecl);
|
topNodes.push(varDecl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remaps[specifier.local.name] = t.memberExpression(target,
|
remaps[specifier.local.name] = t.memberExpression(
|
||||||
t.cloneWithoutLoc(specifier.imported));
|
target,
|
||||||
|
t.cloneWithoutLoc(specifier.imported),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -462,25 +538,29 @@ export default function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasImports && Object.keys(nonHoistedExportNames).length) {
|
if (hasImports && Object.keys(nonHoistedExportNames).length) {
|
||||||
|
|
||||||
// avoid creating too long of export assignment to prevent stack overflow
|
// avoid creating too long of export assignment to prevent stack overflow
|
||||||
const maxHoistedExportsNodeAssignmentLength = 100;
|
const maxHoistedExportsNodeAssignmentLength = 100;
|
||||||
const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames);
|
const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames);
|
||||||
|
|
||||||
for (
|
for (
|
||||||
let currentExportsNodeAssignmentLength = 0;
|
let currentExportsNodeAssignmentLength = 0;
|
||||||
currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length;
|
currentExportsNodeAssignmentLength <
|
||||||
|
nonHoistedExportNamesArr.length;
|
||||||
currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength
|
currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength
|
||||||
) {
|
) {
|
||||||
const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice(
|
const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice(
|
||||||
currentExportsNodeAssignmentLength,
|
currentExportsNodeAssignmentLength,
|
||||||
currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength);
|
currentExportsNodeAssignmentLength +
|
||||||
|
maxHoistedExportsNodeAssignmentLength,
|
||||||
|
);
|
||||||
|
|
||||||
let hoistedExportsNode = t.identifier("undefined");
|
let hoistedExportsNode = t.identifier("undefined");
|
||||||
|
|
||||||
nonHoistedExportNamesChunk.forEach(function(name) {
|
nonHoistedExportNamesChunk.forEach(function(name) {
|
||||||
hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode)
|
hoistedExportsNode = buildExportsAssignment(
|
||||||
.expression;
|
t.identifier(name),
|
||||||
|
hoistedExportsNode,
|
||||||
|
).expression;
|
||||||
});
|
});
|
||||||
|
|
||||||
const node = t.expressionStatement(hoistedExportsNode);
|
const node = t.expressionStatement(hoistedExportsNode);
|
||||||
@ -493,7 +573,9 @@ export default function () {
|
|||||||
// add __esModule declaration if this file has any exports
|
// add __esModule declaration if this file has any exports
|
||||||
if (hasExports && !strict) {
|
if (hasExports && !strict) {
|
||||||
let buildTemplate = buildExportsModuleDeclaration;
|
let buildTemplate = buildExportsModuleDeclaration;
|
||||||
if (this.opts.loose) buildTemplate = buildLooseExportsModuleDeclaration;
|
if (this.opts.loose) {
|
||||||
|
buildTemplate = buildLooseExportsModuleDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
const declar = buildTemplate();
|
const declar = buildTemplate();
|
||||||
declar._blockHoist = 3;
|
declar._blockHoist = 3;
|
||||||
@ -506,7 +588,7 @@ export default function () {
|
|||||||
remaps,
|
remaps,
|
||||||
scope,
|
scope,
|
||||||
exports,
|
exports,
|
||||||
requeueInParent: (newPath) => path.requeue(newPath),
|
requeueInParent: newPath => path.requeue(newPath),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,7 +3,7 @@ const babel = require("babel-core");
|
|||||||
const vm = require("vm");
|
const vm = require("vm");
|
||||||
|
|
||||||
test("Re-export doesn't overwrite __esModule flag", function() {
|
test("Re-export doesn't overwrite __esModule flag", function() {
|
||||||
let code = "export * from \"./dep\";";
|
let code = 'export * from "./dep";';
|
||||||
const depStub = {
|
const depStub = {
|
||||||
__esModule: false,
|
__esModule: false,
|
||||||
};
|
};
|
||||||
@ -20,10 +20,8 @@ test("Re-export doesn't overwrite __esModule flag", function () {
|
|||||||
context.exports = context.module.exports;
|
context.exports = context.module.exports;
|
||||||
|
|
||||||
code = babel.transform(code, {
|
code = babel.transform(code, {
|
||||||
"plugins": [
|
plugins: [[require("../"), { loose: true }]],
|
||||||
[require("../"), { loose: true }],
|
ast: false,
|
||||||
],
|
|
||||||
"ast": false,
|
|
||||||
}).code;
|
}).code;
|
||||||
|
|
||||||
vm.runInNewContext(code, context);
|
vm.runInNewContext(code, context);
|
||||||
@ -32,6 +30,6 @@ test("Re-export doesn't overwrite __esModule flag", function () {
|
|||||||
assert.equal(
|
assert.equal(
|
||||||
context.exports.__esModule,
|
context.exports.__esModule,
|
||||||
true,
|
true,
|
||||||
"Expected exports.__esModule === true"
|
"Expected exports.__esModule === true",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -20,7 +20,6 @@ const buildExportAll = template(`
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|
||||||
const TYPE_IMPORT = "Import";
|
const TYPE_IMPORT = "Import";
|
||||||
|
|
||||||
export default function({ types: t }) {
|
export default function({ types: t }) {
|
||||||
@ -49,20 +48,22 @@ export default function ({ types: t }) {
|
|||||||
// in order to ensure the same update expression value
|
// in order to ensure the same update expression value
|
||||||
let isPostUpdateExpression = path.isUpdateExpression() && !node.prefix;
|
let isPostUpdateExpression = path.isUpdateExpression() && !node.prefix;
|
||||||
if (isPostUpdateExpression) {
|
if (isPostUpdateExpression) {
|
||||||
if (node.operator === "++")
|
if (node.operator === "++") {
|
||||||
{node = t.binaryExpression("+", node.argument, t.numericLiteral(1));}
|
node = t.binaryExpression("+", node.argument, t.numericLiteral(1));
|
||||||
else if (node.operator === "--")
|
} else if (node.operator === "--") {
|
||||||
{node = t.binaryExpression("-", node.argument, t.numericLiteral(1));}
|
node = t.binaryExpression("-", node.argument, t.numericLiteral(1));
|
||||||
else
|
} else {
|
||||||
{isPostUpdateExpression = false;}
|
isPostUpdateExpression = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const exportedName of exportedNames) {
|
for (const exportedName of exportedNames) {
|
||||||
node = this.buildCall(exportedName, node).expression;
|
node = this.buildCall(exportedName, node).expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPostUpdateExpression)
|
if (isPostUpdateExpression) {
|
||||||
{node = t.sequenceExpression([node, path.node]);}
|
node = t.sequenceExpression([node, path.node]);
|
||||||
|
}
|
||||||
|
|
||||||
path.replaceWith(node);
|
path.replaceWith(node);
|
||||||
},
|
},
|
||||||
@ -70,18 +71,26 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
|
|
||||||
CallExpression(path, state) {
|
CallExpression(path, state) {
|
||||||
if (path.node.callee.type === TYPE_IMPORT) {
|
if (path.node.callee.type === TYPE_IMPORT) {
|
||||||
const contextIdent = state.contextIdent;
|
const contextIdent = state.contextIdent;
|
||||||
path.replaceWith(t.callExpression(t.memberExpression(contextIdent, t.identifier("import")),
|
path.replaceWith(
|
||||||
path.node.arguments));
|
t.callExpression(
|
||||||
|
t.memberExpression(contextIdent, t.identifier("import")),
|
||||||
|
path.node.arguments,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ReferencedIdentifier(path, state) {
|
ReferencedIdentifier(path, state) {
|
||||||
if (path.node.name == "__moduleName" && !path.scope.hasBinding("__moduleName")) {
|
if (
|
||||||
path.replaceWith(t.memberExpression(state.contextIdent, t.identifier("id")));
|
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) {
|
if (!module) {
|
||||||
modules.push(module = { key: source, imports: [], exports: [] });
|
modules.push(
|
||||||
|
(module = { key: source, imports: [], exports: [] }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
module[key] = module[key].concat(specifiers);
|
module[key] = module[key].concat(specifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildExportCall(name, val) {
|
function buildExportCall(name, val) {
|
||||||
return t.expressionStatement(
|
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();
|
path.remove();
|
||||||
} else if (path.isExportDefaultDeclaration()) {
|
} else if (path.isExportDefaultDeclaration()) {
|
||||||
const declar = path.get("declaration");
|
const declar = path.get("declaration");
|
||||||
if (declar.isClassDeclaration() || declar.isFunctionDeclaration()) {
|
if (
|
||||||
|
declar.isClassDeclaration() ||
|
||||||
|
declar.isFunctionDeclaration()
|
||||||
|
) {
|
||||||
const id = declar.node.id;
|
const id = declar.node.id;
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
|
|
||||||
@ -163,7 +177,9 @@ export default function ({ types: t }) {
|
|||||||
nodes.push(buildExportCall("default", id));
|
nodes.push(buildExportCall("default", id));
|
||||||
addExportName(id.name, "default");
|
addExportName(id.name, "default");
|
||||||
} else {
|
} else {
|
||||||
nodes.push(buildExportCall("default", t.toExpression(declar.node)));
|
nodes.push(
|
||||||
|
buildExportCall("default", t.toExpression(declar.node)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canHoist || declar.isClassDeclaration()) {
|
if (!canHoist || declar.isClassDeclaration()) {
|
||||||
@ -212,8 +228,16 @@ export default function ({ types: t }) {
|
|||||||
const nodes = [];
|
const nodes = [];
|
||||||
|
|
||||||
for (const specifier of specifiers) {
|
for (const specifier of specifiers) {
|
||||||
nodes.push(buildExportCall(specifier.exported.name, specifier.local));
|
nodes.push(
|
||||||
addExportName(specifier.local.name, specifier.exported.name);
|
buildExportCall(
|
||||||
|
specifier.exported.name,
|
||||||
|
specifier.local,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
addExportName(
|
||||||
|
specifier.local.name,
|
||||||
|
specifier.exported.name,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
path.replaceWithMultiple(nodes);
|
path.replaceWithMultiple(nodes);
|
||||||
@ -229,59 +253,97 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
for (let specifier of specifiers.imports) {
|
for (let specifier of specifiers.imports) {
|
||||||
if (t.isImportNamespaceSpecifier(specifier)) {
|
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)) {
|
} 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)) {
|
if (t.isImportSpecifier(specifier)) {
|
||||||
setterBody.push(t.expressionStatement(t.assignmentExpression("=", specifier.local,
|
setterBody.push(
|
||||||
t.memberExpression(target, specifier.imported))));
|
t.expressionStatement(
|
||||||
|
t.assignmentExpression(
|
||||||
|
"=",
|
||||||
|
specifier.local,
|
||||||
|
t.memberExpression(target, specifier.imported),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specifiers.exports.length) {
|
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([])),
|
t.variableDeclarator(exportObjRef, t.objectExpression([])),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
for (const node of specifiers.exports) {
|
for (const node of specifiers.exports) {
|
||||||
if (t.isExportAllDeclaration(node)) {
|
if (t.isExportAllDeclaration(node)) {
|
||||||
setterBody.push(buildExportAll({
|
setterBody.push(
|
||||||
|
buildExportAll({
|
||||||
KEY: path.scope.generateUidIdentifier("key"),
|
KEY: path.scope.generateUidIdentifier("key"),
|
||||||
EXPORT_OBJ: exportObjRef,
|
EXPORT_OBJ: exportObjRef,
|
||||||
TARGET: target,
|
TARGET: target,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
} else if (t.isExportSpecifier(node)) {
|
} else if (t.isExportSpecifier(node)) {
|
||||||
setterBody.push(t.expressionStatement(
|
setterBody.push(
|
||||||
t.assignmentExpression("=", t.memberExpression(exportObjRef, node.exported),
|
t.expressionStatement(
|
||||||
t.memberExpression(target, node.local))
|
t.assignmentExpression(
|
||||||
));
|
"=",
|
||||||
|
t.memberExpression(exportObjRef, node.exported),
|
||||||
|
t.memberExpression(target, node.local),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setterBody.push(t.expressionStatement(t.callExpression(exportIdent, [exportObjRef])));
|
setterBody.push(
|
||||||
|
t.expressionStatement(
|
||||||
|
t.callExpression(exportIdent, [exportObjRef]),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sources.push(t.stringLiteral(specifiers.key));
|
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();
|
let moduleName = this.getModuleName();
|
||||||
if (moduleName) moduleName = t.stringLiteral(moduleName);
|
if (moduleName) moduleName = t.stringLiteral(moduleName);
|
||||||
|
|
||||||
if (canHoist) {
|
if (canHoist) {
|
||||||
hoistVariables(path, (id) => variableIds.push(id));
|
hoistVariables(path, id => variableIds.push(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variableIds.length) {
|
if (variableIds.length) {
|
||||||
beforeBody.unshift(t.variableDeclaration("var",
|
beforeBody.unshift(
|
||||||
variableIds.map((id) => t.variableDeclarator(id))));
|
t.variableDeclaration(
|
||||||
|
"var",
|
||||||
|
variableIds.map(id => t.variableDeclarator(id)),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
path.traverse(reassignmentVisitor, {
|
path.traverse(reassignmentVisitor, {
|
||||||
@ -297,7 +359,9 @@ export default function ({ types: t }) {
|
|||||||
path.node.body = [
|
path.node.body = [
|
||||||
buildTemplate({
|
buildTemplate({
|
||||||
SYSTEM_REGISTER: t.memberExpression(
|
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,
|
BEFORE_BODY: beforeBody,
|
||||||
MODULE_NAME: moduleName,
|
MODULE_NAME: moduleName,
|
||||||
SETTERS: setters,
|
SETTERS: setters,
|
||||||
|
|||||||
@ -59,7 +59,7 @@ export default function ({ types: t }) {
|
|||||||
const func = call.arguments[1];
|
const func = call.arguments[1];
|
||||||
const browserGlobals = state.opts.globals || {};
|
const browserGlobals = state.opts.globals || {};
|
||||||
|
|
||||||
const commonArgs = amdArgs.elements.map((arg) => {
|
const commonArgs = amdArgs.elements.map(arg => {
|
||||||
if (arg.value === "module" || arg.value === "exports") {
|
if (arg.value === "module" || arg.value === "exports") {
|
||||||
return t.identifier(arg.value);
|
return t.identifier(arg.value);
|
||||||
} else {
|
} 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") {
|
if (arg.value === "module") {
|
||||||
return t.identifier("mod");
|
return t.identifier("mod");
|
||||||
} else if (arg.value === "exports") {
|
} else if (arg.value === "exports") {
|
||||||
return t.memberExpression(t.identifier("mod"), t.identifier("exports"));
|
return t.memberExpression(
|
||||||
|
t.identifier("mod"),
|
||||||
|
t.identifier("exports"),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
let memberExpression;
|
let memberExpression;
|
||||||
|
|
||||||
if (state.opts.exactGlobals) {
|
if (state.opts.exactGlobals) {
|
||||||
const globalRef = browserGlobals[arg.value];
|
const globalRef = browserGlobals[arg.value];
|
||||||
if (globalRef) {
|
if (globalRef) {
|
||||||
memberExpression = globalRef.split(".").reduce(
|
memberExpression = globalRef
|
||||||
(accum, curr) => t.memberExpression(accum, t.identifier(curr)), t.identifier("global")
|
.split(".")
|
||||||
|
.reduce(
|
||||||
|
(accum, curr) =>
|
||||||
|
t.memberExpression(accum, t.identifier(curr)),
|
||||||
|
t.identifier("global"),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
memberExpression = t.memberExpression(
|
memberExpression = t.memberExpression(
|
||||||
t.identifier("global"), t.identifier(t.toIdentifier(arg.value))
|
t.identifier("global"),
|
||||||
|
t.identifier(t.toIdentifier(arg.value)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const requireName = basename(arg.value, extname(arg.value));
|
const requireName = basename(arg.value, extname(arg.value));
|
||||||
const globalName = browserGlobals[requireName] || requireName;
|
const globalName = browserGlobals[requireName] || requireName;
|
||||||
memberExpression = t.memberExpression(
|
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 :
|
const moduleNameOrBasename = moduleName
|
||||||
basename(this.file.opts.filename, extname(this.file.opts.filename));
|
? moduleName.value
|
||||||
|
: basename(
|
||||||
|
this.file.opts.filename,
|
||||||
|
extname(this.file.opts.filename),
|
||||||
|
);
|
||||||
let globalToAssign = t.memberExpression(
|
let globalToAssign = t.memberExpression(
|
||||||
t.identifier("global"), t.identifier(t.toIdentifier(moduleNameOrBasename))
|
t.identifier("global"),
|
||||||
|
t.identifier(t.toIdentifier(moduleNameOrBasename)),
|
||||||
);
|
);
|
||||||
let prerequisiteAssignments = null;
|
let prerequisiteAssignments = null;
|
||||||
|
|
||||||
@ -113,7 +127,9 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
const members = globalName.split(".");
|
const members = globalName.split(".");
|
||||||
globalToAssign = members.slice(1).reduce((accum, curr) => {
|
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));
|
return t.memberExpression(accum, t.identifier(curr));
|
||||||
}, t.memberExpression(t.identifier("global"), t.identifier(members[0])));
|
}, t.memberExpression(t.identifier("global"), t.identifier(members[0])));
|
||||||
}
|
}
|
||||||
@ -125,13 +141,15 @@ export default function ({ types: t }) {
|
|||||||
GLOBAL_TO_ASSIGN: globalToAssign,
|
GLOBAL_TO_ASSIGN: globalToAssign,
|
||||||
});
|
});
|
||||||
|
|
||||||
last.replaceWith(buildWrapper({
|
last.replaceWith(
|
||||||
|
buildWrapper({
|
||||||
MODULE_NAME: moduleName,
|
MODULE_NAME: moduleName,
|
||||||
AMD_ARGUMENTS: amdArgs,
|
AMD_ARGUMENTS: amdArgs,
|
||||||
COMMON_ARGUMENTS: commonArgs,
|
COMMON_ARGUMENTS: commonArgs,
|
||||||
GLOBAL_EXPORT: globalExport,
|
GLOBAL_EXPORT: globalExport,
|
||||||
FUNC: func,
|
FUNC: func,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -18,15 +18,22 @@ export default function ({ types: t }) {
|
|||||||
visitor: {
|
visitor: {
|
||||||
ObjectExpression(path, state) {
|
ObjectExpression(path, state) {
|
||||||
let objectRef;
|
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;
|
if (!propertyPath.isMethod()) return;
|
||||||
|
|
||||||
const propPaths: Array = path.get("properties");
|
const propPaths: Array = path.get("properties");
|
||||||
for (let propPath of propPaths) {
|
for (let propPath of propPaths) {
|
||||||
if (propPath.isObjectProperty()) propPath = propPath.get("value");
|
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() {
|
export default function() {
|
||||||
return {
|
return {
|
||||||
visitor: visitors.merge([{
|
visitor: visitors.merge([
|
||||||
|
{
|
||||||
ArrowFunctionExpression(path) {
|
ArrowFunctionExpression(path) {
|
||||||
// In some conversion cases, it may have already been converted to a function while this callback
|
// In some conversion cases, it may have already been converted to a function while this callback
|
||||||
// was queued up.
|
// 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 })) {
|
if (parentPath.isMemberExpression({ object: node })) {
|
||||||
const grandparentPath = parentPath.parentPath;
|
const grandparentPath = parentPath.parentPath;
|
||||||
|
|
||||||
const argsOptEligible = !state.deopted && !(
|
const argsOptEligible =
|
||||||
// ex: `args[0] = "whatever"`
|
!state.deopted &&
|
||||||
|
!// ex: `args[0] = "whatever"`
|
||||||
(
|
(
|
||||||
grandparentPath.isAssignmentExpression() &&
|
(grandparentPath.isAssignmentExpression() &&
|
||||||
parentPath.node === grandparentPath.node.left
|
parentPath.node === grandparentPath.node.left) ||
|
||||||
) ||
|
|
||||||
|
|
||||||
// ex: `[args[0]] = ["whatever"]`
|
// ex: `[args[0]] = ["whatever"]`
|
||||||
grandparentPath.isLVal() ||
|
grandparentPath.isLVal() ||
|
||||||
|
|
||||||
// ex: `for (rest[0] in this)`
|
// ex: `for (rest[0] in this)`
|
||||||
// ex: `for (rest[0] of this)`
|
// ex: `for (rest[0] of this)`
|
||||||
grandparentPath.isForXStatement() ||
|
grandparentPath.isForXStatement() ||
|
||||||
|
|
||||||
// ex: `++args[0]`
|
// ex: `++args[0]`
|
||||||
// ex: `args[0]--`
|
// ex: `args[0]--`
|
||||||
grandparentPath.isUpdateExpression() ||
|
grandparentPath.isUpdateExpression() ||
|
||||||
|
|
||||||
// ex: `delete args[0]`
|
// ex: `delete args[0]`
|
||||||
grandparentPath.isUnaryExpression({ operator: "delete" }) ||
|
grandparentPath.isUnaryExpression({ operator: "delete" }) ||
|
||||||
|
|
||||||
// ex: `args[0]()`
|
// ex: `args[0]()`
|
||||||
// ex: `new args[0]()`
|
// ex: `new args[0]()`
|
||||||
// ex: `new args[0]`
|
// ex: `new args[0]`
|
||||||
(
|
((grandparentPath.isCallExpression() ||
|
||||||
(
|
grandparentPath.isNewExpression()) &&
|
||||||
grandparentPath.isCallExpression() ||
|
parentPath.node === grandparentPath.node.callee)
|
||||||
grandparentPath.isNewExpression()
|
|
||||||
) &&
|
|
||||||
parentPath.node === grandparentPath.node.callee
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (argsOptEligible) {
|
if (argsOptEligible) {
|
||||||
@ -127,9 +118,8 @@ const memberExpressionOptimisationVisitor = {
|
|||||||
state.candidates.push({ cause: "indexGetter", path });
|
state.candidates.push({ cause: "indexGetter", path });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else if (parentPath.node.property.name === "length") {
|
||||||
// args.length
|
// args.length
|
||||||
else if (parentPath.node.property.name === "length") {
|
|
||||||
state.candidates.push({ cause: "lengthGetter", path });
|
state.candidates.push({ cause: "lengthGetter", path });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -177,32 +167,42 @@ function optimiseIndexGetter(path, argsId, offset) {
|
|||||||
// Avoid unnecessary '+ 0'
|
// Avoid unnecessary '+ 0'
|
||||||
index = path.parent.property;
|
index = path.parent.property;
|
||||||
} else {
|
} else {
|
||||||
index = t.binaryExpression("+", path.parent.property, t.numericLiteral(offset));
|
index = t.binaryExpression(
|
||||||
|
"+",
|
||||||
|
path.parent.property,
|
||||||
|
t.numericLiteral(offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { scope } = path;
|
const { scope } = path;
|
||||||
if (!scope.isPure(index)) {
|
if (!scope.isPure(index)) {
|
||||||
const temp = scope.generateUidIdentifierBasedOnNode(index);
|
const temp = scope.generateUidIdentifierBasedOnNode(index);
|
||||||
scope.push({ id: temp, kind: "var" });
|
scope.push({ id: temp, kind: "var" });
|
||||||
path.parentPath.replaceWith(restIndexImpure({
|
path.parentPath.replaceWith(
|
||||||
|
restIndexImpure({
|
||||||
ARGUMENTS: argsId,
|
ARGUMENTS: argsId,
|
||||||
INDEX: index,
|
INDEX: index,
|
||||||
REF: temp,
|
REF: temp,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
path.parentPath.replaceWith(restIndex({
|
path.parentPath.replaceWith(
|
||||||
|
restIndex({
|
||||||
ARGUMENTS: argsId,
|
ARGUMENTS: argsId,
|
||||||
INDEX: index,
|
INDEX: index,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function optimiseLengthGetter(path, argsId, offset) {
|
function optimiseLengthGetter(path, argsId, offset) {
|
||||||
if (offset) {
|
if (offset) {
|
||||||
path.parentPath.replaceWith(restLength({
|
path.parentPath.replaceWith(
|
||||||
|
restLength({
|
||||||
ARGUMENTS: argsId,
|
ARGUMENTS: argsId,
|
||||||
OFFSET: t.numericLiteral(offset),
|
OFFSET: t.numericLiteral(offset),
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
path.replaceWith(argsId);
|
path.replaceWith(argsId);
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ export const visitor = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.references = state.references.concat(
|
state.references = state.references.concat(
|
||||||
state.candidates.map(({ path }) => path)
|
state.candidates.map(({ path }) => path),
|
||||||
);
|
);
|
||||||
|
|
||||||
const start = t.numericLiteral(node.params.length);
|
const start = t.numericLiteral(node.params.length);
|
||||||
@ -290,7 +290,7 @@ export const visitor = {
|
|||||||
arrLen = t.conditionalExpression(
|
arrLen = t.conditionalExpression(
|
||||||
t.binaryExpression(">", len, start),
|
t.binaryExpression(">", len, start),
|
||||||
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
|
// perform allocation at the lowest common ancestor of all references
|
||||||
loop._blockHoist = 1;
|
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
|
// don't perform the allocation inside a loop
|
||||||
target.findParent((path) => {
|
target.findParent(path => {
|
||||||
if (path.isLoop()) {
|
if (path.isLoop()) {
|
||||||
target = path;
|
target = path;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -6,14 +6,16 @@ export default function () {
|
|||||||
ObjectMethod(path) {
|
ObjectMethod(path) {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
if (node.kind === "method") {
|
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;
|
func.returnType = node.returnType;
|
||||||
|
|
||||||
path.replaceWith(t.objectProperty(
|
path.replaceWith(t.objectProperty(node.key, func, node.computed));
|
||||||
node.key,
|
|
||||||
func,
|
|
||||||
node.computed
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
export default function({ types: t }) {
|
export default function({ types: t }) {
|
||||||
function getSpreadLiteral(spread, scope, state) {
|
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;
|
return spread.argument;
|
||||||
} else {
|
} else {
|
||||||
return scope.toArray(spread.argument, true);
|
return scope.toArray(spread.argument, true);
|
||||||
@ -55,7 +58,12 @@ export default function ({ types: t }) {
|
|||||||
first = t.arrayExpression([]);
|
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) {
|
CallExpression(path, state) {
|
||||||
@ -80,7 +88,12 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
const first = nodes.shift();
|
const first = nodes.shift();
|
||||||
if (nodes.length) {
|
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 {
|
} else {
|
||||||
node.arguments.push(first);
|
node.arguments.push(first);
|
||||||
}
|
}
|
||||||
@ -116,10 +129,13 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
const context = t.arrayExpression([t.nullLiteral()]);
|
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.callExpression(
|
||||||
t.memberExpression(
|
t.memberExpression(
|
||||||
t.memberExpression(
|
t.memberExpression(
|
||||||
@ -127,14 +143,15 @@ export default function ({ types: t }) {
|
|||||||
t.identifier("Function"),
|
t.identifier("Function"),
|
||||||
t.identifier("prototype"),
|
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;
|
const { node } = path;
|
||||||
if (!regex.is(node, "y")) return;
|
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.pattern),
|
||||||
t.stringLiteral(node.flags),
|
t.stringLiteral(node.flags),
|
||||||
]));
|
]),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
export default function({ types: t }) {
|
export default function({ types: t }) {
|
||||||
|
|
||||||
function buildConcatCallExressions(items) {
|
function buildConcatCallExressions(items) {
|
||||||
let avail = true;
|
let avail = true;
|
||||||
return items.reduce(function(left, right) {
|
return items.reduce(function(left, right) {
|
||||||
@ -15,7 +14,7 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
return t.callExpression(
|
return t.callExpression(
|
||||||
t.memberExpression(left, t.identifier("concat")),
|
t.memberExpression(left, t.identifier("concat")),
|
||||||
[right]
|
[right],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -23,7 +22,6 @@ export default function ({ types: t }) {
|
|||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
TaggedTemplateExpression(path, state) {
|
TaggedTemplateExpression(path, state) {
|
||||||
|
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
const { quasi } = node;
|
const { quasi } = node;
|
||||||
|
|
||||||
@ -32,7 +30,8 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
for (const elem of (quasi.quasis: Array)) {
|
for (const elem of (quasi.quasis: Array)) {
|
||||||
const { raw, cooked } = elem.value;
|
const { raw, cooked } = elem.value;
|
||||||
const value = cooked == null
|
const value =
|
||||||
|
cooked == null
|
||||||
? path.scope.buildUndefinedNode()
|
? path.scope.buildUndefinedNode()
|
||||||
: t.stringLiteral(cooked);
|
: t.stringLiteral(cooked);
|
||||||
|
|
||||||
@ -46,7 +45,7 @@ export default function ({ types: t }) {
|
|||||||
const templateObject = state.file.addTemplateObject(
|
const templateObject = state.file.addTemplateObject(
|
||||||
templateName,
|
templateName,
|
||||||
t.arrayExpression(strings),
|
t.arrayExpression(strings),
|
||||||
t.arrayExpression(raws)
|
t.arrayExpression(raws),
|
||||||
);
|
);
|
||||||
|
|
||||||
const args = [templateObject].concat(quasi.expressions);
|
const args = [templateObject].concat(quasi.expressions);
|
||||||
@ -75,7 +74,8 @@ export default function ({ types: t }) {
|
|||||||
|
|
||||||
// since `+` is left-to-right associative
|
// since `+` is left-to-right associative
|
||||||
// ensure the first node is a string if first/second isn't
|
// 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) {
|
if (!t.isStringLiteral(nodes[0]) && considerSecondNode) {
|
||||||
nodes.unshift(t.stringLiteral(""));
|
nodes.unshift(t.stringLiteral(""));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export default function ({ types: t }) {
|
|||||||
UnaryExpression(path) {
|
UnaryExpression(path) {
|
||||||
const { node, parent } = path;
|
const { node, parent } = path;
|
||||||
if (node[IGNORE]) return;
|
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 (
|
if (
|
||||||
path.parentPath.isBinaryExpression() &&
|
path.parentPath.isBinaryExpression() &&
|
||||||
@ -24,7 +24,8 @@ export default function ({ types: t }) {
|
|||||||
// need to handle symbols
|
// need to handle symbols
|
||||||
const opposite = path.getOpposite();
|
const opposite = path.getOpposite();
|
||||||
if (
|
if (
|
||||||
opposite.isLiteral() && opposite.node.value !== "symbol" &&
|
opposite.isLiteral() &&
|
||||||
|
opposite.node.value !== "symbol" &&
|
||||||
opposite.node.value !== "object"
|
opposite.node.value !== "object"
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
@ -32,16 +33,20 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.operator === "typeof") {
|
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()) {
|
if (path.get("argument").isIdentifier()) {
|
||||||
const undefLiteral = t.stringLiteral("undefined");
|
const undefLiteral = t.stringLiteral("undefined");
|
||||||
const unary = t.unaryExpression("typeof", node.argument);
|
const unary = t.unaryExpression("typeof", node.argument);
|
||||||
unary[IGNORE] = true;
|
unary[IGNORE] = true;
|
||||||
path.replaceWith(t.conditionalExpression(
|
path.replaceWith(
|
||||||
|
t.conditionalExpression(
|
||||||
t.binaryExpression("===", unary, undefLiteral),
|
t.binaryExpression("===", unary, undefLiteral),
|
||||||
undefLiteral,
|
undefLiteral,
|
||||||
call
|
call,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
path.replaceWith(call);
|
path.replaceWith(call);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,11 @@ export default function ({ types: t }) {
|
|||||||
MemberExpression: {
|
MemberExpression: {
|
||||||
exit({ node }) {
|
exit({ node }) {
|
||||||
const prop = node.property;
|
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"]
|
// foo.default -> foo["default"]
|
||||||
node.property = t.stringLiteral(prop.name);
|
node.property = t.stringLiteral(prop.name);
|
||||||
node.computed = true;
|
node.computed = true;
|
||||||
|
|||||||
@ -4,7 +4,11 @@ export default function ({ types: t }) {
|
|||||||
ObjectProperty: {
|
ObjectProperty: {
|
||||||
exit({ node }) {
|
exit({ node }) {
|
||||||
const key = node.key;
|
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"
|
// default: "bar" -> "default": "bar"
|
||||||
node.key = t.stringLiteral(key.name);
|
node.key = t.stringLiteral(key.name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,15 @@ export default function ({ types: t }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
path.replaceWith(t.callExpression(
|
path.replaceWith(
|
||||||
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
|
t.callExpression(
|
||||||
[node, defineMap.toDefineObject(mutatorMap)]
|
t.memberExpression(
|
||||||
));
|
t.identifier("Object"),
|
||||||
|
t.identifier("defineProperties"),
|
||||||
|
),
|
||||||
|
[node, defineMap.toDefineObject(mutatorMap)],
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,10 @@ export default function ({ parse, traverse }) {
|
|||||||
return {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
CallExpression(path) {
|
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();
|
const evaluate = path.get("arguments")[0].evaluate();
|
||||||
if (!evaluate.confident) return;
|
if (!evaluate.confident) return;
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,10 @@ export default function ({ types: t }) {
|
|||||||
operator: "**",
|
operator: "**",
|
||||||
|
|
||||||
build(left, right) {
|
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