Compare commits

...

42 Commits

Author SHA1 Message Date
Henry Zhu
7d798952d2 v7.0.0-beta.36 2017-12-25 14:04:08 -05:00
Joe Lim
ed2b88830e Remove extraneous console output when running preset-env tests (#6576) 2017-12-25 13:47:19 -05:00
Bogdan Chadkin
d25918aa5d Fix generation flow unnamed computed property (#7095) 2017-12-22 12:55:40 -06:00
Artem Yavorsky
035286a810 [preset-env] Move all defaults to the separate module (#7084)
* preset-env: Move all defaults to the separate module.

* preset-env: Add test cases for defaults.
2017-12-22 10:42:06 -05:00
Logan Smyth
c9a00fbae8 Merge pull request #7090 from loganfsmyth/chain-processing-rewrite
Refactor config processing more
2017-12-21 19:57:07 -08:00
Logan Smyth
758fd0369c Rewrite config chain loading to build chain recursively to keep caching readable. 2017-12-21 19:06:36 -08:00
Logan Smyth
7b861796cf Centralize validation logic in common folder. 2017-12-21 14:45:19 -08:00
Logan Smyth
f9825394a7 Remove unnecessary folder nesting. 2017-12-21 14:45:19 -08:00
Logan Smyth
43e7d1d2cc Use an object instead of a 2-tuple. 2017-12-21 12:31:48 -08:00
Logan Smyth
de63443762 Split babelrc and babelignore searching into two functions. 2017-12-21 12:28:51 -08:00
Andy
6a73f39199 Support parsing export default abstract class {} (#7075) 2017-12-21 16:13:31 +01:00
Azharuddin
2190e10e9a Better error messages when Babel fails to parse import = and export =… (#7079)
* Better error messages when Babel fails to parse import = and export = syntax from typescript when using babel-plugin-transform-typescript

* Fixing Test cases

* Ran make fix and broken looong sentence into smaller

* Slight changes to Messages after review with Nicolo & existentialism

* Removed trailing space
2017-12-21 02:00:36 +02:00
Nicolò Ribaudo
ae3f5b9149 Return the obj in setPrototypeOf fallback (#7080) 2017-12-20 22:48:10 +01:00
Nicolò Ribaudo
0c885b3200 Add support for extending builtins (#7020) 2017-12-20 14:46:00 -05:00
Artem Yavorsky
148fe7d3ff Add proposal-async-generator-functions to babel-standalone (#7073) 2017-12-20 20:37:16 +01:00
Henry Zhu
cabdf3769d Merge pull request #7065 from babel/dotall-preset-env
Add dot-all regex support to preset-env and standalone
2017-12-19 20:45:18 -05:00
Logan Smyth
1178799f07 Remove the LoadedFile class. 2017-12-19 15:36:54 -08:00
Logan Smyth
b2f1d01965 Add type annotations to utility file. 2017-12-19 15:36:19 -08:00
Logan Smyth
4f53496546 Drop the OptionManager class in favor of function. 2017-12-19 14:19:37 -08:00
Logan Smyth
1312a30d54 Perform normalization in the chain building process. 2017-12-19 14:19:37 -08:00
Logan Smyth
4afbc02476 Move descriptor merging into config chain processing. 2017-12-19 14:19:37 -08:00
Brian Ng
080c7f1e2d Clean up logPlugin 2017-12-19 14:57:19 -06:00
Brian Ng
3cea9f412a Add dot-all regex support to preset-env and standalone 2017-12-19 11:39:00 -06:00
Brian Ng
cd10ea03b4 Fix bug with debug output and unreleased versions 2017-12-19 11:38:59 -06:00
Mathias Bynens
5f8a1a2613 Fix unicode-property-regex installation instructions (#7064) 2017-12-19 11:27:26 -06:00
Mathias Bynens
44da8201a5 Import babel-plugin-transform-dotall-regex (#7059)
Original: https://github.com/mathiasbynens/babel-plugin-transform-dotall-regex

Moving it into the official Babel repository makes it easier to maintain the transform.
2017-12-19 11:01:59 -05:00
Brian Ng
2b065350b5 Treat import type * as a parser error (#7061) 2017-12-19 10:54:20 -05:00
Nicolò Ribaudo
68476b6ddd Make .insert{Before,After} work by default when the parent is an eport declaration (#7040) 2017-12-19 00:05:29 +01:00
Maaz Syed Adeeb
17b37b5013 Handling babylon parsing errors in a better way (#6961)
* Handling babylon parsing errors in a better way

* Better error messages + Helpful URLs

* Replaced message from babylon completely

* Add importMeta plugin to the map
2017-12-18 15:49:34 -05:00
Bo Lingen
56638e1370 Add pipeline operator plugins to babel-standalone (#6955) 2017-12-18 10:10:20 -06:00
Francisco Ryan Tolmasky I
f0e46772a6 babel-types lists JSXIdentifier as an Expression (#6960)
Currently, Babel is treating JSXIdentifier, JSXMemberExpression, and JSXEmptyExpression as expressions as well, which means Babel will for example incorrectly allow you to place these anywhere an expression is wanted.

Closes #6851.
2017-12-18 09:27:43 -06:00
Mahmut Surekci
398bc43656 Add MIT license to proposal-unicode-property-regex (#7047) 2017-12-18 13:48:30 +01:00
Logan Smyth
44ea9433c0 Merge pull request #6952 from loganfsmyth/commonjs-lazy
Add a 'lazy' options to modules-commonjs
2017-12-17 19:32:51 -08:00
Logan Smyth
53826aaaa0 Expose a 'lazy' option for the CommonJS transform. 2017-12-17 18:42:35 -08:00
Logan Smyth
b900a3e5c2 Consistently return AST nodes. 2017-12-17 18:33:47 -08:00
dnalborczyk
ed4d90b33d expose import.meta syntax parser option as plugin (#7008) 2017-12-16 15:06:23 -06:00
Anthony Bianco
209a598d51 Fix loose option description in transform-modules-commonjs 2017-12-16 14:41:05 -06:00
Nicolò Ribaudo
9a146d01b0 [decorators] Don't transform every AssignmentExpression (#7032) 2017-12-15 16:17:31 -05:00
Rouven Weßling
f2437583ba Bump globals to version 11.1.0 (#7006) 2017-12-15 13:20:22 -05:00
Sven SAULEAU
a24c9f8ed6 Merge pull request #7028 from sophiebits/getLetReferences-n2
Fix O(n^2) getLetReferences – 40% faster on large flat files
2017-12-15 07:59:57 +01:00
Sophie Alpert
6a7223af29 Fix O(n^2) getLetReferences – 40% faster on large flat files
`this.blockPath.get("body")` constructs an array of paths corresponding to each node in `blocks.body` so takes O(n) time if n is that length. We were re-constructing that array on each iteration, so the entire loop was O(n^2).

On files with many statements in a single block (such as Rollup-generated bundles), this takes a large portion of time. In particular, this makes transforming react-dom.development.js about 40% faster. Not that you should be transforming our bundle with Babel.

Test Plan:
Make an HTML file with these three lines and watch it in the Chrome Performance tab to see timings (on my machine: 2.9s before, 1.6s after):

```
<!DOCTYPE html>
<script src="https://unpkg.com/babel-standalone@7.0.0-beta.3/babel.js"></script>
<script type="text/babel" src="https://unpkg.com/react-dom@16.2.0/umd/react-dom.development.js"></script>
```
2017-12-14 21:55:26 -08:00
Diogo Franco
a66845169f Rename misleading identifier
notRegenerator actually _enabled_ transforming regeneratorRuntime references.
2017-12-15 11:20:15 +09:00
334 changed files with 4516 additions and 3164 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-codemod-optional-catch-binding",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Remove unused catch bindings",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-remove-unused-catch-binding",
"license": "MIT",
@@ -9,13 +9,13 @@
"@babel/plugin"
],
"dependencies": {
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.35"
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"lerna": "2.0.0-rc.4",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"changelog": {
"repo": "babel/babel",
"labels": {

View File

@@ -1262,7 +1262,7 @@ declare class BabelNodeTSTypeParameter extends BabelNode {
name?: string;
}
type BabelNodeExpression = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeCallExpression | BabelNodeConditionalExpression | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeObjectExpression | BabelNodeSequenceExpression | BabelNodeThisExpression | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeArrowFunctionExpression | BabelNodeClassExpression | BabelNodeMetaProperty | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeTypeCastExpression | BabelNodeJSXElement | BabelNodeJSXEmptyExpression | BabelNodeJSXIdentifier | BabelNodeJSXMemberExpression | BabelNodeJSXFragment | BabelNodeParenthesizedExpression | BabelNodeAwaitExpression | BabelNodeBindExpression | BabelNodeImport | BabelNodeDoExpression | BabelNodeTSAsExpression | BabelNodeTSTypeAssertion | BabelNodeTSNonNullExpression;
type BabelNodeExpression = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeCallExpression | BabelNodeConditionalExpression | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeObjectExpression | BabelNodeSequenceExpression | BabelNodeThisExpression | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeArrowFunctionExpression | BabelNodeClassExpression | BabelNodeMetaProperty | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeTypeCastExpression | BabelNodeJSXElement | BabelNodeJSXFragment | BabelNodeParenthesizedExpression | BabelNodeAwaitExpression | BabelNodeBindExpression | BabelNodeImport | BabelNodeDoExpression | BabelNodeTSAsExpression | BabelNodeTSTypeAssertion | BabelNodeTSNonNullExpression;
type BabelNodeBinary = BabelNodeBinaryExpression | BabelNodeLogicalExpression;
type BabelNodeScopable = BabelNodeBlockStatement | BabelNodeCatchClause | BabelNodeDoWhileStatement | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeProgram | BabelNodeObjectMethod | BabelNodeSwitchStatement | BabelNodeWhileStatement | BabelNodeArrowFunctionExpression | BabelNodeClassDeclaration | BabelNodeClassExpression | BabelNodeForOfStatement | BabelNodeClassMethod;
type BabelNodeBlockParent = BabelNodeBlockStatement | BabelNodeCatchClause | BabelNodeDoWhileStatement | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeProgram | BabelNodeObjectMethod | BabelNodeSwitchStatement | BabelNodeWhileStatement | BabelNodeArrowFunctionExpression | BabelNodeForOfStatement | BabelNodeClassMethod;

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/cli",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel command line.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -29,11 +29,11 @@
"chokidar": "^1.6.1"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-fixtures": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-fixtures": "7.0.0-beta.36"
},
"bin": {
"babel": "./bin/babel.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/code-frame",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Generate errors that contain a code frame that point to source locations.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/core",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel compiler core.",
"main": "./lib/index.js",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
@@ -23,18 +23,18 @@
"compiler"
],
"browser": {
"./lib/config/loading/files/index.js": "./lib/config/loading/files/index-browser.js",
"./lib/config/files/index.js": "./lib/config/files/index-browser.js",
"./lib/transform-file.js": "./lib/transform-file-browser.js",
"./lib/transform-file-sync.js": "./lib/transform-file-sync-browser.js"
},
"dependencies": {
"@babel/code-frame": "7.0.0-beta.35",
"@babel/generator": "7.0.0-beta.35",
"@babel/helpers": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35",
"babylon": "7.0.0-beta.35",
"@babel/code-frame": "7.0.0-beta.36",
"@babel/generator": "7.0.0-beta.36",
"@babel/helpers": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36",
"babylon": "7.0.0-beta.36",
"convert-source-map": "^1.1.0",
"debug": "^3.0.1",
"json5": "^0.5.0",
@@ -44,7 +44,7 @@
"source-map": "^0.5.0"
},
"devDependencies": {
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.35",
"@babel/register": "7.0.0-beta.35"
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.36",
"@babel/register": "7.0.0-beta.36"
}
}

View File

@@ -1,424 +0,0 @@
// @flow
import path from "path";
import micromatch from "micromatch";
import buildDebug from "debug";
import {
validate,
type ValidatedOptions,
type PluginList,
type IgnoreList,
} from "./options";
const debug = buildDebug("babel:config:config-chain");
import { findConfigs, loadConfig, type ConfigFile } from "./loading/files";
import { makeWeakCache, makeStrongCache } from "./caching";
export type ConfigItem = {
type: "arguments" | "env" | "file",
options: ValidatedOptions,
alias: string,
dirname: string,
};
type ConfigPart =
| {
part: "config",
config: ConfigItem,
ignore: ?IgnoreList,
only: ?IgnoreList,
activeEnv: string | null,
}
| {
part: "extends",
path: string,
dirname: string,
activeEnv: string | null,
};
export default function buildConfigChain(
cwd: string,
opts: ValidatedOptions,
envName: string,
): Array<ConfigItem> | null {
const filename = opts.filename ? path.resolve(cwd, opts.filename) : null;
const builder = new ConfigChainBuilder(
filename ? new LoadedFile(filename) : null,
);
try {
builder.mergeConfigArguments(opts, cwd, envName);
// resolve all .babelrc files
if (opts.babelrc !== false && filename) {
findConfigs(path.dirname(filename), envName).forEach(configFile =>
builder.mergeConfigFile(configFile, envName),
);
}
} catch (e) {
if (e.code !== "BABEL_IGNORED_FILE") throw e;
return null;
}
return builder.configs.reverse();
}
class ConfigChainBuilder {
file: LoadedFile | null;
configs: Array<ConfigItem> = [];
seenFiles: Set<ConfigFile> = new Set();
constructor(file: LoadedFile | null) {
this.file = file;
}
mergeConfigArguments(
opts: ValidatedOptions,
dirname: string,
envKey: string,
) {
flattenArgumentsOptionsParts(opts, dirname, envKey).forEach(part =>
this._processConfigPart(part, envKey),
);
}
mergeConfigFile(file: ConfigFile, envName: string) {
if (this.seenFiles.has(file)) {
throw new Error(
`Cycle detected in Babel configuration file through "${
file.filepath
}".`,
);
}
const parts = flattenFileOptionsParts(file)(envName);
this.seenFiles.add(file);
parts.forEach(part => this._processConfigPart(part, envName));
this.seenFiles.delete(file);
}
_processConfigPart(part: ConfigPart, envName: string) {
if (part.part === "config") {
const { ignore, only } = part;
// Bail out ASAP if this file is ignored so that we run as little logic as possible on ignored files.
if (
this.file &&
this.file.shouldIgnore(ignore, only, part.config.dirname)
) {
// TODO(logan): This is a really gross way to bail out. Avoid this in rewrite.
throw Object.assign((new Error("This file has been ignored."): any), {
code: "BABEL_IGNORED_FILE",
});
}
this.configs.push(part.config);
} else {
this.mergeConfigFile(
loadConfig(part.path, part.dirname, envName),
envName,
);
}
}
}
/**
* Given the root config object passed to Babel, split it into the separate
* config parts. The resulting config objects in the 'ConfigPart' have their
* object identity preserved between calls so that they can be used for caching.
*/
function flattenArgumentsOptionsParts(
opts: ValidatedOptions,
dirname: string,
envName: string,
): Array<ConfigPart> {
const {
env,
plugins,
presets,
passPerPreset,
extends: extendsPath,
...options
} = opts;
const raw = [];
if (env) {
raw.push(...flattenArgumentsEnvOptionsParts(env)(dirname)(envName));
}
if (Object.keys(options).length > 0) {
raw.push(...flattenOptionsParts(buildArgumentsItem(options, dirname)));
}
if (plugins) {
raw.push(...flattenArgumentsPluginsOptionsParts(plugins)(dirname));
}
if (presets) {
raw.push(
...flattenArgumentsPresetsOptionsParts(presets)(!!passPerPreset)(dirname),
);
}
if (extendsPath != null) {
raw.push(
...flattenOptionsParts(
buildArgumentsItem({ extends: extendsPath }, dirname),
),
);
}
return raw;
}
/**
* For the top-level 'options' object, we cache the env list based on
* the object identity of the 'env' object.
*/
const flattenArgumentsEnvOptionsParts = makeWeakCache((env: {}) => {
const options: ValidatedOptions = { env };
return makeStrongCache((dirname: string) =>
flattenOptionsPartsLookup(buildArgumentsItem(options, dirname)),
);
});
/**
* For the top-level 'options' object, we cache the plugin list based on
* the object identity of the 'plugins' object.
*/
const flattenArgumentsPluginsOptionsParts = makeWeakCache(
(plugins: PluginList) => {
const options: ValidatedOptions = { plugins };
return makeStrongCache((dirname: string) =>
flattenOptionsParts(buildArgumentsItem(options, dirname)),
);
},
);
/**
* For the top-level 'options' object, we cache the preset list based on
* the object identity of the 'presets' object.
*/
const flattenArgumentsPresetsOptionsParts = makeWeakCache(
(presets: PluginList) =>
makeStrongCache((passPerPreset: boolean) => {
// The concept of passPerPreset is integrally tied to the preset list
// so unfortunately we need to copy both values here, adding an extra
// layer of caching functions.
const options = { presets, passPerPreset };
return makeStrongCache((dirname: string) =>
flattenOptionsParts(buildArgumentsItem(options, dirname)),
);
}),
);
function buildArgumentsItem(
options: ValidatedOptions,
dirname: string,
): ConfigItem {
return {
type: "arguments",
options,
alias: "base",
dirname,
};
}
/**
* Given a config from a specific file, return a list of ConfigPart objects
* with object identity preserved for all 'config' part objects for use
* with caching later in config processing.
*/
const flattenFileOptionsParts = makeWeakCache((file: ConfigFile) => {
return flattenOptionsPartsLookup({
type: "file",
options: validate("file", file.options),
alias: file.filepath,
dirname: file.dirname,
});
});
/**
* Given a config, create a function that will return the config parts for
* the environment passed as the first argument.
*/
function flattenOptionsPartsLookup(
config: ConfigItem,
): (string | null) => Array<ConfigPart> {
const parts = flattenOptionsParts(config);
const def = parts.filter(part => part.activeEnv === null);
const lookup = new Map();
parts.forEach(part => {
if (part.activeEnv !== null) lookup.set(part.activeEnv, []);
});
for (const [activeEnv, values] of lookup) {
parts.forEach(part => {
if (part.activeEnv === null || part.activeEnv === activeEnv) {
values.push(part);
}
});
}
return envName => lookup.get(envName) || def;
}
/**
* Given a generic config object, flatten it into its various parts so that
* then can be cached and processed later.
*/
function flattenOptionsParts(
config: ConfigItem,
activeEnv: string | null = null,
): Array<ConfigPart> {
const { options: rawOpts, alias, dirname } = config;
const parts = [];
if (rawOpts.env) {
for (const envKey of Object.keys(rawOpts.env)) {
if (rawOpts.env[envKey]) {
parts.push(
...flattenOptionsParts(
{
type: "env",
options: rawOpts.env[envKey],
alias: alias + `.env.${envKey}`,
dirname,
},
envKey,
),
);
}
}
}
parts.push({
part: "config",
config,
ignore: rawOpts.ignore,
only: rawOpts.only,
activeEnv,
});
if (rawOpts.extends != null) {
parts.push({
part: "extends",
path: rawOpts.extends,
dirname,
activeEnv,
});
}
return parts;
}
/**
* Track a given file and expose function to check if it should be ignored.
*/
class LoadedFile {
filename: string;
possibleDirs: null | Array<string> = null;
constructor(filename) {
this.filename = filename;
}
/**
* Tests if a filename should be ignored based on "ignore" and "only" options.
*/
shouldIgnore(
ignore: ?IgnoreList,
only: ?IgnoreList,
dirname: string,
): boolean {
if (ignore) {
if (this._matchesPatterns(ignore, dirname)) {
debug(
"Ignored %o because it matched one of %O from %o",
this.filename,
ignore,
dirname,
);
return true;
}
}
if (only) {
if (!this._matchesPatterns(only, dirname)) {
debug(
"Ignored %o because it failed to match one of %O from %o",
this.filename,
only,
dirname,
);
return true;
}
}
return false;
}
/**
* Returns result of calling function with filename if pattern is a function.
* Otherwise returns result of matching pattern Regex with filename.
*/
_matchesPatterns(patterns: IgnoreList, dirname: string): boolean {
const res = [];
const strings = [];
const fns = [];
patterns.forEach(pattern => {
if (typeof pattern === "string") strings.push(pattern);
else if (typeof pattern === "function") fns.push(pattern);
else res.push(pattern);
});
const filename = this.filename;
if (res.some(re => re.test(filename))) return true;
if (fns.some(fn => fn(filename))) return true;
if (strings.length > 0) {
let possibleDirs = this.possibleDirs;
// Lazy-init so we don't initialize this for files that have no glob patterns.
if (!possibleDirs) {
possibleDirs = this.possibleDirs = [];
possibleDirs.push(filename);
let current = filename;
while (true) {
const previous = current;
current = path.dirname(current);
if (previous === current) break;
possibleDirs.push(current);
}
}
const absolutePatterns = strings.map(pattern => {
// Preserve the "!" prefix so that micromatch can use it for negation.
const negate = pattern[0] === "!";
if (negate) pattern = pattern.slice(1);
return (negate ? "!" : "") + path.resolve(dirname, pattern);
});
if (
micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0
) {
return true;
}
}
return false;
}
}

View File

@@ -14,9 +14,10 @@ type SimpleCacheConfiguratorObj = {
invalidate: <T>(handler: () => T) => T,
};
type CacheEntry<ResultT, SideChannel> = Array<
[ResultT, (SideChannel) => boolean],
>;
type CacheEntry<ResultT, SideChannel> = Array<{
value: ResultT,
valid: SideChannel => boolean,
}>;
export type { CacheConfigurator };
@@ -64,7 +65,7 @@ function makeCachedFunction<
);
if (cachedValue) {
for (const [value, valid] of cachedValue) {
for (const { value, valid } of cachedValue) {
if (valid(data)) return value;
}
}
@@ -79,18 +80,18 @@ function makeCachedFunction<
switch (cache.mode()) {
case "forever":
cachedValue = [[value, () => true]];
cachedValue = [{ value, valid: () => true }];
callCache.set(arg, cachedValue);
break;
case "invalidate":
cachedValue = [[value, cache.validator()]];
cachedValue = [{ value, valid: cache.validator() }];
callCache.set(arg, cachedValue);
break;
case "valid":
if (cachedValue) {
cachedValue.push([value, cache.validator()]);
cachedValue.push({ value, valid: cache.validator() });
} else {
cachedValue = [[value, cache.validator()]];
cachedValue = [{ value, valid: cache.validator() }];
callCache.set(arg, cachedValue);
}
}

View File

@@ -0,0 +1,452 @@
// @flow
import path from "path";
import micromatch from "micromatch";
import buildDebug from "debug";
import {
validate,
type ValidatedOptions,
type IgnoreList,
} from "./validation/options";
const debug = buildDebug("babel:config:config-chain");
import {
findBabelrc,
findBabelignore,
loadConfig,
type ConfigFile,
} from "./files";
import { makeWeakCache, makeStrongCache } from "./caching";
import {
createCachedDescriptors,
createUncachedDescriptors,
type UnloadedDescriptor,
type OptionsAndDescriptors,
type ValidatedFile,
} from "./config-descriptors";
export type ConfigChain = {
plugins: Array<UnloadedDescriptor>,
presets: Array<UnloadedDescriptor>,
options: Array<ValidatedOptions>,
};
export type PresetInstance = {
options: ValidatedOptions,
alias: string,
dirname: string,
};
type ConfigContext = {
filename: string | null,
cwd: string,
envName: string,
};
type ConfigContextNamed = {
...ConfigContext,
filename: string,
};
/**
* Build a config chain for a given preset.
*/
export const buildPresetChain = makeWeakCache(
({ dirname, options, alias }: PresetInstance): ConfigChain => {
const result = createUncachedDescriptors(dirname, options, alias);
const { plugins, presets } = result;
return {
plugins: plugins(),
presets: presets(),
options: [normalizeOptions(result.options)],
};
},
);
/**
* Build a config chain for Babel's full root configuration.
*/
export function buildRootChain(
cwd: string,
opts: ValidatedOptions,
envName: string,
): ConfigChain | null {
const context = {
filename: opts.filename ? path.resolve(cwd, opts.filename) : null,
cwd,
envName,
};
const programmaticChain = loadProgrammaticChain(
{
options: opts,
dirname: context.cwd,
},
context,
);
if (!programmaticChain) return null;
const fileChain = emptyChain();
// resolve all .babelrc files
if (opts.babelrc !== false && context.filename !== null) {
const filename = context.filename;
const babelrcFile = findBabelrc(filename, context.envName);
if (babelrcFile) {
const result = loadFileChain(babelrcFile, context);
if (!result) return null;
mergeChain(fileChain, result);
}
const babelignoreFile = findBabelignore(filename);
if (
babelignoreFile &&
shouldIgnore(
context,
babelignoreFile.ignore,
null,
babelignoreFile.dirname,
)
) {
return null;
}
}
// Insert file chain in front so programmatic options have priority
// over configuration file chain items.
const chain = mergeChain(
mergeChain(emptyChain(), fileChain),
programmaticChain,
);
return {
plugins: dedupDescriptors(chain.plugins),
presets: dedupDescriptors(chain.presets),
options: chain.options.map(o => normalizeOptions(o)),
};
}
/**
* Build a config chain for just the programmatic options passed into Babel.
*/
const loadProgrammaticChain = makeChainWalker({
init: arg => arg,
root: input => buildRootDescriptors(input, "base", createCachedDescriptors),
env: (input, envName) =>
buildEnvDescriptors(input, "base", createCachedDescriptors, envName),
});
/**
* Build a config chain for a given file.
*/
const loadFileChain = makeChainWalker({
init: input => validateFile(input),
root: file => loadFileDescriptors(file),
env: (file, envName) => loadFileEnvDescriptors(file)(envName),
});
const validateFile = makeWeakCache((file: ConfigFile): ValidatedFile => ({
filepath: file.filepath,
dirname: file.dirname,
options: validate("file", file.options),
}));
const loadFileDescriptors = makeWeakCache((file: ValidatedFile) =>
buildRootDescriptors(file, file.filepath, createUncachedDescriptors),
);
const loadFileEnvDescriptors = makeWeakCache((file: ValidatedFile) =>
makeStrongCache((envName: string) =>
buildEnvDescriptors(
file,
file.filepath,
createUncachedDescriptors,
envName,
),
),
);
function buildRootDescriptors({ dirname, options }, alias, descriptors) {
return descriptors(dirname, options, alias);
}
function buildEnvDescriptors(
{ dirname, options },
alias,
descriptors,
envName,
) {
const opts = options.env && options.env[envName];
return opts ? descriptors(dirname, opts, `${alias}.env["${envName}"]`) : null;
}
function makeChainWalker<
ArgT,
InnerT: { options: ValidatedOptions, dirname: string },
>({
init,
root,
env,
}: {
init: ArgT => InnerT,
root: InnerT => OptionsAndDescriptors,
env: (InnerT, string) => OptionsAndDescriptors | null,
}): (ArgT, ConfigContext, Set<ConfigFile> | void) => ConfigChain | null {
return (arg, context, files = new Set()) => {
const input = init(arg);
const { dirname } = input;
const flattenedConfigs = [];
const rootOpts = root(input);
flattenedConfigs.push(rootOpts);
const envOpts = env(input, context.envName);
if (envOpts) {
flattenedConfigs.push(envOpts);
}
// Process 'ignore' and 'only' before 'extends' items are processed so
// that we don't do extra work loading extended configs if a file is
// ignored.
if (
flattenedConfigs.some(({ options: { ignore, only } }) =>
shouldIgnore(context, ignore, only, dirname),
)
) {
return null;
}
const chain = emptyChain();
for (const op of flattenedConfigs) {
if (!mergeExtendsChain(chain, op.options, dirname, context, files)) {
return null;
}
mergeChainOpts(chain, op);
}
return chain;
};
}
function mergeExtendsChain(
chain: ConfigChain,
opts: ValidatedOptions,
dirname: string,
context: ConfigContext,
files: Set<ConfigFile>,
): boolean {
if (opts.extends === undefined) return true;
const file = loadConfig(opts.extends, dirname, context.envName);
if (files.has(file)) {
throw new Error(
`Configuration cycle detected loading ${file.filepath}.\n` +
`File already loaded following the config chain:\n` +
Array.from(files, file => ` - ${file.filepath}`).join("\n"),
);
}
files.add(file);
const fileChain = loadFileChain(file, context, files);
files.delete(file);
if (!fileChain) return false;
mergeChain(chain, fileChain);
return true;
}
function mergeChain(target: ConfigChain, source: ConfigChain): ConfigChain {
target.options.push(...source.options);
target.plugins.push(...source.plugins);
target.presets.push(...source.presets);
return target;
}
function mergeChainOpts(
target: ConfigChain,
{ options, plugins, presets }: OptionsAndDescriptors,
): ConfigChain {
target.options.push(options);
target.plugins.push(...plugins());
target.presets.push(...presets());
return target;
}
function emptyChain(): ConfigChain {
return {
options: [],
presets: [],
plugins: [],
};
}
function normalizeOptions(opts: ValidatedOptions): ValidatedOptions {
const options = Object.assign({}, opts);
delete options.extends;
delete options.env;
delete options.plugins;
delete options.presets;
delete options.passPerPreset;
delete options.ignore;
delete options.only;
// "sourceMap" is just aliased to sourceMap, so copy it over as
// we merge the options together.
if (options.sourceMap) {
options.sourceMaps = options.sourceMap;
delete options.sourceMap;
}
return options;
}
function dedupDescriptors(
items: Array<UnloadedDescriptor>,
): Array<UnloadedDescriptor> {
const map: Map<
Function,
Map<string | void, { value: UnloadedDescriptor | null }>,
> = new Map();
const descriptors = [];
for (const item of items) {
if (typeof item.value === "function") {
const fnKey = item.value;
let nameMap = map.get(fnKey);
if (!nameMap) {
nameMap = new Map();
map.set(fnKey, nameMap);
}
let desc = nameMap.get(item.name);
if (!desc) {
desc = { value: null };
descriptors.push(desc);
// Treat passPerPreset presets as unique, skipping them
// in the merge processing steps.
if (!item.ownPass) nameMap.set(item.name, desc);
}
if (item.options === false) {
desc.value = null;
} else {
desc.value = item;
}
} else {
descriptors.push({ value: item });
}
}
return descriptors.reduce((acc, desc) => {
if (desc.value) acc.push(desc.value);
return acc;
}, []);
}
/**
* Tests if a filename should be ignored based on "ignore" and "only" options.
*/
function shouldIgnore(
context: ConfigContext,
ignore: ?IgnoreList,
only: ?IgnoreList,
dirname: string,
): boolean {
if (context.filename === null) return false;
// $FlowIgnore - Flow refinements aren't quite smart enough for this :(
const ctx: ConfigContextNamed = context;
if (ignore) {
if (matchesPatterns(ctx, ignore, dirname)) {
debug(
"Ignored %o because it matched one of %O from %o",
context.filename,
ignore,
dirname,
);
return true;
}
}
if (only) {
if (!matchesPatterns(ctx, only, dirname)) {
debug(
"Ignored %o because it failed to match one of %O from %o",
context.filename,
only,
dirname,
);
return true;
}
}
return false;
}
/**
* Returns result of calling function with filename if pattern is a function.
* Otherwise returns result of matching pattern Regex with filename.
*/
function matchesPatterns(
context: ConfigContextNamed,
patterns: IgnoreList,
dirname: string,
): boolean {
const res = [];
const strings = [];
const fns = [];
patterns.forEach(pattern => {
if (typeof pattern === "string") strings.push(pattern);
else if (typeof pattern === "function") fns.push(pattern);
else res.push(pattern);
});
const filename = context.filename;
if (res.some(re => re.test(context.filename))) return true;
if (fns.some(fn => fn(filename))) return true;
if (strings.length > 0) {
const possibleDirs = getPossibleDirs(context);
const absolutePatterns = strings.map(pattern => {
// Preserve the "!" prefix so that micromatch can use it for negation.
const negate = pattern[0] === "!";
if (negate) pattern = pattern.slice(1);
return (negate ? "!" : "") + path.resolve(dirname, pattern);
});
if (
micromatch(possibleDirs, absolutePatterns, { nocase: true }).length > 0
) {
return true;
}
}
return false;
}
const getPossibleDirs = makeWeakCache((context: ConfigContextNamed) => {
let current = context.filename;
if (current === null) return [];
const possibleDirs = [current];
while (true) {
const previous = current;
current = path.dirname(current);
if (previous === current) break;
possibleDirs.push(current);
}
return possibleDirs;
});

View File

@@ -0,0 +1,272 @@
// @flow
import { loadPlugin, loadPreset } from "./files";
import {
makeWeakCache,
makeStrongCache,
type CacheConfigurator,
} from "./caching";
import type {
ValidatedOptions,
PluginList,
PluginItem,
} from "./validation/options";
// Represents a config object and functions to lazily load the descriptors
// for the plugins and presets so we don't load the plugins/presets unless
// the options object actually ends up being applicable.
export type OptionsAndDescriptors = {
options: ValidatedOptions,
plugins: () => Array<UnloadedDescriptor>,
presets: () => Array<UnloadedDescriptor>,
};
// Represents a plugin or presets at a given location in a config object.
// At this point these have been resolved to a specific object or function,
// but have not yet been executed to call functions with options.
export type UnloadedDescriptor = {
name: string | void,
value: {} | Function,
options: {} | void | false,
dirname: string,
alias: string,
ownPass?: boolean,
};
export type ValidatedFile = {
filepath: string,
dirname: string,
options: ValidatedOptions,
};
/**
* Create a set of descriptors from a given options object, preserving
* descriptor identity based on the identity of the plugin/preset arrays
* themselves.
*/
export function createCachedDescriptors(
dirname: string,
options: ValidatedOptions,
alias: string,
): OptionsAndDescriptors {
const { plugins, presets, passPerPreset } = options;
return {
options,
plugins: plugins
? () => createCachedPluginDescriptors(plugins, dirname)(alias)
: () => [],
presets: presets
? () =>
createCachedPresetDescriptors(presets, dirname)(alias)(
!!passPerPreset,
)
: () => [],
};
}
/**
* Create a set of descriptors from a given options object, with consistent
* identity for the descriptors, but not caching based on any specific identity.
*/
export function createUncachedDescriptors(
dirname: string,
options: ValidatedOptions,
alias: string,
): OptionsAndDescriptors {
// The returned result here is cached to represent a config object in
// memory, so we build and memoize the descriptors to ensure the same
// values are returned consistently.
let plugins;
let presets;
return {
options,
plugins: () => {
if (!plugins) {
plugins = createPluginDescriptors(
options.plugins || [],
dirname,
alias,
);
}
return plugins;
},
presets: () => {
if (!presets) {
presets = createPresetDescriptors(
options.presets || [],
dirname,
alias,
!!options.passPerPreset,
);
}
return presets;
},
};
}
const createCachedPresetDescriptors = makeWeakCache(
(items: PluginList, cache: CacheConfigurator<string>) => {
const dirname = cache.using(dir => dir);
return makeStrongCache((alias: string) =>
makeStrongCache((passPerPreset: boolean) =>
createPresetDescriptors(items, dirname, alias, passPerPreset),
),
);
},
);
const createCachedPluginDescriptors = makeWeakCache(
(items: PluginList, cache: CacheConfigurator<string>) => {
const dirname = cache.using(dir => dir);
return makeStrongCache((alias: string) =>
createPluginDescriptors(items, dirname, alias),
);
},
);
function createPresetDescriptors(
items: PluginList,
dirname: string,
alias: string,
passPerPreset: boolean,
): Array<UnloadedDescriptor> {
return createDescriptors("preset", items, dirname, alias, passPerPreset);
}
function createPluginDescriptors(
items: PluginList,
dirname: string,
alias: string,
): Array<UnloadedDescriptor> {
return createDescriptors("plugin", items, dirname, alias);
}
function createDescriptors(
type: "plugin" | "preset",
items: PluginList,
dirname: string,
alias: string,
ownPass?: boolean,
): Array<UnloadedDescriptor> {
const descriptors = items.map((item, index) =>
createDescriptor(
item,
type === "plugin" ? loadPlugin : loadPreset,
dirname,
{
index,
alias,
ownPass: !!ownPass,
},
),
);
assertNoDuplicates(descriptors);
return descriptors;
}
/**
* Given a plugin/preset item, resolve it into a standard format.
*/
function createDescriptor(
pair: PluginItem,
resolver,
dirname,
{
index,
alias,
ownPass,
}: {
index: number,
alias: string,
ownPass?: boolean,
},
): UnloadedDescriptor {
let name;
let options;
let value = pair;
if (Array.isArray(value)) {
if (value.length === 3) {
// $FlowIgnore - Flow doesn't like the multiple tuple types.
[value, options, name] = value;
} else {
[value, options] = value;
}
}
let filepath = null;
if (typeof value === "string") {
({ filepath, value } = resolver(value, dirname));
}
if (!value) {
throw new Error(`Unexpected falsy value: ${String(value)}`);
}
if (typeof value === "object" && value.__esModule) {
if (value.default) {
value = value.default;
} else {
throw new Error("Must export a default export when using ES6 modules.");
}
}
if (typeof value !== "object" && typeof value !== "function") {
throw new Error(
`Unsupported format: ${typeof value}. Expected an object or a function.`,
);
}
if (filepath !== null && typeof value === "object" && value) {
// We allow object values for plugins/presets nested directly within a
// config object, because it can be useful to define them in nested
// configuration contexts.
throw new Error(
"Plugin/Preset files are not allowed to export objects, only functions.",
);
}
return {
name,
alias: filepath || `${alias}$${index}`,
value,
options,
dirname,
ownPass,
};
}
function assertNoDuplicates(items: Array<UnloadedDescriptor>): void {
const map = new Map();
for (const item of items) {
if (typeof item.value !== "function") continue;
let nameMap = map.get(item.value);
if (!nameMap) {
nameMap = new Set();
map.set(item.value, nameMap);
}
if (nameMap.has(item.name)) {
throw new Error(
[
`Duplicate plugin/preset detected.`,
`If you'd like to use two separate instances of a plugin,`,
`they neen separate names, e.g.`,
``,
` plugins: [`,
` ['some-plugin', {}],`,
` ['some-plugin', {}, 'some unique name'],`,
` ]`,
].join("\n"),
);
}
nameMap.add(item.name);
}
}

View File

@@ -5,7 +5,7 @@ import path from "path";
import fs from "fs";
import json5 from "json5";
import resolve from "resolve";
import { makeStrongCache, type CacheConfigurator } from "../../caching";
import { makeStrongCache, type CacheConfigurator } from "../caching";
const debug = buildDebug("babel:config:loading:files:configuration");
@@ -15,68 +15,75 @@ export type ConfigFile = {
options: {},
};
export type IgnoreFile = {
filepath: string,
dirname: string,
ignore: Array<string>,
};
const BABELRC_FILENAME = ".babelrc";
const BABELRC_JS_FILENAME = ".babelrc.js";
const PACKAGE_FILENAME = "package.json";
const BABELIGNORE_FILENAME = ".babelignore";
export function findConfigs(
dirname: string,
export function findBabelrc(
filepath: string,
envName: string,
): Array<ConfigFile> {
let foundConfig = false;
let foundIgnore = false;
const confs = [];
): ConfigFile | null {
const dirname = path.dirname(filepath);
let loc = dirname;
while (true) {
if (!foundIgnore) {
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
const ignore = readIgnoreConfig(ignoreLoc);
const conf = [
BABELRC_FILENAME,
BABELRC_JS_FILENAME,
PACKAGE_FILENAME,
].reduce((previousConfig: ConfigFile | null, name) => {
const filepath = path.join(loc, name);
const config = readConfig(filepath, envName);
if (ignore) {
debug("Found ignore %o from %o.", ignore.filepath, dirname);
confs.push(ignore);
foundIgnore = true;
if (config && previousConfig) {
throw new Error(
`Multiple configuration files found. Please remove one:\n` +
` - ${path.basename(previousConfig.filepath)}\n` +
` - ${name}\n` +
`from ${loc}`,
);
}
return config || previousConfig;
}, null);
if (conf) {
debug("Found configuration %o from %o.", conf.filepath, dirname);
return conf;
}
if (!foundConfig) {
const conf = [
BABELRC_FILENAME,
BABELRC_JS_FILENAME,
PACKAGE_FILENAME,
].reduce((previousConfig: ConfigFile | null, name) => {
const filepath = path.join(loc, name);
const config = readConfig(filepath, envName);
if (config && previousConfig) {
throw new Error(
`Multiple configuration files found. Please remove one:\n- ${path.basename(
previousConfig.filepath,
)}\n- ${name}\nfrom ${loc}`,
);
}
return config || previousConfig;
}, null);
if (conf) {
debug("Found configuration %o from %o.", conf.filepath, dirname);
confs.push(conf);
foundConfig = true;
}
}
if (foundIgnore && foundConfig) break;
if (loc === path.dirname(loc)) break;
loc = path.dirname(loc);
const nextLoc = path.dirname(loc);
if (loc === nextLoc) break;
loc = nextLoc;
}
return confs;
return null;
}
export function findBabelignore(filepath: string): IgnoreFile | null {
const dirname = path.dirname(filepath);
let loc = dirname;
while (true) {
const ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
const ignore = readIgnoreConfig(ignoreLoc);
if (ignore) {
debug("Found ignore %o from %o.", ignore.filepath, dirname);
return ignore;
}
const nextLoc = path.dirname(loc);
if (loc === nextLoc) break;
loc = nextLoc;
}
return null;
}
export function loadConfig(
@@ -224,7 +231,7 @@ const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
return {
filepath,
dirname: path.dirname(filepath),
options: { ignore },
ignore,
};
});

View File

@@ -6,9 +6,22 @@ export type ConfigFile = {
options: {},
};
export type IgnoreFile = {
filepath: string,
dirname: string,
ignore: Array<string>,
};
export function findBabelrc(
filepath: string,
envName: string, // eslint-disable-line no-unused-vars
): ConfigFile | null {
return null;
}
// eslint-disable-next-line no-unused-vars
export function findConfigs(dirname: string): Array<ConfigFile> {
return [];
export function findBabelignore(filepath: string): IgnoreFile | null {
return null;
}
export function loadConfig(name: string, dirname: string): ConfigFile {

View File

@@ -1,9 +1,31 @@
// @flow
import type Plugin from "./plugin";
import manageOptions from "./option-manager";
import path from "path";
import * as context from "../index";
import Plugin from "./plugin";
import merge from "lodash/merge";
import {
buildRootChain,
buildPresetChain,
type ConfigChain,
type PresetInstance,
} from "./config-chain";
import type { UnloadedDescriptor } from "./config-descriptors";
import traverse from "@babel/traverse";
import clone from "lodash/clone";
import { makeWeakCache, type CacheConfigurator } from "./caching";
import { getEnv } from "./helpers/environment";
import { validate } from "./validation/options";
import { validatePluginObject } from "./validation/plugins";
export type { InputOptions } from "./options";
type LoadedDescriptor = {
value: {},
options: {},
dirname: string,
alias: string,
};
export type { InputOptions } from "./validation/options";
export type ResolvedConfig = {
options: Object,
@@ -14,13 +36,257 @@ export type { Plugin };
export type PluginPassList = Array<Plugin>;
export type PluginPasses = Array<PluginPassList>;
/**
* Standard API for loading Babel configuration data. Not for public consumption.
*/
export default function loadConfig(opts: mixed): ResolvedConfig | null {
if (opts != null && (typeof opts !== "object" || Array.isArray(opts))) {
export default function loadConfig(inputOpts: mixed): ResolvedConfig | null {
if (
inputOpts != null &&
(typeof inputOpts !== "object" || Array.isArray(inputOpts))
) {
throw new Error("Babel options must be an object, null, or undefined");
}
return manageOptions(opts || {});
const args = inputOpts ? validate("arguments", inputOpts) : {};
const { envName = getEnv(), cwd = "." } = args;
const absoluteCwd = path.resolve(cwd);
const configChain = buildRootChain(absoluteCwd, args, envName);
if (!configChain) return null;
const optionDefaults = {};
const options = {};
const passes = [[]];
try {
(function recurseDescriptors(
config: {
plugins: Array<UnloadedDescriptor>,
presets: Array<UnloadedDescriptor>,
},
pass: Array<Plugin>,
envName: string,
) {
const plugins = config.plugins.map(descriptor =>
loadPluginDescriptor(descriptor, envName),
);
const presets = config.presets.map(descriptor => {
return {
preset: loadPresetDescriptor(descriptor, envName),
pass: descriptor.ownPass ? [] : pass,
};
});
// resolve presets
if (presets.length > 0) {
// The passes are created in the same order as the preset list, but are inserted before any
// existing additional passes.
passes.splice(
1,
0,
...presets.map(o => o.pass).filter(p => p !== pass),
);
for (const { preset, pass } of presets) {
recurseDescriptors(
{
plugins: preset.plugins,
presets: preset.presets,
},
pass,
envName,
);
preset.options.forEach(opts => {
merge(optionDefaults, opts);
});
}
}
// resolve plugins
if (plugins.length > 0) {
pass.unshift(...plugins);
}
})(
{
plugins: configChain.plugins,
presets: configChain.presets,
},
passes[0],
envName,
);
configChain.options.forEach(opts => {
merge(options, opts);
});
} catch (e) {
// There are a few case where thrown errors will try to annotate themselves multiple times, so
// to keep things simple we just bail out if re-wrapping the message.
if (!/^\[BABEL\]/.test(e.message)) {
e.message = `[BABEL] ${args.filename || "unknown"}: ${e.message}`;
}
throw e;
}
const opts: Object = merge(optionDefaults, options);
// Tack the passes onto the object itself so that, if this object is passed back to Babel a second time,
// it will be in the right structure to not change behavior.
opts.babelrc = false;
opts.plugins = passes[0];
opts.presets = passes
.slice(1)
.filter(plugins => plugins.length > 0)
.map(plugins => ({ plugins }));
opts.passPerPreset = opts.presets.length > 0;
opts.envName = envName;
opts.cwd = absoluteCwd;
return {
options: opts,
passes: passes,
};
}
/**
* Load a generic plugin/preset from the given descriptor loaded from the config object.
*/
const loadDescriptor = makeWeakCache(
(
{ value, options, dirname, alias }: UnloadedDescriptor,
cache: CacheConfigurator<{ envName: string }>,
): LoadedDescriptor => {
// Disabled presets should already have been filtered out
if (options === false) throw new Error("Assertion failure");
options = options || {};
let item = value;
if (typeof value === "function") {
const api = Object.assign(Object.create(context), {
cache: cache.simple(),
env: () => cache.using(data => data.envName),
async: () => false,
});
try {
item = value(api, options, dirname);
} catch (e) {
if (alias) {
e.message += ` (While processing: ${JSON.stringify(alias)})`;
}
throw e;
}
}
if (!item || typeof item !== "object") {
throw new Error("Plugin/Preset did not return an object.");
}
if (typeof item.then === "function") {
throw new Error(
`You appear to be using an async plugin, ` +
`which your current version of Babel does not support.` +
`If you're using a published plugin, ` +
`you may need to upgrade your @babel/core version.`,
);
}
return { value: item, options, dirname, alias };
},
);
/**
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
*/
function loadPluginDescriptor(
descriptor: UnloadedDescriptor,
envName: string,
): Plugin {
if (descriptor.value instanceof Plugin) {
if (descriptor.options) {
throw new Error(
"Passed options to an existing Plugin instance will not work.",
);
}
return descriptor.value;
}
return instantiatePlugin(loadDescriptor(descriptor, { envName }), {
envName,
});
}
const instantiatePlugin = makeWeakCache(
(
{ value, options, dirname, alias }: LoadedDescriptor,
cache: CacheConfigurator<{ envName: string }>,
): Plugin => {
const pluginObj = validatePluginObject(value);
const plugin = Object.assign({}, pluginObj);
if (plugin.visitor) {
plugin.visitor = traverse.explode(clone(plugin.visitor));
}
if (plugin.inherits) {
const inheritsDescriptor = {
name: undefined,
alias: `${alias}$inherits`,
value: plugin.inherits,
options,
dirname,
};
// If the inherited plugin changes, reinstantiate this plugin.
const inherits = cache.invalidate(data =>
loadPluginDescriptor(inheritsDescriptor, data.envName),
);
plugin.pre = chain(inherits.pre, plugin.pre);
plugin.post = chain(inherits.post, plugin.post);
plugin.manipulateOptions = chain(
inherits.manipulateOptions,
plugin.manipulateOptions,
);
plugin.visitor = traverse.visitors.merge([
inherits.visitor || {},
plugin.visitor || {},
]);
}
return new Plugin(plugin, options, alias);
},
);
/**
* Generate a config object that will act as the root of a new nested config.
*/
const loadPresetDescriptor = (
descriptor: UnloadedDescriptor,
envName: string,
): ConfigChain => {
return buildPresetChain(
instantiatePreset(loadDescriptor(descriptor, { envName })),
);
};
const instantiatePreset = makeWeakCache(
({ value, dirname, alias }: LoadedDescriptor): PresetInstance => {
return {
options: validate("preset", value),
alias,
dirname,
};
},
);
function chain(a, b) {
const fns = [a, b].filter(Boolean);
if (fns.length <= 1) return fns[0];
return function(...args) {
for (const fn of fns) {
fn.apply(this, args);
}
};
}

View File

@@ -1,535 +0,0 @@
// @flow
import path from "path";
import * as context from "../index";
import Plugin, { validatePluginObject } from "./plugin";
import merge from "lodash/merge";
import buildConfigChain, { type ConfigItem } from "./build-config-chain";
import traverse from "@babel/traverse";
import clone from "lodash/clone";
import { makeWeakCache, type CacheConfigurator } from "./caching";
import { getEnv } from "./helpers/environment";
import { validate, type ValidatedOptions, type PluginItem } from "./options";
import { loadPlugin, loadPreset } from "./loading/files";
type MergeOptions =
| ConfigItem
| {
type: "preset",
options: ValidatedOptions,
alias: string,
dirname: string,
};
export default function manageOptions(opts: {}): {
options: Object,
passes: Array<Array<Plugin>>,
} | null {
return new OptionManager().init(opts);
}
class OptionManager {
optionDefaults: ValidatedOptions = {};
options: ValidatedOptions = {};
passes: Array<Array<Plugin>> = [[]];
/**
* This is called when we want to merge the input `opts` into the
* base options.
*
* - `alias` is used to output pretty traces back to the original source.
* - `loc` is used to point to the original config.
* - `dirname` is used to resolve plugins relative to it.
*/
mergeOptions(
config: {
plugins: Array<BasicDescriptor>,
presets: Array<BasicDescriptor>,
},
pass: Array<Plugin>,
envName: string,
) {
const plugins = config.plugins.map(descriptor =>
loadPluginDescriptor(descriptor, envName),
);
const presets = config.presets.map(descriptor => {
return {
preset: loadPresetDescriptor(descriptor, envName),
pass: descriptor.ownPass ? [] : pass,
};
});
// resolve presets
if (presets.length > 0) {
// The passes are created in the same order as the preset list, but are inserted before any
// existing additional passes.
this.passes.splice(
1,
0,
...presets.map(o => o.pass).filter(p => p !== pass),
);
presets.forEach(({ preset, pass }) => {
const loadedConfig = loadConfig(preset);
this.mergeOptions(
{
// Call dedupDescriptors() to remove 'false' descriptors.
plugins: dedupDescriptors(loadedConfig.plugins),
presets: dedupDescriptors(loadedConfig.presets),
},
pass,
envName,
);
merge(this.optionDefaults, normalizeOptions(loadedConfig.options));
});
}
// resolve plugins
if (plugins.length > 0) {
pass.unshift(...plugins);
}
}
mergeConfigChain(chain: $ReadOnlyArray<MergeOptions>, envName: string) {
const config = dedupLoadedConfigs(chain.map(config => loadConfig(config)));
this.mergeOptions(
{
plugins: config.plugins,
presets: config.presets,
},
this.passes[0],
envName,
);
config.options.forEach(opts => {
merge(this.options, normalizeOptions(opts));
});
}
init(inputOpts: {}) {
const args = validate("arguments", inputOpts);
const { envName = getEnv(), cwd = "." } = args;
const absoluteCwd = path.resolve(cwd);
const configChain = buildConfigChain(absoluteCwd, args, envName);
if (!configChain) return null;
try {
this.mergeConfigChain(configChain, envName);
} catch (e) {
// There are a few case where thrown errors will try to annotate themselves multiple times, so
// to keep things simple we just bail out if re-wrapping the message.
if (!/^\[BABEL\]/.test(e.message)) {
e.message = `[BABEL] ${args.filename || "unknown"}: ${e.message}`;
}
throw e;
}
const opts: Object = merge(this.optionDefaults, this.options);
// Tack the passes onto the object itself so that, if this object is passed back to Babel a second time,
// it will be in the right structure to not change behavior.
opts.babelrc = false;
opts.plugins = this.passes[0];
opts.presets = this.passes
.slice(1)
.filter(plugins => plugins.length > 0)
.map(plugins => ({ plugins }));
opts.passPerPreset = opts.presets.length > 0;
opts.envName = envName;
opts.cwd = absoluteCwd;
return {
options: opts,
passes: this.passes,
};
}
}
function normalizeOptions(opts: ValidatedOptions): ValidatedOptions {
const options = Object.assign({}, opts);
delete options.extends;
delete options.env;
delete options.plugins;
delete options.presets;
delete options.passPerPreset;
delete options.ignore;
delete options.only;
// "sourceMap" is just aliased to sourceMap, so copy it over as
// we merge the options together.
if (options.sourceMap) {
options.sourceMaps = options.sourceMap;
delete options.sourceMap;
}
return options;
}
type BasicDescriptor = {
name: string | void,
value: {} | Function,
options: {} | void | false,
dirname: string,
alias: string,
ownPass?: boolean,
};
type LoadedDescriptor = {
value: {},
options: {},
dirname: string,
alias: string,
};
type LoadedConfig = {
options: ValidatedOptions,
plugins: Array<BasicDescriptor>,
presets: Array<BasicDescriptor>,
};
/**
* Load and validate the given config into a set of options, plugins, and presets.
*/
const loadConfig = makeWeakCache((config: MergeOptions): LoadedConfig => {
const options = config.options;
const plugins = (config.options.plugins || []).map((plugin, index) =>
createDescriptor(plugin, loadPlugin, config.dirname, {
index,
alias: config.alias,
}),
);
assertNoDuplicates(plugins);
const presets = (config.options.presets || []).map((preset, index) =>
createDescriptor(preset, loadPreset, config.dirname, {
index,
alias: config.alias,
ownPass: options.passPerPreset,
}),
);
assertNoDuplicates(presets);
return { options, plugins, presets };
});
function assertNoDuplicates(items: Array<BasicDescriptor>): void {
const map = new Map();
for (const item of items) {
if (typeof item.value !== "function") continue;
let nameMap = map.get(item.value);
if (!nameMap) {
nameMap = new Set();
map.set(item.value, nameMap);
}
if (nameMap.has(item.name)) {
throw new Error(
[
`Duplicate plugin/preset detected.`,
`If you'd like to use two separate instances of a plugin,`,
`they neen separate names, e.g.`,
``,
` plugins: [`,
` ['some-plugin', {}],`,
` ['some-plugin', {}, 'some unique name'],`,
` ]`,
].join("\n"),
);
}
nameMap.add(item.name);
}
}
function dedupLoadedConfigs(
items: Array<LoadedConfig>,
): {
plugins: Array<BasicDescriptor>,
presets: Array<BasicDescriptor>,
options: Array<ValidatedOptions>,
} {
const options = [];
const plugins = [];
const presets = [];
for (const item of items) {
plugins.push(...item.plugins);
presets.push(...item.presets);
options.push(item.options);
}
return {
options,
plugins: dedupDescriptors(plugins),
presets: dedupDescriptors(presets),
};
}
function dedupDescriptors(
items: Array<BasicDescriptor>,
): Array<BasicDescriptor> {
const map: Map<
Function,
Map<string | void, { value: BasicDescriptor | null }>,
> = new Map();
const descriptors = [];
for (const item of items) {
if (typeof item.value === "function") {
const fnKey = item.value;
let nameMap = map.get(fnKey);
if (!nameMap) {
nameMap = new Map();
map.set(fnKey, nameMap);
}
let desc = nameMap.get(item.name);
if (!desc) {
desc = { value: null };
descriptors.push(desc);
// Treat passPerPreset presets as unique, skipping them
// in the merge processing steps.
if (!item.ownPass) nameMap.set(item.name, desc);
}
if (item.options === false) {
desc.value = null;
} else {
desc.value = item;
}
} else {
descriptors.push({ value: item });
}
}
return descriptors.reduce((acc, desc) => {
if (desc.value) acc.push(desc.value);
return acc;
}, []);
}
/**
* Load a generic plugin/preset from the given descriptor loaded from the config object.
*/
const loadDescriptor = makeWeakCache(
(
{ value, options, dirname, alias }: BasicDescriptor,
cache: CacheConfigurator<{ envName: string }>,
): LoadedDescriptor => {
// Disabled presets should already have been filtered out
if (options === false) throw new Error("Assertion failure");
options = options || {};
let item = value;
if (typeof value === "function") {
const api = Object.assign(Object.create(context), {
cache: cache.simple(),
env: () => cache.using(data => data.envName),
async: () => false,
});
try {
item = value(api, options, dirname);
} catch (e) {
if (alias) {
e.message += ` (While processing: ${JSON.stringify(alias)})`;
}
throw e;
}
}
if (!item || typeof item !== "object") {
throw new Error("Plugin/Preset did not return an object.");
}
if (typeof item.then === "function") {
throw new Error(
`You appear to be using an async plugin, ` +
`which your current version of Babel does not support.` +
`If you're using a published plugin, ` +
`you may need to upgrade your @babel/core version.`,
);
}
return { value: item, options, dirname, alias };
},
);
/**
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
*/
function loadPluginDescriptor(
descriptor: BasicDescriptor,
envName: string,
): Plugin {
if (descriptor.value instanceof Plugin) {
if (descriptor.options) {
throw new Error(
"Passed options to an existing Plugin instance will not work.",
);
}
return descriptor.value;
}
return instantiatePlugin(loadDescriptor(descriptor, { envName }), {
envName,
});
}
const instantiatePlugin = makeWeakCache(
(
{ value, options, dirname, alias }: LoadedDescriptor,
cache: CacheConfigurator<{ envName: string }>,
): Plugin => {
const pluginObj = validatePluginObject(value);
const plugin = Object.assign({}, pluginObj);
if (plugin.visitor) {
plugin.visitor = traverse.explode(clone(plugin.visitor));
}
if (plugin.inherits) {
const inheritsDescriptor = {
name: undefined,
alias: `${alias}$inherits`,
value: plugin.inherits,
options,
dirname,
};
// If the inherited plugin changes, reinstantiate this plugin.
const inherits = cache.invalidate(data =>
loadPluginDescriptor(inheritsDescriptor, data.envName),
);
plugin.pre = chain(inherits.pre, plugin.pre);
plugin.post = chain(inherits.post, plugin.post);
plugin.manipulateOptions = chain(
inherits.manipulateOptions,
plugin.manipulateOptions,
);
plugin.visitor = traverse.visitors.merge([
inherits.visitor || {},
plugin.visitor || {},
]);
}
return new Plugin(plugin, options, alias);
},
);
/**
* Generate a config object that will act as the root of a new nested config.
*/
const loadPresetDescriptor = (
descriptor: BasicDescriptor,
envName: string,
): MergeOptions => {
return instantiatePreset(loadDescriptor(descriptor, { envName }));
};
const instantiatePreset = makeWeakCache(
({ value, dirname, alias }: LoadedDescriptor): MergeOptions => {
return {
type: "preset",
options: validate("preset", value),
alias,
dirname,
};
},
);
/**
* Given a plugin/preset item, resolve it into a standard format.
*/
function createDescriptor(
pair: PluginItem,
resolver,
dirname,
{
index,
alias,
ownPass,
}: {
index: number,
alias: string,
ownPass?: boolean,
},
): BasicDescriptor {
let name;
let options;
let value = pair;
if (Array.isArray(value)) {
if (value.length === 3) {
// $FlowIgnore - Flow doesn't like the multiple tuple types.
[value, options, name] = value;
} else {
[value, options] = value;
}
}
let filepath = null;
if (typeof value === "string") {
({ filepath, value } = resolver(value, dirname));
}
if (!value) {
throw new Error(`Unexpected falsy value: ${String(value)}`);
}
if (typeof value === "object" && value.__esModule) {
if (value.default) {
value = value.default;
} else {
throw new Error("Must export a default export when using ES6 modules.");
}
}
if (typeof value !== "object" && typeof value !== "function") {
throw new Error(
`Unsupported format: ${typeof value}. Expected an object or a function.`,
);
}
if (filepath !== null && typeof value === "object" && value) {
// We allow object values for plugins/presets nested directly within a
// config object, because it can be useful to define them in nested
// configuration contexts.
throw new Error(
"Plugin/Preset files are not allowed to export objects, only functions.",
);
}
return {
name,
alias: filepath || `${alias}$${index}`,
value,
options,
dirname,
ownPass,
};
}
function chain(a, b) {
const fns = [a, b].filter(Boolean);
if (fns.length <= 1) return fns[0];
return function(...args) {
for (const fn of fns) {
fn.apply(this, args);
}
};
}

View File

@@ -1,100 +1,6 @@
// @flow
import {
assertString,
assertFunction,
assertObject,
type ValidatorSet,
type Validator,
} from "./option-assertions";
// Note: The casts here are just meant to be static assertions to make sure
// that the assertion functions actually assert that the value's type matches
// the declared types.
const VALIDATORS: ValidatorSet = {
name: (assertString: Validator<$PropertyType<PluginObject, "name">>),
manipulateOptions: (assertFunction: Validator<
$PropertyType<PluginObject, "manipulateOptions">,
>),
pre: (assertFunction: Validator<$PropertyType<PluginObject, "pre">>),
post: (assertFunction: Validator<$PropertyType<PluginObject, "post">>),
inherits: (assertFunction: Validator<
$PropertyType<PluginObject, "inherits">,
>),
visitor: (assertVisitorMap: Validator<
$PropertyType<PluginObject, "visitor">,
>),
parserOverride: (assertFunction: Validator<
$PropertyType<PluginObject, "parserOverride">,
>),
generatorOverride: (assertFunction: Validator<
$PropertyType<PluginObject, "generatorOverride">,
>),
};
function assertVisitorMap(key: string, value: mixed): VisitorMap {
const obj = assertObject(key, value);
if (obj) {
Object.keys(obj).forEach(prop => assertVisitorHandler(prop, obj[prop]));
if (obj.enter || obj.exit) {
throw new Error(
`.${key} cannot contain catch-all "enter" or "exit" handlers. Please target individual nodes.`,
);
}
}
return (obj: any);
}
function assertVisitorHandler(
key: string,
value: mixed,
): VisitorHandler | void {
if (value && typeof value === "object") {
Object.keys(value).forEach(handler => {
if (handler !== "enter" && handler !== "exit") {
throw new Error(
`.visitor["${key}"] may only have .enter and/or .exit handlers.`,
);
}
});
} else if (typeof value !== "function") {
throw new Error(`.visitor["${key}"] must be a function`);
}
return (value: any);
}
type VisitorHandler = Function | { enter?: Function, exit?: Function };
export type VisitorMap = {
[string]: VisitorHandler,
};
export type PluginObject = {
name?: string,
manipulateOptions?: Function,
pre?: Function,
post?: Function,
inherits?: Function,
visitor?: VisitorMap,
parserOverride?: Function,
generatorOverride?: Function,
};
export function validatePluginObject(obj: {}): PluginObject {
Object.keys(obj).forEach(key => {
const validator = VALIDATORS[key];
if (validator) validator(key, obj[key]);
else throw new Error(`.${key} is not a valid Plugin property`);
});
return (obj: any);
}
import type { PluginObject } from "./validation/plugins";
export default class Plugin {
key: ?string;

View File

@@ -0,0 +1,95 @@
import {
assertString,
assertFunction,
assertObject,
type ValidatorSet,
type Validator,
} from "./option-assertions";
// Note: The casts here are just meant to be static assertions to make sure
// that the assertion functions actually assert that the value's type matches
// the declared types.
const VALIDATORS: ValidatorSet = {
name: (assertString: Validator<$PropertyType<PluginObject, "name">>),
manipulateOptions: (assertFunction: Validator<
$PropertyType<PluginObject, "manipulateOptions">,
>),
pre: (assertFunction: Validator<$PropertyType<PluginObject, "pre">>),
post: (assertFunction: Validator<$PropertyType<PluginObject, "post">>),
inherits: (assertFunction: Validator<
$PropertyType<PluginObject, "inherits">,
>),
visitor: (assertVisitorMap: Validator<
$PropertyType<PluginObject, "visitor">,
>),
parserOverride: (assertFunction: Validator<
$PropertyType<PluginObject, "parserOverride">,
>),
generatorOverride: (assertFunction: Validator<
$PropertyType<PluginObject, "generatorOverride">,
>),
};
function assertVisitorMap(key: string, value: mixed): VisitorMap {
const obj = assertObject(key, value);
if (obj) {
Object.keys(obj).forEach(prop => assertVisitorHandler(prop, obj[prop]));
if (obj.enter || obj.exit) {
throw new Error(
`.${key} cannot contain catch-all "enter" or "exit" handlers. Please target individual nodes.`,
);
}
}
return (obj: any);
}
function assertVisitorHandler(
key: string,
value: mixed,
): VisitorHandler | void {
if (value && typeof value === "object") {
Object.keys(value).forEach(handler => {
if (handler !== "enter" && handler !== "exit") {
throw new Error(
`.visitor["${key}"] may only have .enter and/or .exit handlers.`,
);
}
});
} else if (typeof value !== "function") {
throw new Error(`.visitor["${key}"] must be a function`);
}
return (value: any);
}
type VisitorHandler = Function | { enter?: Function, exit?: Function };
export type VisitorMap = {
[string]: VisitorHandler,
};
export type PluginObject = {
name?: string,
manipulateOptions?: Function,
pre?: Function,
post?: Function,
inherits?: Function,
visitor?: VisitorMap,
parserOverride?: Function,
generatorOverride?: Function,
};
export function validatePluginObject(obj: {}): PluginObject {
Object.keys(obj).forEach(key => {
const validator = VALIDATORS[key];
if (validator) validator(key, obj[key]);
else throw new Error(`.${key} is not a valid Plugin property`);
});
return (obj: any);
}

View File

@@ -4,7 +4,7 @@ export { default as File } from "./transformation/file/file";
export {
default as buildExternalHelpers,
} from "./tools/build-external-helpers";
export { resolvePlugin, resolvePreset } from "./config/loading/files";
export { resolvePlugin, resolvePreset } from "./config/files";
export { version } from "../package.json";
export { getEnv } from "./config/helpers/environment";

View File

@@ -6,6 +6,7 @@ import convertSourceMap, { typeof Converter } from "convert-source-map";
import { parse } from "babylon";
import { codeFrameColumns } from "@babel/code-frame";
import File from "./file/file";
import generateMissingPluginMessage from "./util/missing-plugin-helper";
const shebangRegex = /^#!.*/;
@@ -88,21 +89,27 @@ function parser(pluginPasses, options, code) {
}
throw new Error("More than one plugin attempted to override parsing.");
} catch (err) {
const loc = err.loc;
const { loc, missingPlugin } = err;
if (loc) {
err.loc = null;
err.message =
`${options.filename || "unknown"}: ${err.message}\n` +
codeFrameColumns(
code,
{
start: {
line: loc.line,
column: loc.column + 1,
},
const codeFrame = codeFrameColumns(
code,
{
start: {
line: loc.line,
column: loc.column + 1,
},
options,
);
},
options,
);
if (missingPlugin) {
err.message =
`${options.filename || "unknown"}: ` +
generateMissingPluginMessage(missingPlugin[0], loc, codeFrame);
} else {
err.message =
`${options.filename || "unknown"}: ${err.message}\n\n` + codeFrame;
}
}
throw err;
}

View File

@@ -0,0 +1,236 @@
// @flow
const pluginNameMap = {
asyncGenerators: {
syntax: {
name: "@babel/plugin-syntax-async-generators",
url: "https://git.io/vb4SY",
},
transform: {
name: "@babel/plugin-proposal-async-generator-functions",
url: "https://git.io/vb4yp",
},
},
classProperties: {
syntax: {
name: "@babel/plugin-syntax-class-properties",
url: "https://git.io/vb4yQ",
},
transform: {
name: "@babel/plugin-proposal-class-properties",
url: "https://git.io/vb4SL",
},
},
decorators: {
syntax: {
name: "@babel/plugin-syntax-decorators",
url: "https://git.io/vb4y9",
},
transform: {
name: "@babel/plugin-proposal-decorators",
url: "https://git.io/vb4ST",
},
},
doExpressions: {
syntax: {
name: "@babel/plugin-syntax-do-expressions",
url: "https://git.io/vb4yh",
},
transform: {
name: "@babel/plugin-proposal-do-expressions",
url: "https://git.io/vb4S3",
},
},
dynamicImport: {
syntax: {
name: "@babel/plugin-syntax-dynamic-import",
url: "https://git.io/vb4Sv",
},
},
exportDefaultFrom: {
syntax: {
name: "@babel/plugin-syntax-export-default-from",
url: "https://git.io/vb4SO",
},
transform: {
name: "@babel/plugin-proposal-export-default-from",
url: "https://git.io/vb4yH",
},
},
exportNamespaceFrom: {
syntax: {
name: "@babel/plugin-syntax-export-namespace-from",
url: "https://git.io/vb4Sf",
},
transform: {
name: "@babel/plugin-proposal-export-namespace-from",
url: "https://git.io/vb4SG",
},
},
flow: {
syntax: {
name: "@babel/plugin-syntax-flow",
url: "https://git.io/vb4yb",
},
transform: {
name: "@babel/plugin-transform-flow-strip-types",
url: "https://git.io/vb49g",
},
},
functionBind: {
syntax: {
name: "@babel/plugin-syntax-function-bind",
url: "https://git.io/vb4y7",
},
transform: {
name: "@babel/plugin-proposal-function-bind",
url: "https://git.io/vb4St",
},
},
functionSent: {
syntax: {
name: "@babel/plugin-syntax-function-sent",
url: "https://git.io/vb4yN",
},
transform: {
name: "@babel/plugin-proposal-function-sent",
url: "https://git.io/vb4SZ",
},
},
importMeta: {
syntax: {
name: "@babel/plugin-syntax-import-meta",
url: "https://git.io/vbKK6",
},
},
jsx: {
syntax: {
name: "@babel/plugin-syntax-jsx",
url: "https://git.io/vb4yA",
},
transform: {
name: "@babel/plugin-transform-react-jsx",
url: "https://git.io/vb4yd",
},
},
nullishCoalescingOperator: {
syntax: {
name: "@babel/plugin-syntax-nullish-coalescing-operator",
url: "https://git.io/vb4yx",
},
transform: {
name: "@babel/plugin-proposal-nullish-coalescing-operator",
url: "https://git.io/vb4Se",
},
},
numericSeparator: {
syntax: {
name: "@babel/plugin-syntax-numeric-separator",
url: "https://git.io/vb4Sq",
},
transform: {
name: "@babel/plugin-proposal-numeric-separator",
url: "https://git.io/vb4yS",
},
},
objectRestSpread: {
syntax: {
name: "@babel/plugin-syntax-object-rest-spread",
url: "https://git.io/vb4y5",
},
transform: {
name: "@babel/plugin-proposal-object-rest-spread",
url: "https://git.io/vb4Ss",
},
},
optionalCatchBinding: {
syntax: {
name: "@babel/plugin-syntax-optional-catch-binding",
url: "https://git.io/vb4Sn",
},
transform: {
name: "@babel/plugin-proposal-optional-catch-binding",
url: "https://git.io/vb4SI",
},
},
optionalChaining: {
syntax: {
name: "@babel/plugin-syntax-optional-chaining",
url: "https://git.io/vb4Sc",
},
transform: {
name: "@babel/plugin-proposal-optional-chaining",
url: "https://git.io/vb4Sk",
},
},
pipelineOperator: {
syntax: {
name: "@babel/plugin-syntax-pipeline-operator",
url: "https://git.io/vb4yj",
},
transform: {
name: "@babel/plugin-proposal-pipeline-operator",
url: "https://git.io/vb4SU",
},
},
throwExpressions: {
syntax: {
name: "@babel/plugin-syntax-throw-expressions",
url: "https://git.io/vb4SJ",
},
transform: {
name: "@babel/plugin-proposal-throw-expressions",
url: "https://git.io/vb4yF",
},
},
typescript: {
syntax: {
name: "@babel/plugin-syntax-typescript",
url: "https://git.io/vb4SC",
},
transform: {
name: "@babel/plugin-transform-typescript",
url: "https://git.io/vb4Sm",
},
},
};
const getNameURLCombination = ({ name, url }) => `${name} (${url})`;
/*
Returns a string of the format:
Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):
[code frame]
Add [npm package name] ([url]) to the 'plugins' section of your Babel config
to enable [parsing|transformation].
*/
export default function generateMissingPluginMessage(
missingPluginName: string,
loc: { line: number, column: number },
codeFrame: string,
): string {
let helpMessage =
`Support for the experimental syntax '${missingPluginName}' isn't currently enabled ` +
`(${loc.line}:${loc.column + 1}):\n\n` +
codeFrame;
const pluginInfo = pluginNameMap[missingPluginName];
if (pluginInfo) {
const { syntax: syntaxPlugin, transform: transformPlugin } = pluginInfo;
if (syntaxPlugin) {
if (transformPlugin) {
const transformPluginInfo = getNameURLCombination(transformPlugin);
helpMessage +=
`\n\nAdd ${transformPluginInfo} to the 'plugins' section of your Babel config ` +
`to enable transformation.`;
} else {
const syntaxPluginInfo = getNameURLCombination(syntaxPlugin);
helpMessage +=
`\n\nAdd ${syntaxPluginInfo} to the 'plugins' section of your Babel config ` +
`to enable parsing.`;
}
}
}
return helpMessage;
}

View File

@@ -599,4 +599,52 @@ describe("api", function() {
assert.ok(script.indexOf("typeof") >= 0);
});
});
describe("handle parsing errors", function() {
const options = {
babelrc: false,
};
it("only syntax plugin available", function(done) {
babel.transformFile(
__dirname + "/fixtures/api/parsing-errors/only-syntax/file.js",
options,
function(err) {
assert.ok(
RegExp(
"Support for the experimental syntax 'dynamicImport' isn't currently enabled \\(1:9\\):",
).exec(err.message),
);
assert.ok(
RegExp(
"Add @babel/plugin-syntax-dynamic-import \\(https://git.io/vb4Sv\\) to the " +
"'plugins' section of your Babel config to enable parsing.",
).exec(err.message),
);
done();
},
);
});
it("both syntax and transform plugin available", function(done) {
babel.transformFile(
__dirname + "/fixtures/api/parsing-errors/syntax-and-transform/file.js",
options,
function(err) {
assert.ok(
RegExp(
"Support for the experimental syntax 'asyncGenerators' isn't currently enabled \\(1:15\\):",
).exec(err.message),
);
assert.ok(
RegExp(
"Add @babel/plugin-proposal-async-generator-functions \\(https://git.io/vb4yp\\) to the " +
"'plugins' section of your Babel config to enable transformation.",
).exec(err.message),
);
done();
},
);
});
});
});

View File

@@ -194,17 +194,50 @@ describe("buildConfigChain", function() {
assert.notEqual(opts1.plugins[0], opts2.plugins[1]);
});
it("should cache the env options by identity", () => {
const env = {
foo: {
plugins: plugins1,
it("should cache the env plugins by identity", () => {
const plugins = [() => ({})];
const opts1 = loadOptions({
envName: "foo",
env: {
foo: {
plugins,
},
},
};
});
const opts2 = loadOptions({
envName: "foo",
env: {
foo: {
plugins,
},
},
});
const opts1 = loadOptions({ envName: "foo", env });
assert.equal(opts1.plugins.length, 1);
assert.equal(opts2.plugins.length, 1);
assert.equal(opts1.plugins[0], opts2.plugins[0]);
});
env.foo.plugins = plugins2;
const opts2 = loadOptions({ envName: "foo", env });
it("should cache the env presets by identity", () => {
const presets = [() => ({ plugins: [() => ({})] })];
const opts1 = loadOptions({
envName: "foo",
env: {
foo: {
presets,
},
},
});
const opts2 = loadOptions({
envName: "foo",
env: {
foo: {
presets,
},
},
});
assert.equal(opts1.plugins.length, 1);
assert.equal(opts2.plugins.length, 1);

View File

@@ -0,0 +1 @@
var $ = import("jquery");

View File

@@ -0,0 +1,4 @@
async function* agf() {
await 1;
yield 2;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/generator",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Turns an AST into code.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -11,14 +11,14 @@
"lib"
],
"dependencies": {
"@babel/types": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.36",
"jsesc": "^2.5.1",
"lodash": "^4.2.0",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
},
"devDependencies": {
"@babel/helper-fixtures": "7.0.0-beta.35",
"babylon": "7.0.0-beta.35"
"@babel/helper-fixtures": "7.0.0-beta.36",
"babylon": "7.0.0-beta.36"
}
}

View File

@@ -420,9 +420,11 @@ export function ObjectTypeIndexer(node: Object) {
}
this._variance(node);
this.token("[");
this.print(node.id, node);
this.token(":");
this.space();
if (node.id) {
this.print(node.id, node);
this.token(":");
this.space();
}
this.print(node.key, node);
this.token("]");
this.token(":");

View File

@@ -7,3 +7,5 @@ type T = { ...U, p: V, };
type T = { ...{}|{ p: V, }};
type T = { foo(): number }
type T = { foo: () => number }
type T = { [string]: U };
type T = { [param: string]: U };

View File

@@ -22,3 +22,9 @@ type T = {
type T = {
foo: () => number
};
type T = {
[string]: U
};
type T = {
[param: string]: U
};

View File

@@ -98,7 +98,7 @@ import type { foo, bar } from "baz";
import type { foo as bar } from "baz";
import type from "foo";
import type, { foo } from "bar";
import type * as namespace from "bar";
import typeof * as namespace from "bar";
import { type Foo } from "bar";
import { typeof Foo } from "bar";
import { type Foo as Bar } from "bar";

View File

@@ -221,7 +221,7 @@ import type { foo, bar } from "baz";
import type { foo as bar } from "baz";
import type from "foo";
import type, { foo } from "bar";
import type * as namespace from "bar";
import typeof * as namespace from "bar";
import { type Foo } from "bar";
import { typeof Foo } from "bar";
import { type Foo as Bar } from "bar";

View File

@@ -2,5 +2,6 @@ abstract class C {}
declare abstract class C {}
export abstract class C {}
// `export abstract class { }` is not valid.
// `export default abstract class C { }` is not valid.
export default abstract class { }
export default abstract class C { }
// `abstract class` is not valid as an expression.

View File

@@ -3,5 +3,6 @@ abstract class C {}
declare abstract class C {}
export abstract class C {} // `export abstract class { }` is not valid.
// `export default abstract class C { }` is not valid.
// `abstract class` is not valid as an expression.
export default abstract class {}
export default abstract class C {} // `abstract class` is not valid as an expression.

View File

@@ -1,4 +1,4 @@
{
"sourceType": "module",
"plugins": ["typescript", "classProperties"]
"plugins": ["typescript"]
}

View File

@@ -1,11 +1,11 @@
{
"name": "@babel/helper-annotate-as-pure",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to annotate paths and nodes with #__PURE__ comment",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-annotate-as-pure",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35"
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "@babel/helper-bindify-decorators",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to bindify decorators",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-bindify-decorators",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "@babel/helper-builder-binary-assignment-operator-visitor",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to build binary assignment operator visitors",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-builder-binary-assignment-operator-visitor",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-explode-assignable-expression": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-explode-assignable-expression": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "@babel/helper-builder-react-jsx",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to build react jsx",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-builder-react-jsx",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.36",
"esutils": "^2.0.0"
}
}

View File

@@ -1,13 +1,13 @@
{
"name": "@babel/helper-call-delegate",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to call delegate",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-call-delegate",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-hoist-variables": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-hoist-variables": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,13 +1,13 @@
{
"name": "@babel/helper-define-map",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to define a map",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-define-map",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-function-name": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35",
"@babel/helper-function-name": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36",
"lodash": "^4.2.0"
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "@babel/helper-explode-assignable-expression",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to explode an assignable expression",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-explode-assignable-expression",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,13 +1,13 @@
{
"name": "@babel/helper-explode-class",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to explode class",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-explode-class",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-bindify-decorators": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-bindify-decorators": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-fixtures",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to support fixtures",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"license": "MIT",

View File

@@ -1,13 +1,13 @@
{
"name": "@babel/helper-function-name",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to change the property 'name' of every function",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-function-name",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-get-function-arity": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-get-function-arity": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,11 +1,11 @@
{
"name": "@babel/helper-get-function-arity",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to get function arity",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-get-function-arity",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35"
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,11 +1,11 @@
{
"name": "@babel/helper-hoist-variables",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to hoist variables",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-hoist-variables",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35"
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-module-imports",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel helper functions for inserting module loads",
"author": "Logan Smyth <loganfsmyth@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,10 +8,10 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-module-imports",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.36",
"lodash": "^4.2.0"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-module-transforms",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel helper functions for implementing ES6 module transformations",
"author": "Logan Smyth <loganfsmyth@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,10 +8,10 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-module-transforms",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-module-imports": "7.0.0-beta.35",
"@babel/helper-simple-access": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35",
"@babel/helper-module-imports": "7.0.0-beta.36",
"@babel/helper-simple-access": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36",
"lodash": "^4.2.0"
}
}

View File

@@ -22,7 +22,7 @@ export { hasExports, isSideEffectImport, isModule };
*/
export function rewriteModuleStatementsAndPrepareHeader(
path: NodePath,
{ exportName, strict, allowTopLevelThis, strictMode, loose, noInterop },
{ exportName, strict, allowTopLevelThis, strictMode, loose, noInterop, lazy },
) {
assert(isModule(path), "Cannot process module statements in a script");
path.node.sourceType = "script";
@@ -30,6 +30,7 @@ export function rewriteModuleStatementsAndPrepareHeader(
const meta = normalizeAndLoadModuleMetadata(path, exportName, {
noInterop,
loose,
lazy,
});
if (!allowTopLevelThis) {
@@ -117,6 +118,9 @@ export function buildNamespaceInitStatements(
) {
const statements = [];
let srcNamespace = t.identifier(sourceMetadata.name);
if (sourceMetadata.lazy) srcNamespace = t.callExpression(srcNamespace, []);
for (const localName of sourceMetadata.importsNamespace) {
if (localName === sourceMetadata.name) continue;
@@ -124,7 +128,7 @@ export function buildNamespaceInitStatements(
statements.push(
template.statement`var NAME = SOURCE;`({
NAME: localName,
SOURCE: sourceMetadata.name,
SOURCE: t.cloneDeep(srcNamespace),
}),
);
}
@@ -134,17 +138,26 @@ export function buildNamespaceInitStatements(
for (const exportName of sourceMetadata.reexportNamespace) {
// Assign export to namespace object.
statements.push(
template.statement`EXPORTS.NAME = NAMESPACE;`({
(sourceMetadata.lazy
? template.statement`
Object.defineProperty(EXPORTS, "NAME", {
enumerable: true,
get: function() {
return NAMESPACE;
}
});
`
: template.statement`EXPORTS.NAME = NAMESPACE;`)({
EXPORTS: metadata.exportName,
NAME: exportName,
NAMESPACE: sourceMetadata.name,
NAMESPACE: t.cloneDeep(srcNamespace),
}),
);
}
if (sourceMetadata.reexportAll) {
const statement = buildNamespaceReexport(
metadata,
sourceMetadata.name,
t.cloneDeep(srcNamespace),
loose,
);
statement.loc = sourceMetadata.reexportAll.loc;
@@ -169,12 +182,16 @@ const getTemplateForReexport = loose => {
};
const buildReexportsFromMeta = (meta, metadata, loose) => {
const namespace = metadata.lazy
? t.callExpression(t.identifier(metadata.name), [])
: t.identifier(metadata.name);
const templateForCurrentMode = getTemplateForReexport(loose);
return Array.from(metadata.reexports, ([exportName, importName]) =>
templateForCurrentMode({
EXPORTS: meta.exportName,
EXPORT_NAME: exportName,
NAMESPACE: metadata.name,
NAMESPACE: t.cloneDeep(namespace),
IMPORT_NAME: importName,
}),
);

View File

@@ -86,7 +86,7 @@ export function isSideEffectImport(source: SourceModuleMetadata) {
export default function normalizeModuleAndLoadMetadata(
programPath: NodePath,
exportName?: string,
{ noInterop = false, loose = false } = {},
{ noInterop = false, loose = false, lazy = false } = {},
): ModuleMetadata {
if (!exportName) {
exportName = programPath.scope.generateUidIdentifier("exports").name;
@@ -94,7 +94,7 @@ export default function normalizeModuleAndLoadMetadata(
nameAnonymousExports(programPath);
const { local, source } = getModuleMetadata(programPath, loose);
const { local, source } = getModuleMetadata(programPath, { loose, lazy });
removeModuleDeclarations(programPath);
@@ -120,7 +120,10 @@ export default function normalizeModuleAndLoadMetadata(
/**
* Get metadata about the imports and exports present in this module.
*/
function getModuleMetadata(programPath: NodePath, loose: boolean) {
function getModuleMetadata(
programPath: NodePath,
{ loose, lazy }: { loose: boolean, lazy: boolean },
) {
const localData = getLocalExportMetadata(programPath, loose);
const sourceData = new Map();
@@ -146,6 +149,8 @@ function getModuleMetadata(programPath: NodePath, loose: boolean) {
reexports: new Map(),
reexportNamespace: new Set(),
reexportAll: null,
lazy: false,
};
sourceData.set(source, data);
}
@@ -249,6 +254,25 @@ function getModuleMetadata(programPath: NodePath, loose: boolean) {
}
}
for (const [source, metadata] of sourceData) {
if (
lazy !== false &&
!(isSideEffectImport(metadata) || metadata.reexportAll)
) {
if (lazy === true) {
// 'true' means that local relative files are eagerly loaded and
// dependency modules are loaded lazily.
metadata.lazy = !/\./.test(source);
} else if (Array.isArray(lazy)) {
metadata.lazy = lazy.indexOf(source);
} else if (typeof lazy === "function") {
metadata.lazy = lazy(source);
} else {
throw new Error(`.lazy must be a boolean, string array, or function`);
}
}
}
return {
local: localData,
source: sourceData,

View File

@@ -24,7 +24,7 @@ export default function rewriteLiveReferences(
imported.set(localName, [source, importName, null]);
}
for (const localName of data.importsNamespace) {
imported.set(localName, [null, null, localName]);
imported.set(localName, [source, null, localName]);
}
}
@@ -60,12 +60,18 @@ export default function rewriteLiveReferences(
scope: programPath.scope,
imported, // local / import
exported, // local name => exported name list
buildImportReference: ([source, importName, localName]) => {
if (localName) return null;
buildImportReference: ([source, importName, localName], identNode) => {
const meta = metadata.source.get(source);
const name = metadata.source.get(source).name;
if (localName) {
if (meta.lazy) identNode = t.callExpression(identNode, []);
return identNode;
}
return t.memberExpression(t.identifier(name), t.identifier(importName));
let namespace = t.identifier(meta.name);
if (meta.lazy) namespace = t.callExpression(namespace, []);
return t.memberExpression(namespace, t.identifier(importName));
},
});
}
@@ -172,7 +178,7 @@ const rewriteReferencesVisitor = {
const importData = imported.get(localName);
if (importData) {
const ref = buildImportReference(importData) || path.node;
const ref = buildImportReference(importData, path.node);
if (path.parentPath.isCallExpression({ callee: path.node })) {
path.replaceWith(t.sequenceExpression([t.numericLiteral(0), ref]));
@@ -225,8 +231,7 @@ const rewriteReferencesVisitor = {
const assignment = path.node;
if (importData) {
assignment.left =
buildImportReference(importData) || assignment.left;
assignment.left = buildImportReference(importData, assignment.left);
assignment.right = t.sequenceExpression([
assignment.right,

View File

@@ -1,11 +1,11 @@
{
"name": "@babel/helper-optimise-call-expression",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to optimise call expression",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-optimise-call-expression",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/types": "7.0.0-beta.35"
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,11 +1,11 @@
{
"name": "@babel/helper-plugin-test-runner",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to support test runner",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-plugin-test-runner",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.35"
"@babel/helper-transform-fixture-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-regex",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to check for literal RegEx",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-regex",
"license": "MIT",

View File

@@ -1,15 +1,15 @@
{
"name": "@babel/helper-remap-async-to-generator",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to remap async functions to generators",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-remap-async-to-generator",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-annotate-as-pure": "7.0.0-beta.35",
"@babel/helper-wrap-function": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-annotate-as-pure": "7.0.0-beta.36",
"@babel/helper-wrap-function": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,14 +1,14 @@
{
"name": "@babel/helper-replace-supers",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper function to replace supers",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-replace-supers",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-optimise-call-expression": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-optimise-call-expression": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-simple-access",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel helper for ensuring that access to a given value is performed through simple accesses",
"author": "Logan Smyth <loganfsmyth@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,8 +8,8 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-simple-access",
"main": "lib/index.js",
"dependencies": {
"@babel/template": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36",
"lodash": "^4.2.0"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helper-transform-fixture-test-runner",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Transform test runner for @babel/helper-fixtures module",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,10 +8,10 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-transform-fixture-test-runner",
"main": "lib/index.js",
"dependencies": {
"@babel/code-frame": "7.0.0-beta.35",
"@babel/core": "7.0.0-beta.35",
"@babel/helper-fixtures": "7.0.0-beta.35",
"@babel/polyfill": "7.0.0-beta.35",
"@babel/code-frame": "7.0.0-beta.36",
"@babel/core": "7.0.0-beta.36",
"@babel/helper-fixtures": "7.0.0-beta.36",
"@babel/polyfill": "7.0.0-beta.36",
"chai": "^4.1.0",
"lodash": "^4.2.0",
"resolve": "^1.3.2",

View File

@@ -1,14 +1,14 @@
{
"name": "@babel/helper-wrap-function",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Helper to wrap functions inside a function call.",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-wrap-function",
"license": "MIT",
"main": "lib/index.js",
"dependencies": {
"@babel/helper-function-name": "7.0.0-beta.35",
"@babel/template": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/helper-function-name": "7.0.0-beta.36",
"@babel/template": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
}
}

View File

@@ -89,11 +89,8 @@ function plainFunction(path: NodePath, callId: Object) {
});
if (isDeclaration) {
const basePath = path.parentPath.isExportDeclaration()
? path.parentPath
: path;
basePath.insertAfter(container[1]);
path.replaceWith(container[0]);
path.insertAfter(container[1]);
} else {
const retFunction = container.callee.body.body[1].argument;
if (!functionId) {

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/helpers",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Collection of helper functions used by Babel transforms.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -8,11 +8,11 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helpers",
"main": "lib/index.js",
"dependencies": {
"@babel/template": "7.0.0-beta.35",
"@babel/traverse": "7.0.0-beta.35",
"@babel/types": "7.0.0-beta.35"
"@babel/template": "7.0.0-beta.36",
"@babel/traverse": "7.0.0-beta.36",
"@babel/types": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -425,6 +425,51 @@ helpers.inheritsLoose = defineHelper(`
}
`);
// Based on https://github.com/WebReflection/babel-plugin-transform-builtin-classes
helpers.wrapNativeSuper = defineHelper(`
var _gPO = Object.getPrototypeOf || function _gPO(o) { return o.__proto__ };
var _sPO = Object.setPrototypeOf || function _sPO(o, p) { o.__proto__ = p; return o };
var _construct = (typeof Reflect === "object" && Reflect.construct) ||
function _construct(Parent, args, Class) {
var Constructor, a = [null];
a.push.apply(a, args);
Constructor = Parent.bind.apply(Parent, a);
return _sPO(new Constructor, Class.prototype);
};
var _cache = typeof Map === "function" && new Map();
export default function _wrapNativeSuper(Class) {
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writeable: true,
configurable: true,
}
});
return _sPO(
Wrapper,
_sPO(
function Super() {
return _construct(Class, arguments, _gPO(this).constructor);
},
Class
)
);
}
`);
helpers.instanceof = defineHelper(`
export default function _instanceof(left, right) {
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/node",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Babel command line",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@@ -16,8 +16,8 @@
"compiler"
],
"dependencies": {
"@babel/polyfill": "7.0.0-beta.35",
"@babel/register": "7.0.0-beta.35",
"@babel/polyfill": "7.0.0-beta.36",
"@babel/register": "7.0.0-beta.36",
"commander": "^2.8.1",
"fs-readdir-recursive": "^1.0.0",
"lodash": "^4.2.0",
@@ -25,11 +25,11 @@
"v8flags": "^3.0.0"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-fixtures": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-fixtures": "7.0.0-beta.36"
},
"bin": {
"babel-node": "./bin/babel-node.js"

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-check-constants",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile ES2015 constants to ES5",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-check-constants",
"license": "MIT",
@@ -9,10 +9,10 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-external-helpers",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "This plugin contains helper functions thatll be placed at the top of the generated code",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-external-helpers",
"license": "MIT",
@@ -9,10 +9,10 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-async-generator-functions",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Turn async generator functions into ES2015 generators",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-async-generator-functions",
"license": "MIT",
@@ -9,14 +9,14 @@
"babel-plugin"
],
"dependencies": {
"@babel/helper-remap-async-to-generator": "7.0.0-beta.35",
"@babel/plugin-syntax-async-generators": "7.0.0-beta.35"
"@babel/helper-remap-async-to-generator": "7.0.0-beta.36",
"@babel/plugin-syntax-async-generators": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-class-properties",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "This plugin transforms static class properties as well as properties declared with the property initializer syntax",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-class-properties",
"license": "MIT",
@@ -9,14 +9,14 @@
"babel-plugin"
],
"dependencies": {
"@babel/helper-function-name": "7.0.0-beta.35",
"@babel/plugin-syntax-class-properties": "7.0.0-beta.35"
"@babel/helper-function-name": "7.0.0-beta.36",
"@babel/plugin-syntax-class-properties": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -228,15 +228,9 @@ export default function(api, options) {
if (path.isClassExpression()) {
path.scope.push({ id: ref });
path.replaceWith(t.assignmentExpression("=", ref, path.node));
} else {
// path.isClassDeclaration()
if (!path.node.id) {
path.node.id = ref;
}
if (path.parentPath.isExportDeclaration()) {
path = path.parentPath;
}
} else if (!path.node.id) {
// Anonymous class declaration
path.node.id = ref;
}
path.insertAfter(nodes);

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-decorators",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"author": "Logan Smyth <loganfsmyth@gmail.com>",
"license": "MIT",
"description": "Compile class and object decorators to ES5",
@@ -12,13 +12,13 @@
"decorators"
],
"dependencies": {
"@babel/plugin-syntax-decorators": "7.0.0-beta.35"
"@babel/plugin-syntax-decorators": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -27,6 +27,8 @@ const buildGetObjectInitializer = template(`
`);
export default function() {
const WARNING_CALLS = new WeakSet();
/**
* If the decorator expressions are non-identifiers, hoist them to before the class so we can be sure
* that they are evaluated in order.
@@ -151,11 +153,14 @@ export default function() {
t.blockStatement([t.returnStatement(node.value)]),
)
: t.nullLiteral();
node.value = t.callExpression(
state.addHelper("initializerWarningHelper"),
[descriptor, t.thisExpression()],
);
WARNING_CALLS.add(node.value);
acc = acc.concat([
t.assignmentExpression(
"=",
@@ -255,10 +260,7 @@ export default function() {
},
AssignmentExpression(path, state) {
if (!path.get("left").isMemberExpression()) return;
if (!path.get("left.property").isIdentifier()) return;
if (!path.get("right").isCallExpression()) return;
if (!path.get("right.callee").isIdentifier()) return;
if (!WARNING_CALLS.has(path.node.right)) return;
path.replaceWith(
t.callExpression(state.addHelper("initializerDefineProperty"), [

View File

@@ -0,0 +1,22 @@
function generateAsyncAction(type) {
type = type.toUpperCase()
const request = createAction(type+'_REQUEST',
undefined, requestMetaCreator
)
request.request = request // crazy
request.success = createAction(type+'_SUCCESS', undefined, metaCreator)
request.error = createAction(type+'_ERROR', undefined, metaCreator)
request.cancel = createAction(type+'_CANCEL', undefined, metaCreator)
request.progress = createAction(type+'_PROGRESS', undefined, metaCreator)
request.process = createAction(type+'_PROCESS', undefined, metaCreator)
return request
}
class A extends B {
constructor(timestamp) {
super()
this.timestamp = timestamp
this.moment = moment(timestamp)
}
}

View File

@@ -0,0 +1,41 @@
function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return right[Symbol.hasInstance](left); } else { return left instanceof right; } }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function generateAsyncAction(type) {
type = type.toUpperCase();
var request = createAction(type + '_REQUEST', undefined, requestMetaCreator);
request.request = request; // crazy
request.success = createAction(type + '_SUCCESS', undefined, metaCreator);
request.error = createAction(type + '_ERROR', undefined, metaCreator);
request.cancel = createAction(type + '_CANCEL', undefined, metaCreator);
request.progress = createAction(type + '_PROGRESS', undefined, metaCreator);
request.process = createAction(type + '_PROCESS', undefined, metaCreator);
return request;
}
var A =
/*#__PURE__*/
function (_B) {
_inherits(A, _B);
function A(timestamp) {
var _this;
_classCallCheck(this, A);
_this = _possibleConstructorReturn(this, (A.__proto__ || Object.getPrototypeOf(A)).call(this));
_this.timestamp = timestamp;
_this.moment = moment(timestamp);
return _this;
}
return A;
}(B);

View File

@@ -0,0 +1,3 @@
{
"presets": ["es2015", "stage-0"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-do-expressions",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile do expressions to ES5",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-do-expressions",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-do-expressions": "7.0.0-beta.35"
"@babel/plugin-syntax-do-expressions": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-export-default-from",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile export default to ES2015",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-export-default-from",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-export-default-from": "7.0.0-beta.35"
"@babel/plugin-syntax-export-default-from": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-export-namespace-from",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile export namespace to ES2015",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-export-namespace-from",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-export-namespace-from": "7.0.0-beta.35"
"@babel/plugin-syntax-export-namespace-from": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-function-bind",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile function bind operator to ES5",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-function-bind",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-function-bind": "7.0.0-beta.35"
"@babel/plugin-syntax-function-bind": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-function-sent",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile the function.sent meta propety to valid ES2015 code",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-function-sent",
"license": "MIT",
@@ -9,14 +9,14 @@
"babel-plugin"
],
"dependencies": {
"@babel/helper-wrap-function": "7.0.0-beta.35",
"@babel/plugin-syntax-function-sent": "7.0.0-beta.35"
"@babel/helper-wrap-function": "7.0.0-beta.36",
"@babel/plugin-syntax-function-sent": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-nullish-coalescing-operator",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Remove nullish coalescing operator",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-nullish-coalescing-opearator",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-nullish-coalescing-operator": "7.0.0-beta.35"
"@babel/plugin-syntax-nullish-coalescing-operator": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-numeric-separator",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Remove numeric separators from Decimal, Binary, Hex and Octal literals",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-numeric-separator",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-numeric-separator": "7.0.0-beta.35"
"@babel/plugin-syntax-numeric-separator": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-object-rest-spread",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile object rest and spread to ES5",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-object-rest-spread",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.35"
"@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-optional-catch-binding",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile optional catch bindings",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-optional-catch-binding",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.35"
"@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-optional-chaining",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Transform optional chaining operators into a series of nil checks",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-optional-chaining",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-optional-chaining": "7.0.0-beta.35"
"@babel/plugin-syntax-optional-chaining": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-pipeline-operator",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Transform pipeline operator into call expressions",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-pipeline-operator",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-pipeline-operator": "7.0.0-beta.35"
"@babel/plugin-syntax-pipeline-operator": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-proposal-throw-expressions",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Wraps Throw Expressions in an IIFE",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-throw-expressions",
"license": "MIT",
@@ -9,13 +9,13 @@
"babel-plugin"
],
"dependencies": {
"@babel/plugin-syntax-throw-expressions": "7.0.0-beta.35"
"@babel/plugin-syntax-throw-expressions": "7.0.0-beta.36"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -9,7 +9,7 @@ Compile [Unicode property escapes](https://github.com/mathiasbynens/regexpu-core
## Installation
```sh
npm install @babel/plugin-proposal-unicode-property-regex
npm install --save-dev @babel/plugin-proposal-unicode-property-regex
```
## Usage

View File

@@ -1,8 +1,9 @@
{
"name": "@babel/plugin-proposal-unicode-property-regex",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Compile Unicode property escapes in Unicode regular expressions to ES5.",
"homepage": "https://babeljs.io/",
"license": "MIT",
"main": "lib/index.js",
"engines": {
"node": ">=4"
@@ -18,14 +19,14 @@
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-unicode-property-regex",
"bugs": "https://github.com/babel/babel/issues",
"dependencies": {
"@babel/helper-regex": "7.0.0-beta.35",
"@babel/helper-regex": "7.0.0-beta.36",
"regexpu-core": "^4.1.3"
},
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35",
"@babel/helper-plugin-test-runner": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36",
"@babel/helper-plugin-test-runner": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-async-generators",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of async generator functions",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-async-generators",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-class-properties",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of class properties",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-class-properties",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-decorators",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of decorators",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-decorators",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-do-expressions",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of do expressions",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-do-expressions",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-dynamic-import",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of import()",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-dynamic-import",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-export-default-from",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of export default from",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-export-default-from",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-export-namespace-from",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of export namespace from",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-export-namespace-from",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-flow",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of the flow syntax",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-flow",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-function-bind",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of function bind",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-function-bind",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@babel/plugin-syntax-function-sent",
"version": "7.0.0-beta.35",
"version": "7.0.0-beta.36",
"description": "Allow parsing of the function.sent meta property",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-function-sent",
"license": "MIT",
@@ -9,9 +9,9 @@
"babel-plugin"
],
"peerDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
},
"devDependencies": {
"@babel/core": "7.0.0-beta.35"
"@babel/core": "7.0.0-beta.36"
}
}

Some files were not shown because too many files have changed in this diff Show More