Merge branch 'development'

Conflicts:
	VERSION
	packages/babel-cli/package.json
	packages/babel-generator/src/buffer.js
	packages/babel-runtime/package.json
	packages/babel-traverse/src/scope/index.js
	packages/babel-types/src/validators.js
	packages/babel/package.json
	packages/babel/src/generation/generators/expressions.js
	packages/babel/src/generation/generators/statements.js
	packages/babel/src/transformation/transformers/es6/tail-call.js
	packages/babel/src/transformation/transformers/es7/async-functions.js
	packages/babel/src/transformation/transformers/es7/exponentiation-operator.js
	packages/babel/src/types/retrievers.js
	packages/babel/test/fixtures/transformation/es6.tail-call/default-parameters/expected.js
	packages/babel/test/fixtures/transformation/es6.tail-call/factorial/expected.js
	packages/babel/test/fixtures/transformation/es6.tail-call/max-args/expected.js
	packages/babel/test/fixtures/transformation/es6.tail-call/recursion/expected.js
	packages/babylon/package.json
This commit is contained in:
Sebastian McKenzie 2015-10-30 00:48:36 +00:00
commit 0b88a89b87
6350 changed files with 169288 additions and 41926 deletions

View File

@ -1 +0,0 @@
packages/babel-cli/src/babel-plugin/templates

View File

@ -1,11 +0,0 @@
{
"stage": 0,
"loose": ["all"],
"blacklist": ["es6.tailCall"],
"optional": ["optimisation.flow.forOf", "bluebirdCoroutines"],
"env": {
"test": {
"auxiliaryCommentBefore": "istanbul ignore next"
}
}
}

View File

@ -1,2 +1,2 @@
packages/babel/src/transformation/templates
packages/babel-core/src/transformation/templates
scripts

View File

@ -1,31 +0,0 @@
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"rules": {
"quotes": [2, "double", "avoid-escape"],
"strict": 0,
"no-underscore-dangle": 0,
"curly": 0,
"no-multi-spaces": 0,
"key-spacing": 0,
"no-return-assign": 0,
"consistent-return": 0,
"no-shadow": 0,
"comma-dangle": 0,
"no-use-before-define": 0,
"no-empty": 0,
"new-parens": 0,
"no-cond-assign": 0,
"no-fallthrough": 0,
"new-cap": 0,
"no-loop-func": 0,
"no-unreachable": 0,
"no-labels": 0,
"no-process-exit": 0,
"camelcase": 0,
"no-console": 0
},
"env": {
"node": true
}
}

14
.flowconfig Normal file
View File

@ -0,0 +1,14 @@
[ignore]
[include]
[libs]
lib/file.js
lib/parser.js
lib/types.js
[options]
strip_root=true
[version]
0.16.0

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "vendor/traceur"]
path = vendor/traceur
url = https://github.com/google/traceur-compiler

View File

@ -13,12 +13,6 @@ _Note: Gaps between patch versions are faulty, broken or test releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.8.27
* **Bug Fix**
* Fix scope tracking of references before the declaration has been visited.
* Correctly identify parameters as binding identifiers.
## 5.8.26
* **Internal**

View File

@ -1,4 +1,4 @@
# NOTE: BEFORE OPENING AN ISSUE PLEASE SEE THE [README](https://github.com/babel/babel#readme).
# NOTE: DO NOT OPEN ISSUES FOR QUESTIONS AND SUPPORT. SEE THE README FOR MORE INFO.
----
@ -50,7 +50,7 @@ If you wish to build a copy of Babel for distribution then run:
$ make build-dist
```
and access the files from `packages/babel/dist`.
and access the files from `packages/babel-core/dist`.
#### Running tests

View File

@ -8,7 +8,9 @@ build: clean
./scripts/build.sh
build-dist: build
cd packages/babel; \
cd packages/babel-core; \
scripts/build-dist.sh
cd packages/babel-polyfill; \
scripts/build-dist.sh
cd packages/babel-runtime; \
node scripts/build-dist.js
@ -18,10 +20,10 @@ watch: clean
lint:
node node_modules/.bin/eslint packages/*/src
#flow check
clean: test-clean
rm -rf coverage
rm -rf packages/*/lib packages/babel/templates.json
test-clean:
rm -rf packages/*/test/tmp
@ -31,10 +33,6 @@ test: lint
./scripts/test.sh
make test-clean
test-browser:
./scripts/test-browser.sh
make test-clean
test-cov: clean
BABEL_ENV=test; \
make build
@ -47,7 +45,7 @@ publish:
make test
node scripts/publish.js
make clean
./scripts/build-website.sh
#./scripts/build-website.sh
bootstrap:
npm install

View File

@ -19,11 +19,13 @@
<a href="http://issuestats.com/github/babel/babel"><img alt="Issue Stats" src="http://issuestats.com/github/babel/babel/badge/issue?style=flat"></a>
</p>
----
## Looking for support?
<p align="center">
For questions and support please visit the <a href="https://babel-slack.herokuapp.com">Slack community</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
</p>
<p align="center">For questions and support please visit the <a href="https://babel-slack.herokuapp.com">Slack community</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>.</p>
<p align="center">The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.</p>
## Want to report an issue with [babeljs.io](https://babeljs.io)?
<p align="center">
For documentation and website issues please visit the <a href="https://github.com/babel/babel.github.io">babel.github.io</a> repo.

View File

@ -1 +1 @@
5.8.33
6.0.11

View File

@ -0,0 +1,9 @@
# Compiler assumptions
Babel and it's associated official transforms make some assumptions about your code. These
assumptions are only made as they're either **impossible** to take into consideration or
are extremely exotic.
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
- Built-in objects such as `Object`, `Array`, `String`, `Number`, `Boolean` etc have not been redefined.
- Standard methods on built-ins have not been redefined in a way that breaks the original contract.

40
doc/design/monorepo.md Normal file
View File

@ -0,0 +1,40 @@
# Why is Babel a monorepo?
Juggling a multimodule project over multiple repos is like trying to teach a newborn baby how to
ride a bike.
Babel follows a monorepo approach, all officially maintained modules are in the same repo.
This is quite taboo but let's look at the pros and cons:
**Pros:**
* Single lint, build, test and release process.
* Easy to coordinate changes across modules.
* Single place to report issues.
* Easier to setup a development environment.
* Tests across modules are ran together which finds bugs that touch multiple modules easier.
**Cons:**
* Codebase looks more intimidating.
* Repo is bigger in size.
* ???
## This is dumb! Nobody in open source does this!
[React](https://github.com/facebook/react/tree/master/packages), [Meteor](https://github.com/meteor/meteor/tree/devel/packages), and [Ember](https://github.com/emberjs/ember.js/tree/master/packages), among others, do this.
## Previous discussion
- [Dan Luu](http://danluu.com/monorepo/)
- [Gregory](http://gregoryszorc.com/blog/2014/09/09/on-monolithic-repositories/)
- [Szorc](http://gregoryszorc.com/blog/2015/02/17/lost-productivity-due-to-non-unified-repositories/)
- [Face](https://developers.facebooklive.com/videos/561/big-code-developer-infrastructure-at-facebook-s-scale)[book](https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/)
- [Benjamin Pollack](http://bitquabit.com/post/unorthodocs-abandon-your-dvcs-and-return-to-sanity/)
- [Benjamin Eberlei](https://qafoo.com/resources/presentations/froscon_2015/monorepos.html)
- [Simon Stewart](http://blog.rocketpoweredjetpants.com/2015/04/monorepo-one-source-code-repository-to.html)
- [Digital Ocean](https://www.digitalocean.com/company/blog/taming-your-go-dependencies/)
- [Google](http://www.infoq.com/presentations/Development-at-Google)
- [Twitter](http://git-merge.com/videos/scaling-git-at-twitter-wilhelm-bierbaum.html)
- [thedufer](http://www.reddit.com/r/programming/comments/1unehr/scaling_mercurial_at_facebook/cek9nkq)
- [Paul Hammant](http://paulhammant.com/categories.html#trunk_based_development)

5
doc/design/versioning.md Normal file
View File

@ -0,0 +1,5 @@
# How does Babel versioning work?
## Does Babel follow semver?
Yes.

View File

@ -1,4 +0,0 @@
This is a collection of documentation about babel internals, for use in development of babel.
# [Properties of nodes](/doc/node-props.md)
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec (ESTree at the time of this writing).

View File

@ -1,11 +0,0 @@
# Properties of nodes
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec ([ESTree](https://github.com/estree/estree) at the time of this writing).
## `_blockHoist`
`node._blockHoist != null` triggers the [block-hoist transformer](/src/babel/transformation/transformers/internal/block-hoist.js). Value should be `true` or an integer in the range `0..3`. `true` is equivalent to `2`. The value indicates whether the node should be hoisted and to what degree. See the source code for more detailed information.
## `_paths`
Stores a representation of a node's position in the tree and relationship to other nodes.
## `shadow`
A truthy value on a function node triggers the [shadow-functions transformer](/src/babel/transformation/transformers/internal/shadow-functions.js), which transforms the node so that it references (or inherits) `arguments` and the `this` context from the parent scope. It is invoked for arrow functions, for example.

27
lib/file.js Normal file
View File

@ -0,0 +1,27 @@
type BabelFileModulesMetadata = {
imports: Array<Object>,
exports: {
exported: Array<Object>,
specifiers: Array<Object>
}
};
type BabelFileMetadata = {
usedHelpers: Array<string>;
marked: Array<{
type: string;
message: string;
loc: Object;
}>;
modules: BabelFileModulesMetadata
};
type BabelFileResult = {
ast?: ?Object;
code?: ?string;
map?: ?Object;
ignored?: ?boolean;
metadata?: ?BabelFileMetadata;
};

10
lib/parser.js Normal file
View File

@ -0,0 +1,10 @@
type BabelParserOptions = {
strictMode?: boolean;
looseModules?: boolean;
highlightCode?: boolean;
nonStandard?: boolean;
sourceType?: "module" | "script";
filename?: string;
features?: Object;
plugins?: Object;
};

View File

@ -1,8 +1,10 @@
{
"private": true,
"license": "MIT",
"devDependencies": {
"babel": "5.8.19",
"babel": "5.8.21",
"babel-eslint": "^4.0.6",
"babel-plugin-flow-comments": "^1.0.9",
"browserify": "^11.2.0",
"bundle-collapser": "^1.2.1",
"chai": "^2.2.0",
@ -14,7 +16,7 @@
"lodash": "^3.10.0",
"matcha": "^0.6.0",
"mocha": "2.2.0",
"mocha-fixtures": "^1.0.5",
"mocha-fixtures": "^1.0.9",
"output-file-sync": "^1.1.1",
"path-exists": "^1.0.0",
"readline-sync": "^1.2.19",
@ -23,7 +25,68 @@
"shelljs": "^0.5.1",
"uglify-js": "^2.4.16"
},
"dependencies": {
"mocha-fixtures": "^1.0.9"
"babel": {
"ignore": [
"packages/babel-cli/src/babel-plugin/templates"
],
"stage": 0,
"loose": [
"all"
],
"plugins": [
"flow-comments"
],
"blacklist": [
"flow",
"es6.tailCall"
],
"optional": [
"optimisation.flow.forOf",
"bluebirdCoroutines",
"runtime"
],
"env": {
"test": {
"auxiliaryCommentBefore": "istanbul ignore next"
}
}
},
"eslintConfig": {
"parser": "babel-eslint",
"extends": "eslint:recommended",
"rules": {
"quotes": [
2,
"double",
"avoid-escape"
],
"no-var": 2,
"strict": 0,
"no-underscore-dangle": 0,
"curly": 0,
"no-multi-spaces": 0,
"key-spacing": 0,
"no-return-assign": 0,
"consistent-return": 0,
"no-shadow": 0,
"comma-dangle": 0,
"no-use-before-define": 0,
"no-empty": 0,
"new-parens": 0,
"no-cond-assign": 0,
"no-fallthrough": 0,
"new-cap": 0,
"no-loop-func": 0,
"no-unreachable": 0,
"no-labels": 0,
"no-process-exit": 0,
"camelcase": 0,
"no-console": 0,
"no-constant-condition": 0,
"no-inner-declarations": 0
},
"env": {
"node": true
}
}
}

3
packages/README.md Normal file
View File

@ -0,0 +1,3 @@
# Woah, what's going on here?
A monorepo, muhahahahahaha. See the [monorepo design doc](/doc/design/monorepo.md) for reasoning.

View File

@ -1,5 +1 @@
# babel-cli
Babel CLI
For more information please look at [babel](https://github.com/babel/babel).

View File

@ -1 +1 @@
module.exports = require("babel-core");
throw new Error("Use the `babel-core` package not `babel`.");

View File

@ -1,6 +1,6 @@
{
"name": "babel",
"version": "5.8.29",
"name": "babel-cli",
"version": "6.0.2",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
@ -8,9 +8,10 @@
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.6.21",
"babel-core": "^6.0.2",
"babel-polyfill": "^6.0.2",
"chokidar": "^1.0.0",
"commander": "^2.6.0",
"commander": "^2.8.1",
"convert-source-map": "^1.1.0",
"fs-readdir-recursive": "^0.1.0",
"glob": "^5.0.5",
@ -18,13 +19,14 @@
"output-file-sync": "^1.1.0",
"path-exists": "^1.0.0",
"path-is-absolute": "^1.0.0",
"slash": "^1.0.0",
"source-map": "^0.5.0",
"slash": "^1.0.0"
"v8flags": "^2.0.10",
"babel-runtime": "^6.0.2"
},
"bin": {
"babel": "./bin/babel.js",
"babel-node": "./bin/babel-node.js",
"babel-external-helpers": "./bin/babel-external-helpers.js",
"babel-plugin": "./bin/babel-plugin.js"
"babel-external-helpers": "./bin/babel-external-helpers.js"
}
}

View File

@ -1 +0,0 @@
module.exports = require("babel-core/polyfill");

View File

@ -1 +0,0 @@
module.exports = require("babel-core/register-without-polyfill");

View File

@ -1 +0,0 @@
module.exports = require("babel-core/register");

View File

@ -4,50 +4,64 @@ import Module from "module";
import { inspect } from "util";
import path from "path";
import repl from "repl";
import register from "babel-core/register";
import { util } from "babel-core";
import * as babel from "babel-core";
import vm from "vm";
import _ from "lodash";
import "babel-polyfill";
var program = new commander.Command("babel-node");
let program = new commander.Command("babel-node");
program.option("-e, --eval [script]", "Evaluate script");
program.option("-p, --print [code]", "Evaluate script and print result");
program.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
program.option("-o, --only [globs]", "");
program.option("-i, --ignore [globs]", "");
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx]");
program.option("-r, --stage [stage]", "Enable support for specific ECMAScript stages");
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers separated by comma to ONLY use", util.list);
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers separated by comma to NOT use", util.list);
program.option("-o, --optional [optional]", "List of optional transformers separated by comma to enable", util.list);
program.option("-w, --plugins [string]", "", util.list);
program.option("-b, --presets [string]", "", util.list);
var pkg = require("../package.json");
let pkg = require("../package.json");
program.version(pkg.version);
program.usage("[options] [ -e script | script.js ] [arguments]");
program.parse(process.argv);
//
babel.register({
extensions: program.extensions,
blacklist: program.blacklist,
whitelist: program.whitelist,
optional: program.optional,
ignore: program.ignore,
stage: program.stage,
register({
extensions: program.extensions,
ignore: program.ignore,
only: program.only,
plugins: program.plugins,
presets: program.presets,
});
//
var _eval = function (code, filename) {
let replPlugin = () => ({
visitor: {
ModuleDeclaration(path) {
throw path.buildCodeFrameError("Modules aren't supported in the REPL");
},
VariableDeclaration(path) {
if (path.node.kind !== "var") {
throw path.buildCodeFrameError("Only `var` variables are supported in the REPL");
}
}
}
});
//
let _eval = function (code, filename) {
code = code.trim();
if (!code) return undefined;
code = babel.transform(code, {
filename: filename,
blacklist: program.blacklist,
whitelist: program.whitelist,
optional: program.optional,
stage: program.stage
presets: program.presets,
plugins: (program.plugins || []).concat([replPlugin])
}).code;
return vm.runInThisContext(code, {
@ -56,13 +70,13 @@ var _eval = function (code, filename) {
};
if (program.eval || program.print) {
var code = program.eval;
let code = program.eval;
if (!code || code === true) code = program.print;
global.__filename = "[eval]";
global.__dirname = process.cwd();
var module = new Module(global.__filename);
let module = new Module(global.__filename);
module.filename = global.__filename;
module.paths = Module._nodeModulePaths(global.__dirname);
@ -70,18 +84,18 @@ if (program.eval || program.print) {
global.module = module;
global.require = module.require.bind(module);
var result = _eval(code, global.__filename);
let result = _eval(code, global.__filename);
if (program.print) {
var output = _.isString(result) ? result : inspect(result);
let output = _.isString(result) ? result : inspect(result);
process.stdout.write(output + "\n");
}
} else {
if (program.args.length) {
// slice all arguments up to the first filename since they're babel args that we handle
var args = process.argv.slice(2);
let args = process.argv.slice(2);
var i = 0;
var ignoreNext = false;
let i = 0;
let ignoreNext = false;
_.each(args, function (arg, i2) {
if (ignoreNext) {
ignoreNext = false;
@ -89,7 +103,7 @@ if (program.eval || program.print) {
}
if (arg[0] === "-") {
var parsedArg = program[arg.slice(2)];
let parsedArg = program[arg.slice(2)];
if (parsedArg && parsedArg !== true) {
ignoreNext = true;
}
@ -101,7 +115,7 @@ if (program.eval || program.print) {
args = args.slice(i);
// make the filename absolute
var filename = args[0];
let filename = args[0];
if (!pathIsAbsolute(filename)) args[0] = path.join(process.cwd(), filename);
// add back on node and concat the sliced args
@ -125,8 +139,8 @@ function replStart() {
}
function replEval(code, context, filename, callback) {
var err;
var result;
let err;
let result;
try {
if (code[0] === "(" && code[code.length - 1] === ")") {

View File

@ -3,447 +3,72 @@
* when found, before invoking the "real" _babel-node(1) executable.
*/
var path = require("path");
var args = [path.join(__dirname, "_babel-node")];
let getV8Flags = require("v8flags");
let path = require("path");
var babelArgs = process.argv.slice(2);
var userArgs;
let args = [path.join(__dirname, "_babel-node")];
let babelArgs = process.argv.slice(2);
let userArgs;
// separate node arguments from script arguments
var argSeparator = babelArgs.indexOf("--");
let argSeparator = babelArgs.indexOf("--");
if (argSeparator > -1) {
userArgs = babelArgs.slice(argSeparator); // including the --
babelArgs = babelArgs.slice(0, argSeparator);
}
babelArgs.forEach(function(arg){
var flag = arg.split("=")[0];
getV8Flags(function (err, v8Flags) {
babelArgs.forEach(function(arg){
let flag = arg.split("=")[0];
switch (flag) {
case "-d":
args.unshift("--debug");
break;
switch (flag) {
case "-d":
args.unshift("--debug");
break;
case "debug":
case "--debug":
case "--debug-brk":
args.unshift(arg);
break;
case "-gc":
case "--expose-gc":
args.unshift("--expose-gc");
break;
case "--use_strict":
case "--es_staging":
case "--harmony":
case "--harmony_shipping":
case "--harmony_modules":
case "--harmony_arrays":
case "--harmony_array_includes":
case "--harmony_regexps":
case "--harmony_arrow_functions":
case "--harmony_proxies":
case "--harmony_sloppy":
case "--harmony_unicode":
case "--harmony_tostring":
case "--harmony_numeric_literals":
case "--harmony_strings":
case "--harmony_scoping":
case "--harmony_classes":
case "--harmony_object_literals":
case "--harmony_templates":
case "--harmony_rest_parameters":
case "--harmony_generators":
case "--compiled_keyed_generic_loads":
case "--pretenuring_call_new":
case "--allocation_site_pretenuring":
case "--trace_pretenuring":
case "--trace_pretenuring_statistics":
case "--track_fields":
case "--track_double_fields":
case "--track_heap_object_fields":
case "--track_computed_fields":
case "--track_field_types":
case "--smi_binop":
case "--vector_ics":
case "--optimize_for_size":
case "--unbox_double_arrays":
case "--string_slices":
case "--crankshaft":
case "--hydrogen_filter":
case "--use_gvn":
case "--gvn_iterations":
case "--use_canonicalizing":
case "--use_inlining":
case "--use_escape_analysis":
case "--use_allocation_folding":
case "--use_local_allocation_folding":
case "--use_write_barrier_elimination":
case "--max_inlining_levels":
case "--max_inlined_source_size":
case "--max_inlined_nodes":
case "--max_inlined_nodes_cumulative":
case "--loop_invariant_code_motion":
case "--fast_math":
case "--collect_megamorphic_maps_from_stub_cache":
case "--hydrogen_stats":
case "--trace_check_elimination":
case "--trace_hydrogen":
case "--trace_hydrogen_filter":
case "--trace_hydrogen_stubs":
case "--trace_hydrogen_file":
case "--trace_phase":
case "--trace_inlining":
case "--trace_load_elimination":
case "--trace_store_elimination":
case "--trace_alloc":
case "--trace_all_uses":
case "--trace_range":
case "--trace_gvn":
case "--trace_representation":
case "--trace_removable_simulates":
case "--trace_escape_analysis":
case "--trace_allocation_folding":
case "--trace_track_allocation_sites":
case "--trace_migration":
case "--trace_generalization":
case "--stress_pointer_maps":
case "--stress_environments":
case "--deopt_every_n_times":
case "--deopt_every_n_garbage_collections":
case "--print_deopt_stress":
case "--trap_on_deopt":
case "--trap_on_stub_deopt":
case "--deoptimize_uncommon_cases":
case "--polymorphic_inlining":
case "--use_osr":
case "--array_bounds_checks_elimination":
case "--trace_bce":
case "--array_bounds_checks_hoisting":
case "--array_index_dehoisting":
case "--analyze_environment_liveness":
case "--load_elimination":
case "--check_elimination":
case "--store_elimination":
case "--dead_code_elimination":
case "--fold_constants":
case "--trace_dead_code_elimination":
case "--unreachable_code_elimination":
case "--trace_osr":
case "--stress_runs":
case "--lookup_sample_by_shared":
case "--cache_optimized_code":
case "--flush_optimized_code_cache":
case "--inline_construct":
case "--inline_arguments":
case "--inline_accessors":
case "--escape_analysis_iterations":
case "--optimize_for_in":
case "--concurrent_recompilation":
case "--job_based_recompilation":
case "--trace_concurrent_recompilation":
case "--concurrent_recompilation_queue_length":
case "--concurrent_recompilation_delay":
case "--block_concurrent_recompilation":
case "--concurrent_osr":
case "--omit_map_checks_for_leaf_maps":
case "--turbo_filter":
case "--trace_turbo":
case "--trace_turbo_graph":
case "--trace_turbo_cfg_file":
case "--trace_turbo_types":
case "--trace_turbo_scheduler":
case "--trace_turbo_reduction":
case "--trace_turbo_jt":
case "--turbo_asm":
case "--turbo_verify":
case "--turbo_stats":
case "--turbo_types":
case "--turbo_source_positions":
case "--context_specialization":
case "--turbo_deoptimization":
case "--turbo_inlining":
case "--turbo_inlining_intrinsics":
case "--trace_turbo_inlining":
case "--loop_assignment_analysis":
case "--turbo_profiling":
case "--turbo_reuse_spill_slots":
case "--turbo_delay_ssa_decon":
case "--turbo_move_optimization":
case "--turbo_jt":
case "--typed_array_max_size_in_heap":
case "--frame_count":
case "--interrupt_budget":
case "--type_info_threshold":
case "--generic_ic_threshold":
case "--self_opt_count":
case "--trace_opt_verbose":
case "--debug_code":
case "--code_comments":
case "--enable_sse3":
case "--enable_sse4_1":
case "--enable_sahf":
case "--enable_avx":
case "--enable_fma3":
case "--enable_vfp3":
case "--enable_armv7":
case "--enable_armv8":
case "--enable_neon":
case "--enable_sudiv":
case "--enable_mls":
case "--enable_movw_movt":
case "--enable_unaligned_accesses":
case "--enable_32dregs":
case "--enable_vldr_imm":
case "--force_long_branches":
case "--expose_natives_as":
case "--expose_debug_as":
case "--expose_free_buffer":
case "--expose_gc":
case "--expose_gc_as":
case "--expose_externalize_string":
case "--expose_trigger_failure":
case "--stack_trace_limit":
case "--builtins_in_stack_traces":
case "--disable_native_files":
case "--inline_new":
case "--trace_codegen":
case "--trace":
case "--mask_constants_with_cookie":
case "--lazy":
case "--trace_opt":
case "--trace_opt_stats":
case "--opt":
case "--always_opt":
case "--always_osr":
case "--prepare_always_opt":
case "--trace_deopt":
case "--trace_stub_failures":
case "--serialize_toplevel":
case "--serialize_inner":
case "--trace_serializer":
case "--min_preparse_length":
case "--max_opt_count":
case "--compilation_cache":
case "--cache_prototype_transitions":
case "--cpu_profiler_sampling_interval":
case "--trace_debug_json":
case "--trace_js_array_abuse":
case "--trace_external_array_abuse":
case "--trace_array_abuse":
case "--enable_liveedit":
case "--hard_abort":
case "--stack_size":
case "--max_stack_trace_source_length":
case "--always_inline_smi_code":
case "--min_semi_space_size":
case "--target_semi_space_size":
case "--max_semi_space_size":
case "--semi_space_growth_factor":
case "--experimental_new_space_growth_heuristic":
case "--max_old_space_size":
case "--initial_old_space_size":
case "--max_executable_size":
case "--gc_global":
case "--gc_interval":
case "--trace_gc":
case "--trace_gc_nvp":
case "--trace_gc_ignore_scavenger":
case "--trace_idle_notification":
case "--trace_idle_notification_verbose":
case "--print_cumulative_gc_stat":
case "--print_max_heap_committed":
case "--trace_gc_verbose":
case "--trace_fragmentation":
case "--collect_maps":
case "--weak_embedded_maps_in_optimized_code":
case "--weak_embedded_objects_in_optimized_code":
case "--flush_code":
case "--flush_code_incrementally":
case "--trace_code_flushing":
case "--age_code":
case "--incremental_marking":
case "--incremental_marking_steps":
case "--concurrent_sweeping":
case "--trace_incremental_marking":
case "--track_gc_object_stats":
case "--heap_profiler_trace_objects":
case "--use_idle_notification":
case "--use_ic":
case "--trace_ic":
case "--native_code_counters":
case "--always_compact":
case "--never_compact":
case "--compact_code_space":
case "--incremental_code_compaction":
case "--cleanup_code_caches_at_gc":
case "--use_marking_progress_bar":
case "--zap_code_space":
case "--random_seed":
case "--trace_weak_arrays":
case "--track_prototype_users":
case "--use_verbose_printer":
case "--allow_natives_syntax":
case "--trace_parse":
case "--trace_sim":
case "--debug_sim":
case "--check_icache":
case "--stop_sim_at":
case "--sim_stack_alignment":
case "--sim_stack_size":
case "--log_regs_modified":
case "--log_colour":
case "--ignore_asm_unimplemented_break":
case "--trace_sim_messages":
case "--stack_trace_on_illegal":
case "--abort_on_uncaught_exception":
case "--randomize_hashes":
case "--hash_seed":
case "--profile_deserialization":
case "--regexp_optimization":
case "--testing_bool_flag":
case "--testing_maybe_bool_flag":
case "--testing_int_flag":
case "--testing_float_flag":
case "--testing_string_flag":
case "--testing_prng_seed":
case "--testing_serialization_file":
case "--startup_blob":
case "--profile_hydrogen_code_stub_compilation":
case "--predictable":
case "--help":
case "--dump_counters":
case "--debugger":
case "--map_counters":
case "--js_arguments":
case "--gdbjit":
case "--gdbjit_full":
case "--gdbjit_dump":
case "--gdbjit_dump_filter":
case "--force_marking_deque_overflows":
case "--stress_compaction":
case "--log":
case "--log_all":
case "--log_api":
case "--log_code":
case "--log_gc":
case "--log_handles":
case "--log_snapshot_positions":
case "--log_suspect":
case "--prof":
case "--prof_browser_mode":
case "--log_regexp":
case "--logfile":
case "--logfile_per_isolate":
case "--ll_prof":
case "--perf_basic_prof":
case "--perf_jit_prof":
case "--gc_fake_mmap":
case "--log_internal_timer_events":
case "--log_timer_events":
case "--log_instruction_stats":
case "--log_instruction_file":
case "--log_instruction_period":
case "--redirect_code_traces":
case "--redirect_code_traces_to":
case "--hydrogen_track_positions":
case "--trace_elements_transitions":
case "--trace_creation_allocation_sites":
case "--print_code_stubs":
case "--test_secondary_stub_cache":
case "--test_primary_stub_cache":
case "--print_code":
case "--print_opt_code":
case "--print_unopt_code":
case "--print_code_verbose":
case "--print_builtin_code":
case "--sodium":
case "--print_all_code":
case "--es5_readonly":
case "--es52_globals":
case "--harmony_typeof":
case "--harmony_collections":
case "--packed_arrays":
case "--smi_only_arrays":
case "--clever_optimizations":
case "--use_range":
case "--eliminate_dead_phis":
case "--optimize_closures":
case "--loop_weight":
case "--opt_safe_uint32_operations":
case "--parallel_recompilation":
case "--trace_parallel_recompilation":
case "--parallel_recompilation_queue_length":
case "--experimental_profiler":
case "--watch_ic_patching":
case "--self_optimization":
case "--direct_self_opt":
case "--retry_self_opt":
case "--count_based_interrupts":
case "--interrupt_at_exit":
case "--weighted_back_edges":
case "--debug_code (generate extra code":
case "--enable_sse2":
case "--enable_cmov":
case "--enable_rdtsc":
case "--enable_vfp2":
case "--enable_fpu":
case "--stack_trace_on_abort":
case "--always_full_compiler":
case "--debugger_auto_break":
case "--break_on_abort":
case "--max_new_space_size":
case "--trace_external_memory":
case "--lazy_sweeping":
case "--trace_exception":
case "--preallocate_message_memory":
case "--preemption":
case "--extra_code":
case "--remote_debugger":
case "--debugger_agent":
case "--debugger_port":
case "--debug_compile_events":
case "--debug_script_collected_events":
case "--log_runtime":
case "--prof_auto":
case "--prof_lazy":
case "--sliding_state_window":
case "--nolazy":
args.unshift(arg);
break;
default:
if (arg.indexOf("--trace") === 0) {
case "debug":
case "--debug":
case "--debug-brk":
args.unshift(arg);
} else {
args.push(arg);
}
break;
break;
case "-gc":
case "--expose-gc":
args.unshift("--expose-gc");
break;
default:
if (v8Flags.indexOf(arg) >= 0 || arg.indexOf("--trace") === 0) {
args.unshift(arg);
} else {
args.push(arg);
}
break;
}
});
// append arguments passed after --
if (argSeparator > -1) {
args = args.concat(userArgs);
}
try {
let kexec = require("kexec");
kexec(process.argv[0], args);
} catch (err) {
if (err.code !== "MODULE_NOT_FOUND") throw err;
let child_process = require("child_process");
let proc = child_process.spawn(process.argv[0], args, { stdio: "inherit" });
proc.on("exit", function (code, signal) {
process.on("exit", function () {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code);
}
});
});
}
});
// append arguments passed after --
if (argSeparator > -1) {
args = args.concat(userArgs);
}
try {
var kexec = require("kexec");
kexec(process.argv[0], args);
} catch (err) {
if (err.code !== "MODULE_NOT_FOUND") throw err;
var child_process = require("child_process");
var proc = child_process.spawn(process.argv[0], args, { stdio: "inherit" });
proc.on("exit", function (code, signal) {
process.on("exit", function () {
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code);
}
});
});
}

View File

@ -1,162 +0,0 @@
import pathExists from "path-exists";
import readline from "readline";
import child from "child_process";
import path from "path";
import fs from "fs";
function spawn(cmd, args, callback) {
console.log(">", cmd, args);
var spawn = child.spawn(cmd, args, { stdio: "inherit" });
spawn.on("exit", function (code) {
if (code === 0) {
callback();
} else {
console.log("Killing...");
process.exit(1);
}
});
}
function spawnMultiple(cmds) {
function next() {
var cmd = cmds.shift();
if (cmd) {
spawn(cmd.command, cmd.args, next);
} else {
process.exit();
}
}
next();
}
function template(name, data = {}) {
var source = fs.readFileSync(path.join(__dirname, "templates", name), "utf8");
source = source.replace(/[A-Z_]+/g, function (key) {
return data[key] === undefined ? key : data[key];
});
return source;
}
function write(filename, content) {
console.log(filename);
fs.writeFileSync(filename, content);
}
function execMaybe(cmd) {
try {
return child.execSync(cmd).toString();
} catch (err) {
return "";
}
}
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var BABEL_PLUGIN_PREFIX = "babel-plugin-";
var cmds = {
init: function () {
var name = path.basename(process.cwd());
if (name.indexOf(BABEL_PLUGIN_PREFIX) === 0) {
name = name.slice(BABEL_PLUGIN_PREFIX.length);
}
rl.question("Description (optional): ", function (description) {
var remote = execMaybe("git config --get remote.origin.url").trim().match(/git@github.com:(.*?).git/);
if (remote) {
build(description, remote[1]);
} else {
rl.question("GitHub Repository (eg. sebmck/babel-plugin-foobar) (optional): ", function (repo) {
build(description, repo);
});
}
});
function build(description, repo) {
rl.close();
var templateData = {
DESCRIPTION: description,
FULL_NAME: BABEL_PLUGIN_PREFIX + name,
NAME: name
};
write("package.json", JSON.stringify({
name: templateData.FULL_NAME,
version: "1.0.0",
description: templateData.DESCRIPTION,
repository: repo || undefined,
license: "MIT",
main: "lib/index.js",
devDependencies: {
babel: "^5.6.0"
},
scripts: {
build: "babel-plugin build",
push: "babel-plugin publish",
test: "babel-plugin test"
},
keywords: ["babel-plugin"]
}, null, " ") + "\n");
write(".npmignore", "node_modules\n*.log\nsrc\n");
write(".gitignore", "node_modules\n*.log\nlib\n");
write("README.md", template("README.md", templateData));
write("LICENSE", template("LICENSE", {
AUTHOR_EMAIL: execMaybe("git config --get user.email").trim(),
AUTHOR_NAME: execMaybe("git config --get user.name").trim(),
YEAR: new Date().getFullYear()
}));
if (!pathExists.sync("src")) {
fs.mkdirSync("src");
write("src/index.js", template("index.js", templateData));
}
}
},
build: function () {
spawn("babel", ["src", "--out-dir", "lib", "--copy-files"], process.exit);
},
publish: function () {
var pkg = require(process.cwd() + "/package.json");
console.log("Current version:", pkg.version);
rl.question("New version (enter nothing for patch): ", function (newVersion) {
rl.close();
newVersion = newVersion || "patch";
spawnMultiple([
{ command: "git", args: ["pull"] },
{ command: "git", args: ["push"] },
{ command: "babel-plugin", args: ["build"] },
{ command: "npm", args: ["version", newVersion] },
{ command: "npm", args: ["publish"] },
{ command: "git", args: ["push", "--follow-tags"] }
]);
});
}
};
var cmd = cmds[process.argv[2]];
if (cmd) {
cmd();
} else {
console.error("Unknown command:", cmd);
process.exit(1);
}

View File

@ -1,22 +0,0 @@
Copyright (c) YEAR AUTHOR_NAME <AUTHOR_EMAIL>
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,35 +0,0 @@
# FULL_NAME
DESCRIPTION
## Installation
```sh
$ npm install FULL_NAME
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["NAME"]
}
```
### Via CLI
```sh
$ babel --plugins NAME script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["NAME"]
});
```

View File

@ -1,8 +0,0 @@
/* eslint no-unused-vars:0 */
export default function ({ Plugin, types: t }) {
return new Plugin("NAME", {
visitor: {
// your visitor methods go here
}
});
}

View File

@ -1,32 +1,34 @@
var outputFileSync = require("output-file-sync");
var pathExists = require("path-exists");
var chokidar = require("chokidar");
var slash = require("slash");
var path = require("path");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
let outputFileSync = require("output-file-sync");
let pathExists = require("path-exists");
let chokidar = require("chokidar");
let slash = require("slash");
let path = require("path");
let util = require("./util");
let fs = require("fs");
let _ = require("lodash");
module.exports = function (commander, filenames) {
function write(src, relative) {
// remove extension and then append back on .js
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
var dest = path.join(commander.outDir, relative);
let dest = path.join(commander.outDir, relative);
var data = util.compile(src, {
let data = util.compile(src, {
sourceFileName: slash(path.relative(dest + "/..", src)),
sourceMapTarget: path.basename(relative)
});
if (!commander.copyFiles && data.ignored) return;
// we've requested explicit sourcemaps to be written to disk
if (data.map && commander.sourceMaps && commander.sourceMaps !== "inline") {
var mapLoc = dest + ".map";
let mapLoc = dest + ".map";
data.code = util.addSourceMappingUrl(data.code, mapLoc);
outputFileSync(mapLoc, JSON.stringify(data.map));
}
outputFileSync(dest, data.code);
util.chmod(src, dest);
util.log(src + " -> " + dest);
}
@ -37,20 +39,22 @@ module.exports = function (commander, filenames) {
if (util.canCompile(filename, commander.extensions)) {
write(src, filename);
} else if (commander.copyFiles) {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
let dest = path.join(commander.outDir, filename);
outputFileSync(dest, fs.readFileSync(src));
util.chmod(src, dest);
}
}
function handle(filename) {
if (!pathExists.sync(filename)) return;
var stat = fs.statSync(filename);
let stat = fs.statSync(filename);
if (stat.isDirectory(filename)) {
var dirname = filename;
let dirname = filename;
_.each(util.readdir(dirname), function (filename) {
var src = path.join(dirname, filename);
let src = path.join(dirname, filename);
handleFile(src, filename);
});
} else {
@ -62,14 +66,14 @@ module.exports = function (commander, filenames) {
if (commander.watch) {
_.each(filenames, function (dirname) {
var watcher = chokidar.watch(dirname, {
let watcher = chokidar.watch(dirname, {
persistent: true,
ignoreInitial: true
});
_.each(["add", "change"], function (type) {
watcher.on(type, function (filename) {
var relative = path.relative(dirname, filename) || filename;
let relative = path.relative(dirname, filename) || filename;
try {
handleFile(filename, relative);
} catch (err) {

View File

@ -1,37 +1,37 @@
var convertSourceMap = require("convert-source-map");
var pathExists = require("path-exists");
var sourceMap = require("source-map");
var chokidar = require("chokidar");
var slash = require("slash");
var path = require("path");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
let convertSourceMap = require("convert-source-map");
let pathExists = require("path-exists");
let sourceMap = require("source-map");
let chokidar = require("chokidar");
let slash = require("slash");
let path = require("path");
let util = require("./util");
let fs = require("fs");
let _ = require("lodash");
module.exports = function (commander, filenames, opts) {
if (commander.sourceMaps === "inline") {
opts.sourceMaps = true;
}
var results = [];
let results = [];
var buildResult = function () {
var map = new sourceMap.SourceMapGenerator({
let buildResult = function () {
let map = new sourceMap.SourceMapGenerator({
file: path.basename(commander.outFile) || "stdout",
sourceRoot: opts.sourceRoot
});
var code = "";
var offset = 0;
let code = "";
let offset = 0;
_.each(results, function (result) {
var filename = result.filename;
let filename = result.filename;
code += result.code + "\n";
if (result.map) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
let consumer = new sourceMap.SourceMapConsumer(result.map);
var sourceFilename = filename;
let sourceFilename = filename;
if (commander.outFile) {
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
}
@ -54,6 +54,8 @@ module.exports = function (commander, filenames, opts) {
}
});
// add the inline sourcemap comment if we've either explicitly asked for inline source
// maps, or we've requested them without any output file
if (commander.sourceMaps === "inline" || (!commander.outFile && commander.sourceMaps)) {
code += "\n" + convertSourceMap.fromObject(map).toComment();
}
@ -64,12 +66,13 @@ module.exports = function (commander, filenames, opts) {
};
};
var output = function () {
var result = buildResult();
let output = function () {
let result = buildResult();
if (commander.outFile) {
// we've requested for a sorucemap to be written to disk
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
var mapLoc = commander.outFile + ".map";
let mapLoc = commander.outFile + ".map";
result.code = util.addSourceMappingUrl(result.code, mapLoc);
fs.writeFileSync(mapLoc, JSON.stringify(result.map));
}
@ -80,13 +83,13 @@ module.exports = function (commander, filenames, opts) {
}
};
var stdin = function () {
var code = "";
let stdin = function () {
let code = "";
process.stdin.setEncoding("utf8");
process.stdin.on("readable", function () {
var chunk = process.stdin.read();
let chunk = process.stdin.read();
if (chunk !== null) code += chunk;
});
@ -96,16 +99,16 @@ module.exports = function (commander, filenames, opts) {
});
};
var walk = function () {
var _filenames = [];
let walk = function () {
let _filenames = [];
results = [];
_.each(filenames, function (filename) {
if (!pathExists.sync(filename)) return;
var stat = fs.statSync(filename);
let stat = fs.statSync(filename);
if (stat.isDirectory()) {
var dirname = filename;
let dirname = filename;
_.each(util.readdirFilter(filename), function (filename) {
_filenames.push(path.join(dirname, filename));
@ -118,7 +121,7 @@ module.exports = function (commander, filenames, opts) {
_.each(_filenames, function (filename) {
if (util.shouldIgnore(filename)) return;
var data = util.compile(filename);
let data = util.compile(filename);
if (data.ignored) return;
results.push(data);
});
@ -126,7 +129,7 @@ module.exports = function (commander, filenames, opts) {
output();
};
var files = function () {
let files = function () {
walk();
if (commander.watch) {

View File

@ -2,22 +2,19 @@
require("babel-core");
var moduleFormatters = require("babel-core/lib/transformation/modules");
var pathExists = require("path-exists");
var commander = require("commander");
var transform = require("babel-core").transform;
var kebabCase = require("lodash/string/kebabCase");
var options = require("babel-core").options;
var util = require("babel-core").util;
var uniq = require("lodash/array/uniq");
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
var glob = require("glob");
let pathExists = require("path-exists");
let commander = require("commander");
let kebabCase = require("lodash/string/kebabCase");
let options = require("babel-core").options;
let util = require("babel-core").util;
let uniq = require("lodash/array/uniq");
let each = require("lodash/collection/each");
let glob = require("glob");
each(options, function (option, key) {
if (option.hidden) return;
var arg = kebabCase(key);
let arg = kebabCase(key);
if (option.type !== "boolean") {
arg += " [" + (option.type || "string") + "]";
@ -33,7 +30,7 @@ each(options, function (option, key) {
arg = "-" + option.shorthand + ", " + arg;
}
var desc = [];
let desc = [];
if (option.deprecated) desc.push("[DEPRECATED] " + option.deprecated);
if (option.description) desc.push(option.description);
@ -47,27 +44,7 @@ commander.option("-d, --out-dir [out]", "Compile an input directory of modules i
commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files");
commander.option("-q, --quiet", "Don't log anything");
commander.on("--help", function () {
var outKeys = function (title, obj) {
console.log(" " + title + ":");
console.log();
each(keys(obj).sort(), function (key) {
if (key[0] === "_") return;
if (obj[key].metadata && obj[key].metadata.optional) key = "[" + key + "]";
console.log(" - " + key);
});
console.log();
};
outKeys("Transformers", transform.pipeline.transformers);
outKeys("Module formatters", moduleFormatters);
});
var pkg = require("../../package.json");
let pkg = require("../../package.json");
commander.version(pkg.version + " (babel-core " + require("babel-core").version + ")");
commander.usage("[options] <files ...>");
commander.parse(process.argv);
@ -80,10 +57,10 @@ if (commander.extensions) {
//
var errors = [];
let errors = [];
var filenames = commander.args.reduce(function (globbed, input) {
var files = glob.sync(input);
let filenames = commander.args.reduce(function (globbed, input) {
let files = glob.sync(input);
if (!files.length) files = [input];
return globbed.concat(files);
}, []);
@ -121,7 +98,7 @@ if (errors.length) {
//
var opts = exports.opts = {};
let opts = exports.opts = {};
each(options, function (opt, key) {
if (commander[key] !== undefined) {
@ -135,7 +112,7 @@ if (opts.only) {
opts.only = util.arrayify(opts.only, util.regexify);
}
var fn;
let fn;
if (commander.outDir) {
fn = require("./dir");

View File

@ -1,50 +1,54 @@
var commander = require("commander");
var readdir = require("fs-readdir-recursive");
var index = require("./index");
var babel = require("babel-core");
var util = require("babel-core").util;
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
let commander = require("commander");
let readdir = require("fs-readdir-recursive");
let index = require("./index");
let babel = require("babel-core");
let util = require("babel-core").util;
let path = require("path");
let fs = require("fs");
let _ = require("lodash");
exports.readdirFilter = function (filename) {
export function chmod(src, dest) {
fs.chmodSync(dest, fs.statSync(src).mode);
}
export function readdirFilter(filename) {
return readdir(filename).filter(function (filename) {
return util.canCompile(filename);
});
};
}
exports.readdir = readdir;
export { readdir };
exports.canCompile = util.canCompile;
export let canCompile = util.canCompile;
exports.shouldIgnore = function (loc) {
export function shouldIgnore(loc) {
return util.shouldIgnore(loc, index.opts.ignore, index.opts.only);
};
}
exports.addSourceMappingUrl = function (code, loc) {
export function addSourceMappingUrl(code, loc) {
return code + "\n//# sourceMappingURL=" + path.basename(loc);
};
}
exports.log = function (msg) {
export function log(msg) {
if (!commander.quiet) console.log(msg);
};
}
exports.transform = function (filename, code, opts) {
export function transform(filename, code, opts) {
opts = _.defaults(opts || {}, index.opts);
opts.filename = filename;
opts.ignore = null;
opts.only = null;
var result = babel.transform(code, opts);
let result = babel.transform(code, opts);
result.filename = filename;
result.actual = code;
return result;
};
}
exports.compile = function (filename, opts) {
export function compile(filename, opts) {
try {
var code = fs.readFileSync(filename, "utf8");
return exports.transform(filename, code, opts);
let code = fs.readFileSync(filename, "utf8");
return transform(filename, code, opts);
} catch (err) {
if (commander.watch) {
console.error(toErrorStack(err));
@ -53,7 +57,7 @@ exports.compile = function (filename, opts) {
throw err;
}
}
};
}
function toErrorStack(err) {
if (err._babel && err instanceof SyntaxError) {

View File

@ -1,3 +1 @@
{
"breakConfig": true
}
{}

View File

@ -8,4 +8,4 @@
}
})(this, function (global) {
var babelHelpers = global;
})
});

View File

@ -1,3 +1,3 @@
{
"args": ["--whitelist", "slice,has-own"]
"args": ["--whitelist", "createClass"]
}

View File

@ -1,5 +1,21 @@
(function (global) {
var babelHelpers = global.babelHelpers = {};
babelHelpers.hasOwn = Object.prototype.hasOwnProperty;
babelHelpers.slice = Array.prototype.slice;
babelHelpers.createClass = (function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
})();
})(typeof global === "undefined" ? self : global);

View File

@ -1,3 +0,0 @@
{
"args": ["--blacklist", "es6.arrowFunctions"]
}

View File

@ -1 +0,0 @@
arr.map(x => x * MULTIPLIER);

View File

@ -1,3 +0,0 @@
"use strict";
arr.map(x => x * MULTIPLIER);

View File

@ -1,3 +0,0 @@
{
"args": ["--whitelist", "es6.arrowFunctions"]
}

View File

@ -1,2 +0,0 @@
let MULTIPLER = 5;
arr.map(x => x * MULTIPLIER);

View File

@ -1,4 +0,0 @@
let MULTIPLER = 5;
arr.map(function (x) {
return x * MULTIPLIER;
});

View File

@ -15,6 +15,16 @@ var _ = require("lodash");
var fixtureLoc = __dirname + "/fixtures";
var tmpLoc = __dirname + "/tmp";
var presetLocs = [
__dirname + "/../../babel-preset-es2015",
__dirname + "/../../babel-preset-react"
].join(",");
var pluginLocs = [
__dirname + "/../../babel-plugin-transform-strict-mode",
__dirname + "/../../babel-plugin-transform-es2015-modules-commonjs",
].join(",");
var readDir = function (loc) {
var files = {};
if (pathExists.sync(loc)) {
@ -43,7 +53,7 @@ var assertTest = function (stdout, stderr, opts) {
chai.expect(stderr).to.equal(expectStderr, "stderr didn't match");
}
} else if (stderr) {
throw new Error("stderr: " + JSON.stringify(stderr));
throw new Error("stderr:\n" + stderr);
}
var expectStdout = opts.stdout.trim();
@ -57,7 +67,7 @@ var assertTest = function (stdout, stderr, opts) {
chai.expect(stdout).to.equal(expectStdout, "stdout didn't match");
}
} else if (stdout) {
throw new Error("stdout: " + JSON.stringify(stdout));
throw new Error("stdout:\n" + stdout);
}
_.each(opts.outFiles, function (expect, filename) {
@ -74,7 +84,18 @@ var buildTest = function (binName, testName, opts) {
clear();
saveInFiles(opts.inFiles);
var args = [binLoc].concat(opts.args);
var args = [binLoc];
if (binName !== "babel-external-helpers") {
args.push("--presets", presetLocs, "--plugins", pluginLocs);
}
if (binName === "babel-node") {
args.push("--only", "packages/*/test");
}
args = args.concat(opts.args);
var spawn = child.spawn(process.execPath, args);
var stderr = "";

View File

@ -0,0 +1 @@
/src

View File

@ -0,0 +1 @@
# babel-code-frame

View File

@ -0,0 +1,18 @@
{
"name": "babel-code-frame",
"version": "6.0.2",
"description": "",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"main": "lib/index.js",
"dependencies": {
"babel-runtime": "^6.0.2",
"chalk": "^1.1.0",
"esutils": "^2.0.2",
"js-tokens": "^1.0.1",
"line-numbers": "^0.2.0",
"repeating": "^1.1.3"
}
}

View File

@ -0,0 +1,121 @@
/* @flow */
import lineNumbers from "line-numbers";
import repeating from "repeating";
import jsTokens from "js-tokens";
import esutils from "esutils";
import chalk from "chalk";
/**
* Chalk styles for token types.
*/
let defs = {
string: chalk.red,
punctuator: chalk.bold,
curly: chalk.green,
parens: chalk.blue.bold,
square: chalk.yellow,
keyword: chalk.cyan,
number: chalk.magenta,
regex: chalk.magenta,
comment: chalk.grey,
invalid: chalk.inverse
};
/**
* RegExp to test for newlines in terminal.
*/
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
/**
* Get the type of token, specifying punctuator type.
*/
function getTokenType(match) {
let token = jsTokens.matchToToken(match);
if (token.type === "name" && esutils.keyword.isReservedWordES6(token.value)) {
return "keyword";
}
if (token.type === "punctuator") {
switch (token.value) {
case "{":
case "}":
return "curly";
case "(":
case ")":
return "parens";
case "[":
case "]":
return "square";
}
}
return token.type;
}
/**
* Highlight `text`.
*/
function highlight(text: string) {
return text.replace(jsTokens, function (...args) {
let type = getTokenType(args);
let colorize = defs[type];
if (colorize) {
return args[0].split(NEWLINE).map(str => colorize(str)).join("\n");
} else {
return args[0];
}
});
}
/**
* Create a code frame, adding line numbers, code highlighting, and pointing to a given position.
*/
export default function (
rawLines: string,
lineNumber: number,
colNumber: number,
opts: Object = {},
): string {
colNumber = Math.max(colNumber, 0);
let highlighted = opts.highlightCode && chalk.supportsColor;
if (highlighted) rawLines = highlight(rawLines);
let lines = rawLines.split(NEWLINE);
let start = Math.max(lineNumber - 3, 0);
let end = Math.min(lines.length, lineNumber + 3);
if (!lineNumber && !colNumber) {
start = 0;
end = lines.length;
}
let frame = lineNumbers(lines.slice(start, end), {
start: start + 1,
before: " ",
after: " | ",
transform(params) {
if (params.number !== lineNumber) {
return;
}
if (colNumber) {
params.line += `\n${params.before}${repeating(" ", params.width)}${params.after}${repeating(" ", colNumber - 1)}^`;
}
params.before = params.before.replace(/^./, ">");
}
}).join("\n");
if (highlighted) {
return chalk.reset(frame);
} else {
return frame;
}
}

View File

@ -0,0 +1 @@
# babel-core

View File

@ -0,0 +1 @@
module.exports = require("./lib/api/node.js");

View File

@ -0,0 +1,59 @@
{
"name": "babel-core",
"version": "6.0.2",
"description": "A compiler for writing next generation JavaScript",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"browser": {
"./lib/api/register/node.js": "./lib/api/register/browser.js",
"esprima-fb": false
},
"keywords": [
"6to5",
"babel",
"classes",
"const",
"es6",
"harmony",
"let",
"modules",
"transpile",
"transpiler",
"var"
],
"scripts": {
"bench": "make bench",
"test": "make test"
},
"dependencies": {
"babel-code-frame": "^6.0.2",
"babel-generator": "^6.0.2",
"babel-helpers": "^6.0.2",
"babel-messages": "^6.0.2",
"babel-template": "^6.0.2",
"babel-runtime": "^6.0.2",
"babel-traverse": "^6.0.2",
"babel-types": "^6.0.2",
"babylon": "^6.0.2",
"convert-source-map": "^1.1.0",
"debug": "^2.1.1",
"esutils": "^2.0.0",
"home-or-tmp": "^1.0.0",
"json5": "^0.4.0",
"lodash": "^3.10.0",
"minimatch": "^2.0.3",
"path-exists": "^1.0.0",
"path-is-absolute": "^1.0.0",
"private": "^0.1.6",
"regenerator": "0.8.35",
"shebang-regex": "^1.0.0",
"slash": "^1.0.0",
"source-map": "^0.4.0",
"source-map-support": "^0.2.10"
},
"devDependencies": {
"babel-polyfill": "^6.0.2"
}
}

View File

@ -0,0 +1,22 @@
#!/bin/sh
set -ex
BROWSERIFY_CMD="../../node_modules/browserify/bin/cmd.js"
UGLIFY_CMD="../../node_modules/uglify-js/bin/uglifyjs"
BROWSERIFY_IGNORE="-i esprima-fb -i through"
mkdir -p dist
# Add a Unicode BOM so browsers will interpret the file as UTF-8
node -p '"\uFEFF"' > dist/browser.js
node $BROWSERIFY_CMD lib/api/browser.js \
--standalone babel \
--plugin bundle-collapser/plugin \
--plugin derequire/plugin \
$BROWSERIFY_IGNORE \
>>dist/browser.j
node -p '"\uFEFF"' > dist/browser.min.js
node $UGLIFY_CMD dist/browser.js \
--compress warnings=false \
--mangle \
>>dist/browser.min.js

View File

@ -0,0 +1,6 @@
function rmRelative(loc) {
rm(__dirname + "/../" + loc);
}
rmRelative("browser.js");
rmRelative("browser.min.js");

View File

@ -0,0 +1,6 @@
function relative(loc) {
return __dirname + "/../" + loc;
}
cp(relative("dist/browser.js"), relative("browser.js"));
cp(relative("dist/browser.min.js"), relative("browser.min.js"));

View File

@ -0,0 +1,95 @@
/* @flow */
/* eslint no-new-func: 0 */
import { transform } from "./node";
export * from "./node";
export function run(code: string, opts: Object = {}): any {
return new Function(transform(code, opts).code)();
}
export function load(url: string, callback: Function, opts: Object = {}, hold?: boolean) {
opts.filename = opts.filename || url;
let xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
xhr.open("GET", url, true);
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
let status = xhr.status;
if (status === 0 || status === 200) {
let param = [xhr.responseText, opts];
if (!hold) run(param);
if (callback) callback(param);
} else {
throw new Error(`Could not load ${url}`);
}
};
xhr.send(null);
}
function runScripts() {
let scripts: Array<Array<any> | Object> = [];
let types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
let index = 0;
/**
* Transform and execute script. Ensures correct load order.
*/
function exec() {
let param = scripts[index];
if (param instanceof Array) {
run(param, index);
index++;
exec();
}
}
/**
* Load, transform, and execute all scripts.
*/
function run(script: Object, i: number) {
let opts = {};
if (script.src) {
load(script.src, function (param) {
scripts[i] = param;
exec();
}, opts, true);
} else {
opts.filename = "embedded";
scripts[i] = [script.innerHTML, opts];
}
}
// Collect scripts with Babel `types`.
let _scripts = global.document.getElementsByTagName("script");
for (let i = 0; i < _scripts.length; ++i) {
let _script = _scripts[i];
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
}
for (let i = 0; i < scripts.length; i++) {
run(scripts[i], i);
}
exec();
}
/**
* Register load event to transform and execute scripts.
*/
if (global.addEventListener) {
global.addEventListener("DOMContentLoaded", runScripts, false);
} else if (global.attachEvent) {
global.attachEvent("onload", runScripts);
}

View File

@ -0,0 +1,65 @@
/* @flow */
import isFunction from "lodash/lang/isFunction";
import fs from "fs";
export { default as File } from "../transformation/file";
export { default as options } from "../transformation/file/options/config";
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
export { default as template } from "babel-template";
export { version } from "../../package";
//
import * as util from "../util";
export { util };
import * as messages from "babel-messages";
export { messages };
import * as t from "babel-types";
export { t as types };
//
import Pipeline from "../transformation/pipeline";
export { Pipeline };
let pipeline = new Pipeline;
export let transform = pipeline.transform.bind(pipeline);
export let transformFromAst = pipeline.transformFromAst.bind(pipeline);
//
export function transformFile(filename: string, opts?: Object, callback: Function) {
if (isFunction(opts)) {
callback = opts;
opts = {};
}
opts.filename = filename;
fs.readFile(filename, function (err, code) {
let result;
if (!err) {
try {
result = transform(code, opts);
} catch (_err) {
err = _err;
}
}
if (err) {
callback(err);
} else {
callback(null, result);
}
});
}
export function transformFileSync(filename: string, opts?: Object = {}): string {
opts.filename = filename;
return transform(fs.readFileSync(filename, "utf8"), opts);
}

View File

@ -0,0 +1,3 @@
// required to safely use babel/register within a browserify codebase
export default function () {}

View File

@ -1,10 +1,12 @@
/* @flow */
import path from "path";
import fs from "fs";
import homeOrTmp from "home-or-tmp";
import pathExists from "path-exists";
const FILENAME = process.env.BABEL_CACHE_PATH || path.join(homeOrTmp, ".babel.json");
var data = {};
let data = {};
/**
* Write stringified cache to disk.

View File

@ -0,0 +1,145 @@
/* @flow */
import deepClone from "lodash/lang/cloneDeep";
import sourceMapSupport from "source-map-support";
import * as registerCache from "./cache";
import OptionManager from "../../transformation/file/options/option-manager";
import extend from "lodash/object/extend";
import * as babel from "../node";
import each from "lodash/collection/each";
import * as util from "../../util";
import fs from "fs";
import path from "path";
sourceMapSupport.install({
handleUncaughtExceptions: false,
retrieveSourceMap(source) {
let map = maps && maps[source];
if (map) {
return {
url: null,
map: map
};
} else {
return null;
}
}
});
registerCache.load();
let cache = registerCache.get();
let transformOpts = {};
let ignore;
let only;
let oldHandlers = {};
let maps = {};
let cwd = process.cwd();
function getRelativePath(filename){
return path.relative(cwd, filename);
}
function mtime(filename) {
return +fs.statSync(filename).mtime;
}
function compile(filename, opts = {}) {
let result;
opts.filename = filename;
let optsManager = new OptionManager;
optsManager.mergeOptions(deepClone(transformOpts));
opts = optsManager.init(opts);
let cacheKey = `${JSON.stringify(opts)}:${babel.version}`;
let env = process.env.BABEL_ENV || process.env.NODE_ENV;
if (env) cacheKey += `:${env}`;
if (cache) {
let cached = cache[cacheKey];
if (cached && cached.mtime === mtime(filename)) {
result = cached;
}
}
if (!result) {
result = babel.transformFileSync(filename, extend(opts, {
sourceMap: "both",
ast: false
}));
}
if (cache) {
cache[cacheKey] = result;
result.mtime = mtime(filename);
}
maps[filename] = result.map;
return result.code;
}
function shouldIgnore(filename) {
if (!ignore && !only) {
return getRelativePath(filename).split(path.sep).indexOf("node_modules") >= 0;
} else {
return util.shouldIgnore(filename, ignore || [], only);
}
}
function loader(m, filename) {
m._compile(compile(filename), filename);
}
function registerExtension(ext) {
let old = oldHandlers[ext] || oldHandlers[".js"] || require.extensions[".js"];
require.extensions[ext] = function (m, filename) {
if (shouldIgnore(filename)) {
old(m, filename);
} else {
loader(m, filename, old);
}
};
}
function hookExtensions(_exts) {
each(oldHandlers, function (old, ext) {
if (old === undefined) {
delete require.extensions[ext];
} else {
require.extensions[ext] = old;
}
});
oldHandlers = {};
each(_exts, function (ext) {
oldHandlers[ext] = require.extensions[ext];
registerExtension(ext);
});
}
hookExtensions(util.canCompile.EXTENSIONS);
export default function (opts?: Object = {}) {
if (opts.only != null) only = util.arrayify(opts.only, util.regexify);
if (opts.ignore != null) ignore = util.arrayify(opts.ignore, util.regexify);
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
if (opts.cache === false) cache = null;
delete opts.extensions;
delete opts.ignore;
delete opts.cache;
delete opts.only;
extend(transformOpts, opts);
}

View File

@ -0,0 +1,19 @@
/* @flow */
import merge from "lodash/object/merge";
export default function (dest?: Object, src?: Object): ?Object {
if (!dest || !src) return;
return merge(dest, src, function (a, b) {
if (b && Array.isArray(a)) {
let c = a.slice(0);
for (let v of b) {
if (a.indexOf(v) < 0) {
c.push(v);
}
}
return c;
}
});
}

View File

@ -0,0 +1,25 @@
/* @flow */
import * as t from "babel-types";
/**
* Normalize an AST.
*
* - Wrap `Program` node with a `File` node.
*/
export default function (
ast: Object,
comments?: Array<Object>,
tokens?: Array<Object>,
) {
if (ast) {
if (ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);
} else if (ast.type === "File") {
return ast;
}
}
throw new Error("Not a valid ast?");
}

View File

@ -0,0 +1,24 @@
/* @flow */
import Module from "module";
let relativeModules = {};
export default function (loc: string, relative: string = process.cwd()): ?string {
// we're in the browser, probably
if (typeof Module === "object") return null;
let relativeMod = relativeModules[relative];
if (!relativeMod) {
relativeMod = new Module;
relativeMod.paths = Module._nodeModulePaths(relative);
relativeModules[relative] = relativeMod;
}
try {
return Module._resolveFilename(loc, relativeMod);
} catch (err) {
return null;
}
}

View File

@ -0,0 +1,26 @@
/* @flow */
export default class Store extends Map {
constructor() {
super();
this.dynamicData = {};
}
dynamicData: Object;
setDynamic(key, fn) {
this.dynamicData[key] = fn;
}
get(key: string): any {
if (this.has(key)) {
return super.get(key);
} else {
if (Object.prototype.hasOwnProperty.call(this.dynamicData, key)) {
let val = this.dynamicData[key]();
this.set(key, val);
return val;
}
}
}
}

View File

@ -0,0 +1,110 @@
/* @flow */
import * as helpers from "babel-helpers";
import generator from "babel-generator";
import * as messages from "babel-messages";
import template from "babel-template";
import each from "lodash/collection/each";
import * as t from "babel-types";
let buildUmdWrapper = template(`
(function (root, factory) {
if (typeof define === "function" && define.amd) {
define(AMD_ARGUMENTS, factory);
} else if (typeof exports === "object") {
factory(COMMON_ARGUMENTS);
} else {
factory(BROWSER_ARGUMENTS);
}
})(UMD_ROOT, function (FACTORY_PARAMETERS) {
FACTORY_BODY
});
`);
function buildGlobal(namespace, builder) {
let body = [];
let container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
let tree = t.program([t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]);
body.push(t.variableDeclaration("var", [
t.variableDeclarator(
namespace,
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([]))
)
]));
builder(body);
return tree;
}
function buildUmd(namespace, builder) {
let body = [];
body.push(t.variableDeclaration("var", [
t.variableDeclarator(namespace, t.identifier("global"))
]));
builder(body);
return t.program([
buildUmdWrapper({
FACTORY_PARAMETERS: t.identifier("global"),
BROWSER_ARGUMENTS: t.assignmentExpression(
"=",
t.memberExpression(t.identifier("root"), namespace),
t.objectExpression([])
),
COMMON_ARGUMENTS: t.identifier("exports"),
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
FACTORY_BODY: body,
UMD_ROOT: t.identifier("this")
})
]);
}
function buildVar(namespace, builder) {
let body = [];
body.push(t.variableDeclaration("var", [
t.variableDeclarator(namespace, t.objectExpression([]))
]));
builder(body);
return t.program(body);
}
function buildHelpers(body, namespace, whitelist) {
each(helpers.list, function (name) {
if (whitelist && whitelist.indexOf(name) === -1) return;
let key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement(
t.assignmentExpression("=", t.memberExpression(namespace, key), helpers.get(name))
));
});
}
export default function (
whitelist?: Array<string>,
outputType: "global" | "umd" | "var" = "global",
) {
let namespace = t.identifier("babelHelpers");
let builder = function (body) {
return buildHelpers(body, namespace, whitelist);
};
let tree;
let build = {
global: buildGlobal,
umd: buildUmd,
var: buildVar
}[outputType];
if (build) {
tree = build(namespace, builder);
} else {
throw new Error(messages.get("unsupportedOutputType", outputType));
}
return generator(tree).code;
}

View File

@ -0,0 +1,555 @@
/* @flow */
/* global BabelParserOptions */
/* global BabelFileMetadata */
/* global BabelFileResult */
import getHelper from "babel-helpers";
import * as metadataVisitor from "./metadata";
import convertSourceMap from "convert-source-map";
import OptionManager from "./options/option-manager";
import type Pipeline from "../pipeline";
import type Plugin from "../plugin";
import PluginPass from "../plugin-pass";
import shebangRegex from "shebang-regex";
import { NodePath, Hub, Scope } from "babel-traverse";
import sourceMap from "source-map";
import generate from "babel-generator";
import codeFrame from "babel-code-frame";
import defaults from "lodash/object/defaults";
import traverse from "babel-traverse";
import Logger from "./logger";
import Store from "../../store";
import { parse } from "babylon";
import * as util from "../../util";
import path from "path";
import * as t from "babel-types";
import blockHoistPlugin from "../internal-plugins/block-hoist";
import shadowFunctionsPlugin from "../internal-plugins/shadow-functions";
const INTERNAL_PLUGINS = [
[blockHoistPlugin],
[shadowFunctionsPlugin]
];
let errorVisitor = {
enter(path, state) {
let loc = path.node.loc;
if (loc) {
state.loc = loc;
path.stop();
}
}
};
export default class File extends Store {
constructor(opts: Object = {}, pipeline: Pipeline) {
super();
this.pipeline = pipeline;
this.log = new Logger(this, opts.filename || "unknown");
this.opts = this.initOptions(opts);
this.parserOpts = {
highlightCode: this.opts.highlightCode,
nonStandard: this.opts.nonStandard,
sourceType: this.opts.sourceType,
filename: this.opts.filename,
plugins: []
};
this.pluginVisitors = [];
this.pluginPasses = [];
this.pluginStack = [];
this.buildPlugins();
this.metadata = {
usedHelpers: [],
marked: [],
modules: {
imports: [],
exports: {
exported: [],
specifiers: []
}
}
};
this.dynamicImportTypes = {};
this.dynamicImportIds = {};
this.dynamicImports = [];
this.declarations = {};
this.usedHelpers = {};
this.path = null;
this.ast = {};
this.code = "";
this.shebang = "";
this.hub = new Hub(this);
}
static helpers: Array<string>;
pluginVisitors: Array<Object>;
pluginPasses: Array<PluginPass>;
pluginStack: Array<Plugin>;
pipeline: Pipeline;
parserOpts: BabelParserOptions;
log: Logger;
opts: Object;
dynamicImportTypes: Object;
dynamicImportIds: Object;
dynamicImports: Array<Object>;
declarations: Object;
usedHelpers: Object;
path: NodePath;
ast: Object;
scope: Scope;
metadata: BabelFileMetadata;
hub: Hub;
code: string;
shebang: string;
getMetadata() {
let has = false;
for (let node of (this.ast.program.body: Array<Object>)) {
if (t.isModuleDeclaration(node)) {
has = true;
break;
}
}
if (has) {
this.path.traverse(metadataVisitor, this);
}
}
initOptions(opts) {
opts = new OptionManager(this.log, this.pipeline).init(opts);
if (opts.inputSourceMap) {
opts.sourceMaps = true;
}
if (opts.moduleId) {
opts.moduleIds = true;
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.ignore = util.arrayify(opts.ignore, util.regexify);
if (opts.only) opts.only = util.arrayify(opts.only, util.regexify);
defaults(opts, {
moduleRoot: opts.sourceRoot
});
defaults(opts, {
sourceRoot: opts.moduleRoot
});
defaults(opts, {
filenameRelative: opts.filename
});
let basenameRelative = path.basename(opts.filenameRelative);
defaults(opts, {
sourceFileName: basenameRelative,
sourceMapTarget: basenameRelative
});
return opts;
}
buildPlugins() {
let plugins: Array<[PluginPass, Object]> = this.opts.plugins.concat(INTERNAL_PLUGINS);
// init plugins!
for (let ref of plugins) {
let [plugin, pluginOpts] = ref; // todo: fix - can't embed in loop head because of flow bug
this.pluginStack.push(plugin);
this.pluginVisitors.push(plugin.visitor);
this.pluginPasses.push(new PluginPass(this, plugin, pluginOpts));
if (plugin.manipulateOptions) {
plugin.manipulateOptions(this.opts, this.parserOpts, this);
}
}
}
getModuleName(): ?string {
let opts = this.opts;
if (!opts.moduleIds) {
return null;
}
// moduleId is n/a if a `getModuleId()` is provided
if (opts.moduleId != null && !opts.getModuleId) {
return opts.moduleId;
}
let filenameRelative = opts.filenameRelative;
let moduleName = "";
if (opts.moduleRoot != null) {
moduleName = opts.moduleRoot + "/";
}
if (!opts.filenameRelative) {
return moduleName + opts.filename.replace(/^\//, "");
}
if (opts.sourceRoot != null) {
// remove sourceRoot from filename
let sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
}
// remove extension
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
moduleName += filenameRelative;
// normalize path separators
moduleName = moduleName.replace(/\\/g, "/");
if (opts.getModuleId) {
// If return is falsy, assume they want us to use our generated default name
return opts.getModuleId(moduleName) || moduleName;
} else {
return moduleName;
}
}
resolveModuleSource(source: string): string {
let resolveModuleSource = this.opts.resolveModuleSource;
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
return source;
}
addImport(source: string, imported: string, name?: string = imported): Object {
let alias = `${source}:${imported}`;
let id = this.dynamicImportIds[alias];
if (!id) {
source = this.resolveModuleSource(source);
id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(name);
let specifiers = [];
if (imported === "*") {
specifiers.push(t.importNamespaceSpecifier(id));
} else if (imported === "default") {
specifiers.push(t.importDefaultSpecifier(id));
} else {
specifiers.push(t.importSpecifier(id, t.identifier(imported)));
}
let declar = t.importDeclaration(specifiers, t.stringLiteral(source));
declar._blockHoist = 3;
this.path.unshiftContainer("body", declar);
}
return id;
}
addHelper(name: string): Object {
let declar = this.declarations[name];
if (declar) return declar;
if (!this.usedHelpers[name]) {
this.metadata.usedHelpers.push(name);
this.usedHelpers[name] = true;
}
let generator = this.get("helperGenerator");
let runtime = this.get("helpersNamespace");
if (generator) {
return generator(name);
} else if (runtime) {
let id = t.identifier(t.toIdentifier(name));
return t.memberExpression(runtime, id);
}
let ref = getHelper(name);
let uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
if (t.isFunctionExpression(ref) && !ref.id) {
ref.body._compact = true;
ref._generated = true;
ref.id = uid;
ref.type = "FunctionDeclaration";
this.path.unshiftContainer("body", ref);
} else {
ref._compact = true;
this.scope.push({
id: uid,
init: ref,
unique: true
});
}
return uid;
}
addTemplateObject(
helperName: string,
strings: Array<Object>,
raw: Object,
): Object {
// Generate a unique name based on the string literals so we dedupe
// identical strings used in the program.
let stringIds = raw.elements.map(function(string) {
return string.value;
});
let name = `${helperName}_${raw.elements.length}_${stringIds.join(",")}`;
let declar = this.declarations[name];
if (declar) return declar;
let uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject");
let helperId = this.addHelper(helperName);
let init = t.callExpression(helperId, [strings, raw]);
init._compact = true;
this.scope.push({
id: uid,
init: init,
_blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers
});
return uid;
}
buildCodeFrameError(node: Object, msg: string, Error: typeof Error = SyntaxError): Error {
let loc = node && (node.loc || node._loc);
let err = new Error(msg);
if (loc) {
err.loc = loc.start;
} else {
traverse(node, errorVisitor, this.scope, err);
err.message += " (This is an error on an internal node. Probably an internal error";
if (err.loc) {
err.message += ". Location has been estimated.";
}
err.message += ")";
}
return err
}
mergeSourceMap(map: Object) {
let inputMap = this.opts.inputSourceMap;
if (inputMap) {
let inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
let outputMapConsumer = new sourceMap.SourceMapConsumer(map);
let outputMapGenerator = sourceMap.SourceMapGenerator.fromSourceMap(outputMapConsumer);
outputMapGenerator.applySourceMap(inputMapConsumer);
let mergedMap = outputMapGenerator.toJSON();
mergedMap.sources = inputMap.sources;
mergedMap.file = inputMap.file;
return mergedMap;
} else {
return map;
}
}
parse(code: string) {
this.log.debug("Parse start");
let ast = parse(code, this.parserOpts);
this.log.debug("Parse stop");
return ast;
}
_addAst(ast) {
this.path = NodePath.get({
hub: this.hub,
parentPath: null,
parent: ast,
container: ast,
key: "program"
}).setContext();
this.scope = this.path.scope;
this.ast = ast;
this.getMetadata();
}
addAst(ast) {
this.log.debug("Start set AST");
this._addAst(ast);
this.log.debug("End set AST");
}
transform(): BabelFileResult {
this.call("pre");
this.log.debug(`Start transform traverse`);
traverse(this.ast, traverse.visitors.merge(this.pluginVisitors, this.pluginPasses), this.scope);
this.log.debug(`End transform traverse`);
this.call("post");
return this.generate();
}
wrap(code: string, callback: Function): BabelFileResult {
code = code + "";
try {
if (this.shouldIgnore()) {
return this.makeResult({ code, ignored: true });
} else {
return callback();
}
} catch (err) {
if (err._babel) {
throw err;
} else {
err._babel = true;
}
let message = err.message = `${this.opts.filename}: ${err.message}`;
let loc = err.loc;
if (loc) {
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, this.opts);
message += "\n" + err.codeFrame;
}
if (process.browser) {
// chrome has it's own pretty stringifier which doesn't use the stack property
// https://github.com/babel/babel/issues/2175
err.message = message;
}
if (err.stack) {
let newStack = err.stack.replace(err.message, message);
try {
err.stack = newStack;
} catch (e) {
// `err.stack` may be a readonly property in some environments
}
}
throw err;
}
}
addCode(code: string) {
code = (code || "") + "";
code = this.parseInputSourceMap(code);
this.code = code;
}
parseCode() {
this.parseShebang();
let ast = this.parse(this.code);
this.addAst(ast);
}
shouldIgnore() {
let opts = this.opts;
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
}
call(key: "pre" | "post") {
for (let pass of (this.pluginPasses: Array<PluginPass>)) {
let plugin = pass.plugin;
let fn = plugin[key];
if (fn) fn.call(pass, this, pass);
}
}
parseInputSourceMap(code: string): string {
let opts = this.opts;
if (opts.inputSourceMap !== false) {
let inputMap = convertSourceMap.fromSource(code);
if (inputMap) {
opts.inputSourceMap = inputMap.toObject();
code = convertSourceMap.removeComments(code);
}
}
return code;
}
parseShebang() {
let shebangMatch = shebangRegex.exec(this.code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
this.code = this.code.replace(shebangRegex, "");
}
}
makeResult({ code, map, ast, ignored }: BabelFileResult): BabelFileResult {
let result = {
metadata: null,
options: this.opts,
ignored: !!ignored,
code: null,
ast: null,
map: map || null
};
if (this.opts.code) {
result.code = code;
}
if (this.opts.ast) {
result.ast = ast;
}
if (this.opts.metadata) {
result.metadata = this.metadata;
}
return result;
}
generate(): BabelFileResult {
let opts = this.opts;
let ast = this.ast;
let result: BabelFileResult = { ast };
if (!opts.code) return this.makeResult(result);
this.log.debug("Generation start");
let _result = generate(ast, opts, this.code);
result.code = _result.code;
result.map = _result.map;
this.log.debug("Generation end");
if (this.shebang) {
// add back shebang
result.code = `${this.shebang}${result.code}`;
}
if (result.map) {
result.map = this.mergeSourceMap(result.map);
}
if (opts.sourceMaps === "inline" || opts.sourceMaps === "both") {
result.code += "\n" + convertSourceMap.fromObject(result.map).toComment();
}
if (opts.sourceMaps === "inline") {
result.map = null;
}
return this.makeResult(result);
}
}
export { File };

View File

@ -0,0 +1,59 @@
/* @flow */
import type File from "./index";
import buildDebug from "debug/node";
let verboseDebug = buildDebug("babel:verbose");
let generalDebug = buildDebug("babel");
let seenDeprecatedMessages = [];
export default class Logger {
constructor(file: File, filename: string) {
this.filename = filename;
this.file = file;
}
filename: string;
file: File;
_buildMessage(msg: string): string {
let parts = `[BABEL] ${this.filename}`;
if (msg) parts += `: ${msg}`;
return parts;
}
warn(msg: string) {
console.warn(this._buildMessage(msg));
}
error(msg: string, Constructor: typeof Error = Error): Error {
throw new Constructor(this._buildMessage(msg));
}
deprecate(msg: string) {
if (this.file.opts && this.file.opts.suppressDeprecationMessages) return;
msg = this._buildMessage(msg);
// already seen this message
if (seenDeprecatedMessages.indexOf(msg) >= 0) return;
// make sure we don't see it again
seenDeprecatedMessages.push(msg);
console.error(msg);
}
verbose(msg: string) {
if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg));
}
debug(msg: string) {
if (generalDebug.enabled) generalDebug(this._buildMessage(msg));
}
deopt(node: Object, msg: string) {
this.debug(msg);
}
}

View File

@ -0,0 +1,142 @@
/* @flow */
import * as t from "babel-types";
export let ModuleDeclaration = {
enter(path, file) {
let { node } = path;
if (node.source) {
node.source.value = file.resolveModuleSource(node.source.value);
}
}
};
export let ImportDeclaration = {
exit(path, file) {
let { node } = path;
let specifiers = [];
let imported = [];
file.metadata.modules.imports.push({
source: node.source.value,
imported,
specifiers
});
for (let specifier of (path.get("specifiers"): Array<Object>)) {
let local = specifier.node.local.name;
if (specifier.isImportDefaultSpecifier()) {
imported.push("default");
specifiers.push({
kind: "named",
imported: "default",
local
});
}
if (specifier.isImportSpecifier()) {
let importedName = specifier.node.imported.name;
imported.push(importedName);
specifiers.push({
kind: "named",
imported: importedName,
local
});
}
if (specifier.isImportNamespaceSpecifier()) {
imported.push("*");
specifiers.push({
kind: "namespace",
local
});
}
}
}
};
export function ExportDeclaration(path, file) {
let { node } = path;
let source = node.source ? node.source.value : null;
let exports = file.metadata.modules.exports;
// export function foo() {}
// export let foo = "bar";
let declar = path.get("declaration");
if (declar.isStatement()) {
let bindings = declar.getBindingIdentifiers();
for (let name in bindings) {
exports.exported.push(name);
exports.specifiers.push({
kind: "local",
local: name,
exported: path.isExportDefaultDeclaration() ? "default" : name
});
}
}
if (path.isExportNamedDeclaration() && node.specifiers) {
for (let specifier of (node.specifiers: Array<Object>)) {
let exported = specifier.exported.name;
exports.exported.push(exported);
// export foo from "bar";
if (t.isExportDefaultSpecifier(specifier)) {
exports.specifiers.push({
kind: "external",
local: exported,
exported,
source
});
}
// export * as foo from "bar";
if (t.isExportNamespaceSpecifier(specifier)) {
exports.specifiers.push({
kind: "external-namespace",
exported,
source
});
}
let local = specifier.local;
if (!local) continue;
// export { foo } from "bar";
// export { foo as bar } from "bar";
if (source) {
exports.specifiers.push({
kind: "external",
local: local.name,
exported,
source
});
}
// export { foo };
// export { foo as bar };
if (!source) {
exports.specifiers.push({
kind: "local",
local: local.name,
exported
});
}
}
}
// export * from "bar";
if (path.isExportAllDeclaration()) {
exports.specifiers.push({
kind: "external-all",
source
});
}
}
export function Scope(path) {
path.skip();
}

View File

@ -0,0 +1,171 @@
{
"filename": {
"type": "filename",
"description": "filename to use when reading from stdin - this will be used in source-maps, errors etc",
"default": "unknown",
"shorthand": "f"
},
"filenameRelative": {
"hidden": true,
"type": "string"
},
"inputSourceMap": {
"hidden": true
},
"env": {
"hidden": true,
"default": {}
},
"mode": {
"description": "",
"hidden": true
},
"retainLines": {
"type": "boolean",
"default": false,
"description": "retain line numbers - will result in really ugly code"
},
"highlightCode": {
"description": "enable/disable ANSI syntax highlighting of code frames (on by default)",
"type": "boolean",
"default": true
},
"suppressDeprecationMessages": {
"type": "boolean",
"default": false,
"hidden": true
},
"presets": {
"type": "list",
"description": "",
"default": []
},
"plugins": {
"type": "list",
"default": [],
"description": ""
},
"ignore": {
"type": "list",
"description": "list of glob paths to **not** compile",
"default": []
},
"only": {
"type": "list",
"description": "list of glob paths to **only** compile"
},
"code": {
"hidden": true,
"default": true,
"type": "boolean"
},
"metadata": {
"hidden": true,
"default": true,
"type": "boolean"
},
"ast": {
"hidden": true,
"default": true,
"type": "boolean"
},
"comments": {
"type": "boolean",
"default": true,
"description": "strip/output comments in generated output (on by default)"
},
"shouldPrintComment": {
"hidden": true,
"description": "optional callback to control whether a comment should be inserted, when this is used the comments option is ignored"
},
"compact": {
"type": "booleanString",
"default": "auto",
"description": "do not include superfluous whitespace characters and line terminators [true|false|auto]"
},
"sourceMap": {
"alias": "sourceMaps",
"hidden": true
},
"sourceMaps": {
"type": "booleanString",
"description": "[true|false|inline]",
"default": false,
"shorthand": "s"
},
"sourceMapTarget": {
"type": "string",
"description": "set `file` on returned source map"
},
"sourceFileName": {
"type": "string",
"description": "set `sources[0]` on returned source map"
},
"sourceRoot": {
"type": "filename",
"description": "the root from which all sources are relative"
},
"babelrc": {
"description": "Whether or not to look up .babelrc and .babelignore files",
"type": "boolean",
"default": true
},
"sourceType": {
"description": "",
"default": "module"
},
"auxiliaryComment": {
"description": "",
"type": "string"
},
"resolveModuleSource": {
"hidden": true
},
"getModuleId": {
"hidden": true
},
"moduleRoot": {
"type": "filename",
"description": "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions"
},
"moduleIds": {
"type": "boolean",
"default": false,
"shorthand": "M",
"description": "insert an explicit id for modules"
},
"moduleId": {
"description": "specify a custom name for module ids",
"type": "string"
}
}

View File

@ -0,0 +1,24 @@
/* @flow */
import * as parsers from "./parsers";
import config from "./config";
export { config };
export function normaliseOptions(options: Object = {}): Object {
for (let key in options) {
let val = options[key];
if (val == null) continue;
let opt = config[key];
if (opt && opt.alias) opt = config[opt.alias];
if (!opt) continue;
let parser = parsers[opt.type];
if (parser) val = parser(val);
options[key] = val;
}
return options;
}

View File

@ -0,0 +1,321 @@
/* @flow */
import * as context from "../../../api/node";
import type Logger from "../logger";
import Plugin from "../../plugin";
import * as messages from "babel-messages";
import { normaliseOptions } from "./index";
import resolve from "../../../helpers/resolve";
import json5 from "json5";
import isAbsolute from "path-is-absolute";
import pathExists from "path-exists";
import cloneDeep from "lodash/lang/cloneDeep";
import clone from "lodash/lang/clone";
import merge from "../../../helpers/merge";
import config from "./config";
import path from "path";
import fs from "fs";
let existsCache = {};
let jsonCache = {};
const BABELIGNORE_FILENAME = ".babelignore";
const BABELRC_FILENAME = ".babelrc";
const PACKAGE_FILENAME = "package.json";
function exists(filename) {
let cached = existsCache[filename];
if (cached == null) {
return existsCache[filename] = pathExists.sync(filename);
} else {
return cached;
}
}
export default class OptionManager {
constructor(log?: Logger) {
this.resolvedConfigs = [];
this.options = OptionManager.createBareOptions();
this.log = log;
}
resolvedConfigs: Array<string>;
options: Object;
log: ?Logger;
static memoisedPlugins: Array<{
container: Function;
plugin: Plugin;
}>;
static memoisePluginContainer(fn, loc, i) {
for (let cache of (OptionManager.memoisedPlugins: Array<Object>)) {
if (cache.container === fn) return cache.plugin;
}
let obj;
if (typeof fn === "function") {
obj = fn(context);
} else {
obj = fn;
}
if (typeof obj === "object") {
let plugin = new Plugin(obj);
OptionManager.memoisedPlugins.push({
container: fn,
plugin: plugin
});
return plugin;
} else {
throw new TypeError(messages.get("pluginNotObject", loc, i, typeof obj) + loc + i);
}
}
static createBareOptions() {
let opts = {};
for (let key in config) {
let opt = config[key];
opts[key] = clone(opt.default);
}
return opts;
}
static normalisePlugin(plugin, loc, i) {
if (!(plugin instanceof Plugin)) {
// allow plugin containers to be specified so they don't have to manually require
if (typeof plugin === "function" || typeof plugin === "object") {
plugin = OptionManager.memoisePluginContainer(plugin, loc, i);
} else {
throw new TypeError(messages.get("pluginNotFunction", loc, i, typeof plugin));
}
}
plugin.init(loc, i);
return plugin;
}
static normalisePlugins(loc, dirname, plugins) {
return plugins.map(function (val, i) {
let plugin, options;
// destructure plugins
if (Array.isArray(val)) {
[plugin, options] = val;
} else {
plugin = val;
}
// allow plugins to be specified as strings
if (typeof plugin === "string") {
let pluginLoc = resolve(`babel-plugin-${plugin}`, dirname) || resolve(plugin, dirname);
if (pluginLoc) {
plugin = require(pluginLoc);
} else {
throw new ReferenceError(messages.get("pluginUnknown", plugin, loc, i));
}
}
plugin = OptionManager.normalisePlugin(plugin, loc, i);
return [plugin, options];
});
}
addConfig(loc: string, key?: string, json = json5) {
if (this.resolvedConfigs.indexOf(loc) >= 0) return;
let content = fs.readFileSync(loc, "utf8");
let opts;
try {
opts = jsonCache[content] = jsonCache[content] || json.parse(content);
if (key) opts = opts[key];
} catch (err) {
err.message = `${loc}: Error while parsing JSON - ${err.message}`;
throw err;
}
this.mergeOptions(opts, loc);
this.resolvedConfigs.push(loc);
}
/**
* This is called when we want to merge the input `opts` into our
* 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(rawOpts?: Object, alias: string = "foreign", loc?: string, dirname?: string) {
if (!rawOpts) return;
//
if (typeof rawOpts !== "object" || Array.isArray(rawOpts)) {
this.log.error(`Invalid options type for ${alias}`, TypeError);
}
//
let opts = cloneDeep(rawOpts, val => val);
//
dirname = dirname || process.cwd();
loc = loc || alias;
for (let key in opts) {
let option = config[key];
// check for an unknown option
if (!option && this.log) {
this.log.error(`Unknown option: ${alias}.${key}`, ReferenceError);
}
}
// normalise options
normaliseOptions(opts);
// resolve plugins
if (opts.plugins) {
opts.plugins = OptionManager.normalisePlugins(loc, dirname, opts.plugins);
}
// add extends clause
if (opts.extends) {
let extendsLoc = resolve(opts.extends, dirname);
if (extendsLoc) {
this.addConfig(extendsLoc);
} else {
if (this.log) this.log.error(`Couldn't resolve extends clause of ${opts.extends} in ${alias}`);
}
delete opts.extends;
}
// resolve presets
if (opts.presets) {
this.mergePresets(opts.presets, dirname);
delete opts.presets;
}
// env
let envOpts;
let envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
if (opts.env) {
envOpts = opts.env[envKey];
delete opts.env;
}
// merge them into this current files options
merge(this.options, opts);
// merge in env options
this.mergeOptions(envOpts, `${alias}.env.${envKey}`);
}
mergePresets(presets: Array<string | Object>, dirname: string) {
for (let val of presets) {
if (typeof val === "string") {
let presetLoc = resolve(`babel-preset-${val}`, dirname) || resolve(val, dirname);
if (presetLoc) {
let presetOpts = require(presetLoc);
this.mergeOptions(presetOpts, presetLoc, presetLoc, path.dirname(presetLoc));
} else {
throw new Error("Couldn't find preset");
}
} else if (typeof val === "object") {
this.mergeOptions(val);
} else {
throw new Error("todo");
}
}
}
addIgnoreConfig(loc) {
let file = fs.readFileSync(loc, "utf8");
let lines = file.split("\n");
lines = lines
.map((line) => line.replace(/#(.*?)$/, "").trim())
.filter((line) => !!line);
this.mergeOptions({ ignore: lines }, loc);
}
findConfigs(loc) {
if (!loc) return;
if (!isAbsolute(loc)) {
loc = path.join(process.cwd(), loc);
}
let foundConfig = false;
let foundIgnore = false;
while (loc !== (loc = path.dirname(loc))) {
if (!foundConfig) {
let configLoc = path.join(loc, BABELRC_FILENAME);
if (exists(configLoc)) {
this.addConfig(configLoc);
foundConfig = true;
}
let pkgLoc = path.join(loc, PACKAGE_FILENAME);
if (exists(pkgLoc)) {
this.addConfig(pkgLoc, "babel", JSON);
foundConfig = true;
}
}
if (!foundIgnore) {
let ignoreLoc = path.join(loc, BABELIGNORE_FILENAME);
if (exists(ignoreLoc)) {
this.addIgnoreConfig(ignoreLoc);
foundIgnore = true;
}
}
if (foundIgnore && foundConfig) return;
}
}
normaliseOptions() {
let opts = this.options;
for (let key in config) {
let option = config[key];
let val = opts[key];
// optional
if (!val && option.optional) continue;
// aliases
if (option.alias) {
opts[option.alias] = opts[option.alias] || val;
} else {
opts[key] = val;
}
}
}
init(opts: Object): Object {
// resolve all .babelrc files
if (opts.babelrc !== false) {
this.findConfigs(opts.filename);
}
// merge in base options
this.mergeOptions(opts, "base");
// normalise
this.normaliseOptions(opts);
return this.options;
}
}
OptionManager.memoisedPlugins = [];

View File

@ -0,0 +1,22 @@
/* @flow */
import slash from "slash";
import * as util from "../../../util";
export function number(val: any): number {
return +val;
}
export let filename = slash;
export function boolean(val: any): boolean {
return !!val;
}
export function booleanString(val: any): boolean | any {
return util.booleanify(val);
}
export function list(val: any): Array<string> {
return util.list(val);
}

View File

@ -0,0 +1,42 @@
/* @flow */
import Plugin from "../plugin";
import sortBy from "lodash/collection/sortBy";
export default new Plugin({
/**
* [Please add a description.]
*
* Priority:
*
* - 0 We want this to be at the **very** bottom
* - 1 Default node position
* - 2 Priority over normal nodes
* - 3 We want this to be at the **very** top
*/
visitor: {
Block: {
exit({ node }) {
let hasChange = false;
for (let i = 0; i < node.body.length; i++) {
let bodyNode = node.body[i];
if (bodyNode && bodyNode._blockHoist != null) {
hasChange = true;
break;
}
}
if (!hasChange) return;
node.body = sortBy(node.body, function(bodyNode){
let priority = bodyNode && bodyNode._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;
// Higher priorities should move toward the top.
return -1 * priority;
});
}
}
}
});

View File

@ -0,0 +1,68 @@
/* @flow */
import Plugin from "../plugin";
import * as t from "babel-types";
export default new Plugin({
visitor: {
ThisExpression(path) {
remap(path, "this", () => t.thisExpression());
},
ReferencedIdentifier(path) {
if (path.node.name === "arguments") {
remap(path, "arguments", () => t.identifier("arguments"));
}
}
}
});
function shouldShadow(path, shadowPath) {
if (path.is("_forceShadow")) {
return true;
} else {
return shadowPath && !shadowPath.isArrowFunctionExpression();
}
}
function remap(path, key, create) {
// ensure that we're shadowed
let shadowPath = path.inShadow(key);
if (!shouldShadow(path, shadowPath)) return;
let shadowFunction = path.node._shadowedFunctionLiteral;
let currentFunction;
let fnPath = path.findParent(function (path) {
if (path.isProgram() || path.isFunction()) {
// catch current function in case this is the shadowed one and we can ignore it
currentFunction = currentFunction || path;
}
if (path.isProgram()) {
return true;
} else if (path.isFunction()) {
if (shadowFunction) {
return path === shadowFunction || path.node === shadowFunction.node;
} else {
return !path.is("shadow");
}
}
return false;
});
// no point in realiasing if we're in this function
if (fnPath === currentFunction) return;
let cached = fnPath.getData(key);
if (cached) return path.replaceWith(cached);
let init = create();
let id = path.scope.generateUidIdentifier(key);
fnPath.setData(key, id);
fnPath.scope.push({ id, init });
return path.replaceWith(id);
}

View File

@ -0,0 +1,41 @@
/* @flow */
import normalizeAst from "../helpers/normalize-ast";
import File from "./file";
export default class Pipeline {
lint(code: string, opts?: Object = {}) {
opts.code = false;
opts.mode = "lint";
return this.transform(code, opts);
}
pretransform(code: string, opts?: Object) {
let file = new File(opts, this);
return file.wrap(code, function () {
file.addCode(code);
file.parseCode(code);
return file;
});
}
transform(code: string, opts?: Object) {
let file = new File(opts, this);
return file.wrap(code, function () {
file.addCode(code);
file.parseCode(code);
return file.transform();
});
}
transformFromAst(ast, code: string, opts: Object) {
ast = normalizeAst(ast);
let file = new File(opts, this);
return file.wrap(code, function () {
file.addCode(code);
file.addAst(ast);
return file.transform();
});
}
}

View File

@ -0,0 +1,42 @@
/* @flow */
import type Plugin from "./plugin";
import Store from "../store";
import traverse from "babel-traverse";
import File from "./file";
export default class PluginPass extends Store {
constructor(file: File, plugin: Plugin, options: Object = {}) {
super();
this.plugin = plugin;
this.file = file;
this.opts = options;
}
plugin: Plugin;
file: File;
opts: Object;
transform() {
let file = this.file;
file.log.debug(`Start transformer ${this.key}`);
traverse(file.ast, this.plugin.visitor, file.scope, file);
file.log.debug(`Finish transformer ${this.key}`);
}
addHelper(...args) {
return this.file.addHelper(...args);
}
addImport(...args) {
return this.file.addImport(...args);
}
getModuleName(...args) {
return this.file.getModuleName(...args);
}
buildCodeFrameError(...args) {
return this.file.buildCodeFrameError(...args);
}
}

View File

@ -0,0 +1,86 @@
/* @flow */
import OptionManager from "./file/options/option-manager"
import * as messages from "babel-messages";
import Store from "../store";
import traverse from "babel-traverse";
import assign from "lodash/object/assign";
import clone from "lodash/lang/clone";
export default class Plugin extends Store {
constructor(plugin: Object) {
super();
this.initialized = false;
this.raw = assign({}, plugin);
this.manipulateOptions = this.take("manipulateOptions");
this.post = this.take("post");
this.pre = this.take("pre");
this.visitor = this.normalize(clone(this.take("visitor")) || {});
}
initialized: boolean;
raw: Object;
manipulateOptions: ?Function;
post: ?Function;
pre: ?Function;
visitor: Object;
take(key) {
let val = this.raw[key];
delete this.raw[key];
return val;
}
chain(target, key) {
if (!target[key]) return this[key];
if (!this[key]) return target[key];
let fns: Array<?Function> = [target[key], this[key]];
return function (...args) {
let val;
for (let fn of fns) {
if (fn) {
let ret = fn.apply(this, args);
if (ret != null) val = ret;
}
}
return val;
};
}
maybeInherit(loc: string) {
let inherits = this.take("inherits");
if (!inherits) return;
inherits = OptionManager.normalisePlugin(inherits, loc, "inherits");
this.manipulateOptions = this.chain(inherits, "manipulateOptions");
this.post = this.chain(inherits, "post");
this.pre = this.chain(inherits, "pre");
this.visitor = traverse.visitors.merge([inherits.visitor, this.visitor]);
}
/**
* We lazy initialise parts of a plugin that rely on contextual information such as
* position on disk and how it was specified.
*/
init(loc: string, i: number) {
if (this.initialized) return;
this.initialized = true;
this.maybeInherit(loc);
for (let key in this.raw) {
throw new Error(messages.get("pluginInvalidProperty", loc, i, key));
}
}
normalize(visitor: Object): Object {
traverse.explode(visitor);
return visitor;
}
}

View File

@ -0,0 +1,148 @@
/* @flow */
import escapeRegExp from "lodash/string/escapeRegExp";
import startsWith from "lodash/string/startsWith";
import isBoolean from "lodash/lang/isBoolean";
import minimatch from "minimatch";
import contains from "lodash/collection/contains";
import isString from "lodash/lang/isString";
import isRegExp from "lodash/lang/isRegExp";
import path from "path";
import slash from "slash";
export { inherits, inspect } from "util";
/**
* Test if a filename ends with a compilable extension.
*/
export function canCompile(filename: string, altExts?: Array<string>) {
let exts = altExts || canCompile.EXTENSIONS;
let ext = path.extname(filename);
return contains(exts, ext);
}
/**
* Default set of compilable extensions.
*/
canCompile.EXTENSIONS = [".js", ".jsx", ".es6", ".es"];
/**
* Create an array from any value, splitting strings by ",".
*/
export function list(val?: string): Array<string> {
if (!val) {
return [];
} else if (Array.isArray(val)) {
return val;
} else if (typeof val === "string") {
return val.split(",");
} else {
return [val];
}
}
/**
* Create a RegExp from a string, array, or regexp.
*/
export function regexify(val: any): RegExp {
if (!val) {
return new RegExp(/.^/);
}
if (Array.isArray(val)) {
val = new RegExp(val.map(escapeRegExp).join("|"), "i");
}
if (typeof val === "string") {
// normalise path separators
val = slash(val);
// remove starting wildcards or relative separator if present
if (startsWith(val, "./") || startsWith(val, "*/")) val = val.slice(2);
if (startsWith(val, "**/")) val = val.slice(3);
let regex = minimatch.makeRe(val, { nocase: true });
return new RegExp(regex.source.slice(1, -1), "i");
}
if (isRegExp(val)) {
return val;
}
throw new TypeError("illegal type for regexify");
}
/**
* Create an array from a boolean, string, or array, mapped by and optional function.
*/
export function arrayify(val: any, mapFn?: Function): Array<any> {
if (!val) return [];
if (isBoolean(val)) return arrayify([val], mapFn);
if (isString(val)) return arrayify(list(val), mapFn);
if (Array.isArray(val)) {
if (mapFn) val = val.map(mapFn);
return val;
}
return [val];
}
/**
* Makes boolean-like strings into booleans.
*/
export function booleanify(val: any): boolean | any {
if (val === "true" || val == 1) {
return true;
}
if (val === "false" || val == 0 || !val) {
return false;
}
return val;
}
/**
* Tests if a filename should be ignored based on "ignore" and "only" options.
*/
export function shouldIgnore(
filename: string,
ignore: Array<RegExp | Function> = [],
only?: Array<RegExp | Function>,
): boolean {
filename = slash(filename);
if (only) {
for (let pattern of only) {
if (_shouldIgnore(pattern, filename)) return false;
}
return true;
} else if (ignore.length) {
for (let pattern of ignore) {
if (_shouldIgnore(pattern, filename)) 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 _shouldIgnore(pattern: Function | RegExp, filename: string) {
if (typeof pattern === "function") {
return pattern(filename);
} else {
return pattern.test(filename);
}
}

View File

@ -0,0 +1 @@
{}

View File

@ -1,8 +1,11 @@
require("../lib/api/node");
var buildExernalHelpers = require("../lib/tools/build-external-helpers");
var getFixtures = require("mocha-fixtures");
var transform = require("../lib/transformation");
var sourceMap = require("source-map");
var codeFrame = require("../lib/helpers/code-frame");
var codeFrame = require("babel-code-frame");
var register = require("../register");
var Module = require("module");
var assert = require("assert");
var chai = require("chai");
@ -14,7 +17,14 @@ exports.fixtures = getFixtures(__dirname + "/fixtures", function () {
return require("../test-fixtures.json");
});
require("../lib/polyfill");
require("babel-polyfill");
register({
ignore: [
path.resolve(__dirname + "/../.."),
"node_modules"
]
});
eval(buildExernalHelpers());
@ -49,25 +59,41 @@ chai.assert.throw = function (fn, msg) {
return chai.assert._throw(fn, msg);
};
var run = function (task, done) {
function wrapPackagesArray(type, names) {
return (names || []).map(function (val) {
if (typeof val === "string") val = [val];
val[0] = __dirname + "/../../babel-" + type + "-" + val[0];
return val;
});
}
function run(task, done) {
var actual = task.actual;
var expect = task.expect;
var exec = task.exec;
var opts = task.options;
var getOpts = function (self) {
return _.merge({
function getOpts(self) {
var newOpts = _.merge({
suppressDeprecationMessages: true,
filename: self.loc,
sourceMap: !!(task.sourceMappings || task.sourceMap)
}, opts);
};
newOpts.plugins = wrapPackagesArray("plugin", newOpts.plugins);
newOpts.presets = wrapPackagesArray("preset", newOpts.presets).map(function (val) {
return val[0];
});
return newOpts;
}
var execCode = exec.code;
var result;
if (execCode) {
result = transform(execCode, getOpts(exec));
var execOpts = getOpts(exec);
result = transform(execCode, execOpts);
execCode = result.code;
try {
@ -118,7 +144,7 @@ var run = function (task, done) {
chai.expect({ line: expect.line, column: expect.column }).to.deep.equal(actual);
});
}
};
}
exports.run = function (name, suiteOpts, taskOpts, dynamicOpts) {
suiteOpts = suiteOpts || {};

View File

@ -0,0 +1,342 @@
require("../lib/api/node");
var buildExternalHelpers = require("../lib/tools/build-external-helpers");
var transform = require("../lib/transformation");
var Pipeline = require("../lib/transformation/pipeline");
var assert = require("assert");
var File = require("../lib/transformation/file").default;
function assertIgnored(result) {
assert.ok(result.ignored);
}
function assertNotIgnored(result) {
assert.ok(!result.ignored);
}
// shim
function transformAsync(code, opts) {
return {
then: function (resolve) {
resolve(transform(code, opts));
}
};
}
suite("api", function () {
test("code option false", function () {
return transformAsync("foo('bar');", { code: false }).then(function (result) {
assert.ok(!result.code);
});
});
test("ast option false", function () {
return transformAsync("foo('bar');", { ast: false }).then(function (result) {
assert.ok(!result.ast);
});
});
test("auxiliaryComment option", function () {
return transformAsync("class Foo {}", {
auxiliaryComment: "yo bro",
plugins: [function (babel) {
var t = babel.types;
return {
visitor: {
Program: function (path) {
path.unshiftContainer("body", t.expressionStatement(t.identifier("start")));
path.pushContainer("body", t.expressionStatement(t.identifier("end")));
}
}
};
}]
}).then(function (result) {
assert.equal(result.code, "/*yo bro*/start;\nclass Foo {}\n/*yo bro*/end;");
});
});
test("modules metadata", function () {
return Promise.all([
transformAsync('import { externalName as localName } from "external";').then(function (result) {
assert.deepEqual(result.metadata.modules.imports[0], {
source: "external",
imported: ["externalName"],
specifiers: [{
kind: "named",
imported: "externalName",
local: "localName"
}]
});
}),
transformAsync('import * as localName2 from "external";').then(function (result) {
assert.deepEqual(result.metadata.modules.imports[0], {
source: "external",
imported: ["*"],
specifiers: [{
kind: "namespace",
local: "localName2"
}]
});
}),
transformAsync('import localName3 from "external";').then(function (result) {
assert.deepEqual(result.metadata.modules.imports[0], {
source: "external",
imported: ["default"],
specifiers: [{
kind: "named",
imported: "default",
local: "localName3"
}]
});
}),
transformAsync('import localName from "./array";', {
resolveModuleSource: function() {
return "override-source";
}
}).then(function (result) {
assert.deepEqual(result.metadata.modules.imports, [
{
source: "override-source",
imported: ["default"],
specifiers: [
{
"kind": "named",
"imported": "default",
"local": "localName"
}
]
}
]);
}),
transformAsync('export * as externalName1 from "external";', {
plugins: [require("../../babel-plugin-syntax-export-extensions")]
}).then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ['externalName1'],
specifiers: [{
kind: "external-namespace",
exported: "externalName1",
source: "external",
}]
});
}),
transformAsync('export externalName2 from "external";', {
plugins: [require("../../babel-plugin-syntax-export-extensions")]
}).then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ["externalName2"],
specifiers: [{
kind: "external",
local: "externalName2",
exported: "externalName2",
source: "external"
}]
});
}),
transformAsync('export function namedFunction() {}').then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ["namedFunction"],
specifiers: [{
kind: "local",
local: "namedFunction",
exported: "namedFunction"
}]
});
}),
transformAsync('export var foo = "bar";').then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
"exported": ["foo"],
specifiers: [{
kind: "local",
local: "foo",
exported: "foo"
}]
});
}),
transformAsync("export { localName as externalName3 };").then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ["externalName3"],
specifiers: [{
kind: "local",
local: "localName",
exported: "externalName3"
}]
});
}),
transformAsync('export { externalName4 } from "external";').then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ["externalName4"],
specifiers: [{
kind: "external",
local: "externalName4",
exported: "externalName4",
source: "external"
}]
});
}),
transformAsync('export * from "external";').then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: [],
specifiers: [{
kind: "external-all",
source: "external"
}]
});
}),
transformAsync("export default function defaultFunction() {}").then(function (result) {
assert.deepEqual(result.metadata.modules.exports, {
exported: ["defaultFunction"],
specifiers: [{
kind: "local",
local: "defaultFunction",
exported: "default"
}]
});
})
]);
});
test("ignore option", function () {
return Promise.all([
transformAsync("", {
ignore: "node_modules",
filename: "/foo/node_modules/bar"
}).then(assertIgnored),
transformAsync("", {
ignore: "foo/node_modules",
filename: "/foo/node_modules/bar"
}).then(assertIgnored),
transformAsync("", {
ignore: "foo/node_modules/*.bar",
filename: "/foo/node_modules/foo.bar"
}).then(assertIgnored)
]);
});
test("only option", function () {
return Promise.all([
transformAsync("", {
only: "node_modules",
filename: "/foo/node_modules/bar"
}).then(assertNotIgnored),
transformAsync("", {
only: "foo/node_modules",
filename: "/foo/node_modules/bar"
}).then(assertNotIgnored),
transformAsync("", {
only: "foo/node_modules/*.bar",
filename: "/foo/node_modules/foo.bar"
}).then(assertNotIgnored),
transformAsync("", {
only: "node_modules",
filename: "/foo/node_module/bar"
}).then(assertIgnored),
transformAsync("", {
only: "foo/node_modules",
filename: "/bar/node_modules/foo"
}).then(assertIgnored),
transformAsync("", {
only: "foo/node_modules/*.bar",
filename: "/foo/node_modules/bar.foo"
}).then(assertIgnored)
])
});
suite("env option", function () {
var oldBabelEnv = process.env.BABEL_ENV;
var oldNodeEnv = process.env.NODE_ENV;
before(function () {
delete process.env.BABEL_ENV;
delete process.env.NODE_ENV;
});
after(function () {
process.env.BABEL_ENV = oldBabelEnv;
process.env.NODE_ENV = oldNodeEnv;
});
test("default", function () {
return transformAsync("foo;", {
env: {
development: { code: false }
}
}).then(function (result) {
assert.equal(result.code, undefined);
});
});
test("BABEL_ENV", function () {
process.env.BABEL_ENV = "foo";
return transformAsync("foo;", {
env: {
foo: { code: false }
}
}).then(function (result) {
assert.equal(result.code, undefined);
});
});
test("NODE_ENV", function () {
process.env.NODE_ENV = "foo";
return transformAsync("foo;", {
env: {
foo: { code: false }
}
}).then(function (result) {
assert.equal(result.code, undefined);
});
});
});
test("resolveModuleSource option", function () {
var actual = 'import foo from "foo-import-default";\nimport "foo-import-bare";\nexport { foo } from "foo-export-named";';
var expected = 'import foo from "resolved/foo-import-default";\nimport "resolved/foo-import-bare";\nexport { foo } from "resolved/foo-export-named";';
return transformAsync(actual, {
resolveModuleSource: function (originalSource) {
return "resolved/" + originalSource;
}
}).then(function (result) {
assert.equal(result.code.trim(), expected);
});
});
suite("buildExternalHelpers", function () {
test("all", function () {
var script = buildExternalHelpers();
assert.ok(script.indexOf("classCallCheck") >= -1);
assert.ok(script.indexOf("inherits") >= 0);
});
test("whitelist", function () {
var script = buildExternalHelpers(["inherits"]);
assert.ok(script.indexOf("classCallCheck") === -1);
assert.ok(script.indexOf("inherits") >= 0);
});
test("empty whitelist", function () {
var script = buildExternalHelpers([]);
assert.ok(script.indexOf("classCallCheck") === -1);
assert.ok(script.indexOf("inherits") === -1);
});
});
});

View File

@ -0,0 +1,66 @@
var traverse = require("babel-traverse").default;
var assert = require("assert");
var parse = require("babylon").parse;
suite("evaluation", function () {
function addTest(code, type, value, notConfident) {
test(type + ": " + code, function () {
var visitor = {};
visitor[type] = function (path) {
var evaluate = path.evaluate();
assert.equal(evaluate.confident, !notConfident);
assert.equal(evaluate.value, value);
};
traverse(parse(code, {
plugins: ["*"]
}), visitor);
});
}
addTest("void 0", "UnaryExpression", undefined);
addTest("!true", "UnaryExpression", false);
addTest("+'2'", "UnaryExpression", 2);
addTest("-'2'", "UnaryExpression", -2);
addTest("~1", "UnaryExpression", -2);
addTest("3 - 1", "BinaryExpression", 2);
addTest("5 + 5", "BinaryExpression", 10);
addTest("10 / 2", "BinaryExpression", 5);
addTest("2 * 3", "BinaryExpression", 6);
addTest("4 % 2", "BinaryExpression", 0);
addTest("2 ** 3", "BinaryExpression", 8);
addTest("1 < 2", "BinaryExpression", true);
addTest("1 > 2", "BinaryExpression", false);
addTest("1 <= 2", "BinaryExpression", true);
addTest("1 >= 2", "BinaryExpression", false);
addTest("1 == '1'", "BinaryExpression", true);
addTest("1 != 2", "BinaryExpression", true);
addTest("'str' === 'str'", "BinaryExpression", true);
addTest("'four' === 4", "BinaryExpression", false);
addTest("'four' !== '4'", "BinaryExpression", true);
addTest("'str' !== 'str'", "BinaryExpression", false);
addTest("1 | 0", "BinaryExpression", 1);
addTest("1 & 1", "BinaryExpression", 1);
addTest("1 ^ 0", "BinaryExpression", 1);
addTest("1 << 2", "BinaryExpression", 4);
addTest("1 >> 2", "BinaryExpression", 0);
addTest("1 in [1]", "BinaryExpression", undefined, true);
addTest("A instanceof B", "BinaryExpression", undefined, true);
addTest("'abc' === 'abc' && 1 === 1", "LogicalExpression", true);
addTest("'abc' === 'abc' && 1 === 10", "LogicalExpression", false);
addTest("'abc' === 'xyz' && 1 === 1", "LogicalExpression", false);
addTest("'abc' === 'xyz' && 1 === 10", "LogicalExpression", false);
addTest("'abc' === 'abc' || 1 === 1", "LogicalExpression", true);
addTest("'abc' === 'abc' || 1 === 10", "LogicalExpression", true);
addTest("'abc' === 'xyz' || 1 === 1", "LogicalExpression", true);
addTest("'abc' === 'xyz' || 1 === 10", "LogicalExpression", false);
addTest("'abc' === 'abc' || config.flag === 1", "LogicalExpression", true);
addTest("obj.a === 'abc' || config.flag === 1", "LogicalExpression", undefined, true);
addTest("'abc' !== 'abc' && config.flag === 1", "LogicalExpression", false);
addTest("obj.a === 'abc' && 1 === 1", "LogicalExpression", undefined, true);
addTest("'abc' === 'abc' && (1 === 1 || config.flag)", "LogicalExpression", true);
addTest("'abc' === 'xyz' || (1 === 1 && config.flag)", "LogicalExpression", undefined, true);
addTest("'abc' === 'xyz' || (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
addTest("'abc' === 'abc' && (1 === 1 && 'four' === 'four')", "LogicalExpression", true);
});

View File

@ -0,0 +1,3 @@
{
"plugins": ["transform-es2015-arrow-functions"]
}

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