├── .gitignore ├── src ├── features │ ├── exponentiation-operator.js │ ├── async-generators.js │ ├── es2015-typeof-symbol.js │ ├── es2015-arrow-functions.js │ ├── es2015-unicode-regex.js │ ├── es3-property-literals.js │ ├── es2015-computed-properties.js │ ├── es2015-literals.js │ ├── es2015-parameters.js │ ├── es2015-shorthand-properties.js │ ├── es3-member-expression-literals.js │ ├── es5-property-mutators.js │ ├── trailing-function-commas.js │ ├── es2015-template-literals.js │ ├── es2015-spread.js │ ├── es2015-duplicate-keys.js │ ├── es2015-constants.js │ ├── es3-function-scope.js │ ├── es2015-classes.js │ ├── es2015-destructuring.js │ ├── es2015-object-super.js │ ├── es2015-function-name.js │ ├── es2015-sticky-regex.js │ ├── es2015-block-scoped-functions.js │ ├── object-rest-spread.js │ ├── function-sent.js │ ├── es2015-block-scoping.js │ ├── async-functions.js │ ├── es2015-for-of.js │ ├── es2015-generators.js │ └── es2015-generator-return.js └── features.yaml ├── lib ├── tests.js └── index.js ├── test.js ├── test.html ├── dist-template.js ├── package.json ├── README.md └── dist └── babel-features.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /sandbox 3 | -------------------------------------------------------------------------------- /src/features/exponentiation-operator.js: -------------------------------------------------------------------------------- 1 | assert( 2 | 2 ** 10 === 1024 3 | ) 4 | -------------------------------------------------------------------------------- /src/features/async-generators.js: -------------------------------------------------------------------------------- 1 | async function* foo(x) { 2 | return await x 3 | } 4 | -------------------------------------------------------------------------------- /src/features/es2015-typeof-symbol.js: -------------------------------------------------------------------------------- 1 | assert( 2 | typeof Symbol() === 'symbol' 3 | ) 4 | -------------------------------------------------------------------------------- /src/features/es2015-arrow-functions.js: -------------------------------------------------------------------------------- 1 | var foo = () => true 2 | 3 | assert( 4 | foo() 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-unicode-regex.js: -------------------------------------------------------------------------------- 1 | var re = /^.$/u 2 | 3 | assert( 4 | re.test("𠮷") 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es3-property-literals.js: -------------------------------------------------------------------------------- 1 | var foo = {if: true} 2 | 3 | assert( 4 | foo["if"] 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-computed-properties.js: -------------------------------------------------------------------------------- 1 | var foo = {["b" + "ar"]: true} 2 | 3 | assert( 4 | foo.bar 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-literals.js: -------------------------------------------------------------------------------- 1 | assert( 2 | 0b111 === 0o7 3 | ) 4 | 5 | assert( 6 | '\u{20bb7}' === '𠮷' 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-parameters.js: -------------------------------------------------------------------------------- 1 | function foo(x = true) { 2 | return x 3 | } 4 | 5 | assert( 6 | foo() 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-shorthand-properties.js: -------------------------------------------------------------------------------- 1 | var foo = true 2 | var bar = {foo} 3 | 4 | assert( 5 | bar.foo 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es3-member-expression-literals.js: -------------------------------------------------------------------------------- 1 | var foo = {} 2 | foo.if = true 3 | 4 | assert( 5 | foo.if 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es5-property-mutators.js: -------------------------------------------------------------------------------- 1 | var foo = { 2 | get bar() { return true } 3 | } 4 | 5 | assert( 6 | foo.bar 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/trailing-function-commas.js: -------------------------------------------------------------------------------- 1 | function foo(a, b,) { return a + b } 2 | 3 | assert( 4 | foo(1, 2,) === 3 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-template-literals.js: -------------------------------------------------------------------------------- 1 | var foo = "foo" 2 | var bar = `${foo}bar` 3 | 4 | assert( 5 | bar === "foobar" 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es2015-spread.js: -------------------------------------------------------------------------------- 1 | function foo(a, b, c) { 2 | return a + b === c 3 | } 4 | var list = [2, 3] 5 | 6 | assert( 7 | foo(1, ...list) 8 | ) 9 | -------------------------------------------------------------------------------- /src/features/es2015-duplicate-keys.js: -------------------------------------------------------------------------------- 1 | var x = {a: 5, a: 6} 2 | assert(x.a === 6) 3 | 4 | var y = { 5 | get a() { return 1 }, 6 | a: 2, 7 | } 8 | assert(y.a === 2) 9 | -------------------------------------------------------------------------------- /src/features/es2015-constants.js: -------------------------------------------------------------------------------- 1 | const foo = true 2 | 3 | try { 4 | foo = false 5 | } catch (e) { 6 | assert( 7 | foo 8 | ) 9 | } 10 | 11 | assert( 12 | foo 13 | ) 14 | -------------------------------------------------------------------------------- /src/features/es3-function-scope.js: -------------------------------------------------------------------------------- 1 | var foo = function $babel_features_es3_function_scope$() {} 2 | 3 | assert( 4 | typeof $babel_features_es3_function_scope$ === "undefined" 5 | ) 6 | -------------------------------------------------------------------------------- /src/features/es2015-classes.js: -------------------------------------------------------------------------------- 1 | class A { 2 | foo() { return false } 3 | } 4 | class B extends A { 5 | bar() { return !super.foo() } 6 | } 7 | 8 | assert( 9 | new B().bar() 10 | ) 11 | -------------------------------------------------------------------------------- /src/features/es2015-destructuring.js: -------------------------------------------------------------------------------- 1 | function foo({a, b: b1, c: [x, , y]}) { 2 | return a === 1 && b1 === 2 && x === 3 && y === 5 3 | } 4 | 5 | assert( 6 | foo({a: 1, b: 2, c: [3, 4, 5]}) 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-object-super.js: -------------------------------------------------------------------------------- 1 | var a = { foo() { return 'f' } } 2 | var b = { foo() { return super.foo() + 'oo' } } 3 | Object.setPrototypeOf(b, a) 4 | 5 | assert( 6 | b.foo() === 'foo' 7 | ) 8 | -------------------------------------------------------------------------------- /src/features/es2015-function-name.js: -------------------------------------------------------------------------------- 1 | var foo = function () {} 2 | 3 | assert( 4 | foo.name === 'foo' 5 | ) 6 | 7 | var obj = { bar: function () {} } 8 | 9 | assert( 10 | obj.bar.name === 'bar' 11 | ) 12 | -------------------------------------------------------------------------------- /src/features/es2015-sticky-regex.js: -------------------------------------------------------------------------------- 1 | // NOTE: Up to now, there is no runtime polyfill/shim available for sticky, 2 | // So this test never pass even with babel plugin applied. 3 | 4 | assert( 5 | /o+/y.sticky 6 | ) 7 | -------------------------------------------------------------------------------- /src/features/es2015-block-scoped-functions.js: -------------------------------------------------------------------------------- 1 | var outer = foo() 2 | function foo() { return 1 } 3 | 4 | { 5 | var inner = foo() 6 | function foo() { return 0 } 7 | } 8 | 9 | assert( 10 | inner === 0 && outer === 1 11 | ) 12 | -------------------------------------------------------------------------------- /src/features/object-rest-spread.js: -------------------------------------------------------------------------------- 1 | var {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4} 2 | assert(Object.keys(z).length === 2 && z.a === 3 && z.b === 4) 3 | 4 | var o = {x, y, ...z} 5 | assert(Object.keys(o).length === 4 && o.a === 3 && o.b === 4) 6 | -------------------------------------------------------------------------------- /src/features/function-sent.js: -------------------------------------------------------------------------------- 1 | function* g() { 2 | assert(function.sent === 1) 3 | yield 4 | assert(function.sent === 2) 5 | var x = yield 6 | assert(function.sent === x) 7 | } 8 | 9 | var test = g() 10 | test.next(1) 11 | test.next(2) 12 | test.next(Math.random()) 13 | -------------------------------------------------------------------------------- /src/features/es2015-block-scoping.js: -------------------------------------------------------------------------------- 1 | let foo = 0, bar = 1 2 | foo += bar 3 | { 4 | const bar = 2 5 | foo += bar 6 | } 7 | 8 | assert( 9 | foo === 3 10 | ) 11 | 12 | switch (0) { 13 | default: 14 | const bar = 3 15 | foo += bar 16 | } 17 | 18 | assert( 19 | foo === 6 20 | ) 21 | -------------------------------------------------------------------------------- /src/features/async-functions.js: -------------------------------------------------------------------------------- 1 | async function foo(x) { 2 | return await x 3 | } 4 | 5 | var called = false 6 | var p = foo({ 7 | then: function () { 8 | called = true 9 | throw 'test async functions' 10 | } 11 | }) 12 | 13 | assert(typeof p.then === 'function') 14 | assert(called) 15 | -------------------------------------------------------------------------------- /src/features/es2015-for-of.js: -------------------------------------------------------------------------------- 1 | var o = {} 2 | o[Symbol.iterator] = function () { 3 | var i = 0 4 | return { 5 | next: function () { 6 | if (i < 3) return {value: ++i} 7 | return {done: true} 8 | } 9 | } 10 | } 11 | var sum = 0 12 | for (var x of o) { 13 | sum += x 14 | } 15 | 16 | assert( 17 | sum === 6 18 | ) 19 | -------------------------------------------------------------------------------- /lib/tests.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var fs = require('fs') 4 | var yaml = require('js-yaml') 5 | 6 | module.exports = 7 | yaml.safeLoad(fs.readFileSync(__dirname + '/../src/features.yaml', 'utf-8')) 8 | .map(function (f) { 9 | return { 10 | feature: f, 11 | code: fs.readFileSync(__dirname + '/../src/features/' + f + '.js', 'utf-8') 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var f = require('./lib') 4 | console.log('Node.js:', process.versions.node) 5 | console.log('V8:', process.versions.v8) 6 | console.log() 7 | 8 | console.log('babel features test result:') 9 | console.log(f.test()) 10 | console.log() 11 | 12 | console.log('recommended plugins:') 13 | console.log(f.options().plugins) 14 | console.log() 15 | -------------------------------------------------------------------------------- /src/features/es2015-generators.js: -------------------------------------------------------------------------------- 1 | function* g() { 2 | yield 1 3 | yield 2 4 | yield 3 5 | } 6 | var foo = g() 7 | 8 | assert( 9 | foo.next().value === 1 10 | ) 11 | assert( 12 | foo.next().value === 2 13 | ) 14 | assert( 15 | foo.next().value === 3 16 | ) 17 | assert( 18 | foo.next().done 19 | ) 20 | 21 | var result = function* () { return 1 }().next() 22 | 23 | assert( 24 | result.done && result.value === 1 25 | ) 26 | -------------------------------------------------------------------------------- /src/features/es2015-generator-return.js: -------------------------------------------------------------------------------- 1 | var closed 2 | function* g() { 3 | try { 4 | closed = false 5 | while (true) yield 6 | } finally { 7 | closed = true 8 | } 9 | } 10 | var foo = g() 11 | foo.next() 12 | var result = foo.return('ok') 13 | 14 | assert( 15 | result.done && result.value === 'ok' && closed 16 | ) 17 | 18 | result = foo.next() 19 | 20 | assert( 21 | result.done && result.value === undefined 22 | ) 23 | 24 | result = function* () {}().return('ok2') 25 | 26 | assert( 27 | result.done && result.value === 'ok2' 28 | ) 29 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

 8 | 
26 | 


--------------------------------------------------------------------------------
/dist-template.js:
--------------------------------------------------------------------------------
 1 | void function(global) {
 2 | 	'use strict'
 3 | 
 4 | 	switch (moduleFormat()) {
 5 | 		case 'systemjs':
 6 | 			System.register([], function (_export) {
 7 | 				return {
 8 | 					execute: function () {
 9 | 						_export("test", test)
10 | 						_export("options", options)
11 | 					}
12 | 				}
13 | 			})
14 | 			break
15 | 		case 'amd':
16 | 			define({test: test, options: options})
17 | 			break
18 | 		case 'commonjs':
19 | 			exports.test = test
20 | 			exports.options = options
21 | 			break
22 | 		default:
23 | 			global.BabelFeatures = {test: test, options: options}
24 | 	}
25 | 
26 | 	/* BODY */
27 | 
28 | }(this)
29 | 


--------------------------------------------------------------------------------
/src/features.yaml:
--------------------------------------------------------------------------------
 1 | # ES3
 2 | - es3-member-expression-literals
 3 | - es3-property-literals
 4 | 
 5 | # ES5
 6 | - es5-property-mutators
 7 | 
 8 | # ES2015
 9 | - es2015-arrow-functions
10 | - es2015-block-scoped-functions
11 | - es2015-block-scoping
12 | - es2015-classes
13 | - es2015-computed-properties
14 | - es2015-constants
15 | - es2015-destructuring
16 | - es2015-duplicate-keys
17 | - es2015-for-of
18 | - es2015-function-name
19 | - es2015-literals
20 | - es2015-object-super
21 | - es2015-parameters
22 | - es2015-shorthand-properties
23 | - es2015-spread
24 | - es2015-sticky-regex
25 | - es2015-template-literals
26 | - es2015-typeof-symbol
27 | - es2015-unicode-regex
28 | 
29 | # Stage 3
30 | - exponentiation-operator   # ES2016
31 | - trailing-function-commas  # Stage 3
32 | 
33 | # Special features
34 | - es3-function-scope
35 | - es2015-generators
36 | - es2015-generator-return
37 | - async-functions     # Stage 3
38 | - async-generators    # Stage 2
39 | - function-sent       # Stage 2
40 | - object-rest-spread  # Stage 2
41 | 


--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "babel-features",
 3 |   "version": "2.0.1",
 4 |   "description": "Test babel features, can be used to generate babel options for specific compilation targets",
 5 |   "main": "lib/index.js",
 6 |   "scripts": {
 7 |     "prepublish": "node build",
 8 |     "test": "node test",
 9 |     "test-es2015": "BABEL_DISABLE_CACHE=1 babel-node --presets es2015 test",
10 |     "test-features": "BABEL_DISABLE_CACHE=1 babel-node --presets features test",
11 |     "test-generator": "BABEL_DISABLE_CACHE=1 babel-node test -w transform-async-to-generator,transform-es2015-generator-return",
12 |     "test-function-name": "BABEL_DISABLE_CACHE=1 babel-node --plugins transform-es2015-function-name test"
13 |   },
14 |   "repository": {
15 |     "type": "git",
16 |     "url": "git+https://github.com/hax/babel-features.git"
17 |   },
18 |   "keywords": [
19 |     "babel"
20 |   ],
21 |   "author": "HE Shi-Jun ",
22 |   "license": "ISC",
23 |   "bugs": {
24 |     "url": "https://github.com/hax/babel-features/issues"
25 |   },
26 |   "homepage": "https://github.com/hax/babel-features#readme",
27 |   "devDependencies": {
28 |     "babel-cli": "^6.16.0",
29 |     "babel-plugin-syntax-function-sent": "^6.8.0",
30 |     "babel-plugin-transform-es2015-generator-return": "^1.2.0",
31 |     "babel-polyfill": "^6.16.0",
32 |     "babel-preset-es2015": "^6.18.0",
33 |     "babel-preset-features": "^2.0.2",
34 |     "babel-preset-stage-0": "^6.16.0"
35 |   },
36 |   "dependencies": {
37 |     "js-yaml": "^3.7.0"
38 |   }
39 | }
40 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | # babel-features
 2 | 
 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/hax/babel-features.svg)](https://greenkeeper.io/)
 4 | Test babel features, can be used to generate babel options for specific compilation targets
 5 | 
 6 | 
 7 | NOTE: The latest version (2.x) is for babel 6.x, for babel 5.x please use [version 1.x](https://github.com/hax/babel-features/tree/1.x)
 8 | 
 9 | ## Install
10 | 
11 | ```sh
12 | npm install babel-features@latest
13 | ```
14 | 
15 | ## Usage
16 | 
17 | ### Node.js
18 | ```js
19 | var features = require('babel-features').test()
20 | console.log(features)
21 | // output on Node.js 5.0.0:
22 | // { 'es3-member-expression-literals': true,
23 | //   'es3-property-literals': true,
24 | //   'es5-property-mutators': true,
25 | //   'es2015-arrow-functions': true,
26 | //   'es2015-block-scoping': true,
27 | //   'es2015-classes': true,
28 | //   'es2015-computed-properties': true,
29 | //   'es2015-constants': true,
30 | //   'es2015-destructuring': false,
31 | //   'es2015-for-of': true,
32 | //   'es2015-function-name': false,
33 | //   'es2015-literals': true,
34 | //   'es2015-object-super': true,
35 | //   'es2015-parameters': false,
36 | //   'es2015-shorthand-properties': true,
37 | //   'es2015-spread': false,
38 | //   'es2015-sticky-regex': false,
39 | //   'es2015-template-literals': true,
40 | //   'es2015-typeof-symbol': true,
41 | //   'es2015-unicode-regex': false,
42 | //   'es2015-modules': false,
43 | //   'es2015-generators': false,
44 | //   'es3-function-scope': true }
45 | ```
46 | 
47 | ### Use babel preset
48 | See https://github.com/ariporad/babel-preset-features
49 | 
50 | ### Use babel register
51 | ```js
52 | var babelOptions = require('babel-features').options()
53 | require('babel-core/register')(babelOptions)
54 | ```
55 | 
56 | 
57 | ## TODO
58 | - Generate `.babelrc`
59 | - Generate `multiform.json` for https://github.com/callumlocke/multiform
60 | - Auto generate babel presets for some targets
61 | 


--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
  1 | 'use strict'
  2 | 
  3 | 
  4 | var tests = require('./tests')
  5 | 
  6 | /* BEGIN */
  7 | 
  8 | function test() {
  9 | 	var result = {}
 10 | 	for (var i = 0; i < tests.length; ++i) {
 11 | 		var name = tests[i].feature
 12 | 		var code = tests[i].code
 13 | 		result[name] = testFeature(code) || testFeature(code, true)
 14 | 	}
 15 | 	return result
 16 | }
 17 | 
 18 | function testFeature(code, strict) {
 19 | 	if (strict) code = '"use strict";' + code
 20 | 	try {
 21 | 		var r
 22 | 		new Function('assert', code)(function assert(test) {
 23 | 			if (r === false) return
 24 | 			r = !!test
 25 | 		})
 26 | 		if (r === undefined) throw new Error('no assert for ' + f)
 27 | 		if (r) return strict ? 'strict' : true
 28 | 	} catch (e) {}
 29 | 	return false
 30 | }
 31 | 
 32 | 
 33 | var enumerable = {}.propertyIsEnumerable
 34 | var PREFIX = 'transform-'
 35 | 
 36 | function options(opts) {
 37 | 	if (opts === undefined) opts = {}
 38 | 	var strict = opts.strict === undefined ? true : !!opts.strict
 39 | 	var modules = opts.modules === undefined ? true : !!opts.modules
 40 | 
 41 | 	var plugins = []
 42 | 	var testResult = test()
 43 | 	var regeneratorOptions = {generators: false, async: false, asyncGenerators: false}
 44 | 	for (var f in testResult) {
 45 | 		if (!enumerable.call(testResult, f)) continue
 46 | 		if (testResult[f] === true) continue
 47 | 		if (testResult[f] === 'strict' && strict) continue
 48 | 		switch (f) {
 49 | 			case 'es2015-constants':
 50 | 				plugins.push('check-' + f)
 51 | 				break
 52 | 			case 'trailing-function-commas':
 53 | 			case 'function-sent':
 54 | 				plugins.push('syntax-' + f)
 55 | 				break
 56 | 			case 'object-rest-spread':
 57 | 				plugins.push(PREFIX + f)
 58 | 				// currently transform-object-rest-spread only enable syntax,
 59 | 				// need destructuring transform,
 60 | 				// also need parameters transform for destructuring function parameters
 61 | 				if (testResult['es2015-destructuring']) {
 62 | 					plugins.push(	PREFIX + 'es2015-destructuring',
 63 | 						PREFIX + 'es2015-parameters')
 64 | 				}
 65 | 				break
 66 | 			case 'es3-function-scope':
 67 | 				plugins.push('jscript')
 68 | 				break
 69 | 			case 'es2015-generators':
 70 | 				regeneratorOptions.generators = true
 71 | 				break
 72 | 			case 'es2015-generator-return':
 73 | 				if (testResult['es2015-generators']) plugins.push(PREFIX + f)
 74 | 				break
 75 | 			case 'async-functions':
 76 | 				plugins.push('syntax-' + f)
 77 | 				regeneratorOptions.async = true
 78 | 				break
 79 | 			case 'async-generators':
 80 | 				plugins.push('syntax-' + f)
 81 | 				regeneratorOptions.asyncGenerators = true
 82 | 				break
 83 | 			default:
 84 | 				plugins.push(PREFIX + f)
 85 | 		}
 86 | 	}
 87 | 	plugins.push([PREFIX + 'regenerator', regeneratorOptions])
 88 | 
 89 | 	if (modules) {
 90 | 		var m = PREFIX + 'es2015-modules-' + moduleFormat()
 91 | 		if (strict) plugins.push(m)
 92 | 		else plugins.push([m, {strict: false}])
 93 | 	} else if (strict) {
 94 | 		plugins.push(PREFIX + 'strict-mode')
 95 | 	}
 96 | 
 97 | 	return {plugins: plugins}
 98 | }
 99 | 
100 | function moduleFormat() {
101 | 	if (typeof System === 'function' && typeof System.register === 'function') return 'systemjs'
102 | 	if (typeof define === 'function' && define.amd) return 'amd'
103 | 	if (typeof require === 'function' && typeof exports === 'object') return 'commonjs'
104 | 	return 'umd'
105 | }
106 | 
107 | /* END */
108 | 
109 | exports.test = test
110 | exports.options = options
111 | 


--------------------------------------------------------------------------------
/dist/babel-features.js:
--------------------------------------------------------------------------------
  1 | void function(global) {
  2 | 	'use strict'
  3 | 
  4 | 	switch (moduleFormat()) {
  5 | 		case 'systemjs':
  6 | 			System.register([], function (_export) {
  7 | 				return {
  8 | 					execute: function () {
  9 | 						_export("test", test)
 10 | 						_export("options", options)
 11 | 					}
 12 | 				}
 13 | 			})
 14 | 			break
 15 | 		case 'amd':
 16 | 			define({test: test, options: options})
 17 | 			break
 18 | 		case 'commonjs':
 19 | 			exports.test = test
 20 | 			exports.options = options
 21 | 			break
 22 | 		default:
 23 | 			global.BabelFeatures = {test: test, options: options}
 24 | 	}
 25 | 
 26 | 	var tests = [
 27 | 	{
 28 | 		"feature": "es3-member-expression-literals",
 29 | 		"code": "var foo = {}\nfoo.if = true\n\nassert(\n\tfoo.if\n)\n"
 30 | 	},
 31 | 	{
 32 | 		"feature": "es3-property-literals",
 33 | 		"code": "var foo = {if: true}\n\nassert(\n\tfoo[\"if\"]\n)\n"
 34 | 	},
 35 | 	{
 36 | 		"feature": "es5-property-mutators",
 37 | 		"code": "var foo = {\n\tget bar() { return true }\n}\n\nassert(\n\tfoo.bar\n)\n"
 38 | 	},
 39 | 	{
 40 | 		"feature": "es2015-arrow-functions",
 41 | 		"code": "var foo = () => true\n\nassert(\n\tfoo()\n)\n"
 42 | 	},
 43 | 	{
 44 | 		"feature": "es2015-block-scoped-functions",
 45 | 		"code": "var outer = foo()\nfunction foo() { return 1 }\n\n{\n\tvar inner = foo()\n\tfunction foo() { return 0 }\n}\n\nassert(\n\tinner === 0 && outer === 1\n)\n"
 46 | 	},
 47 | 	{
 48 | 		"feature": "es2015-block-scoping",
 49 | 		"code": "let foo = 0, bar = 1\nfoo += bar\n{\n\tconst bar = 2\n\tfoo += bar\n}\n\nassert(\n\tfoo === 3\n)\n\nswitch (0) {\n\tdefault:\n\t\tconst bar = 3\n\t\tfoo += bar\n}\n\nassert(\n\tfoo === 6\n)\n"
 50 | 	},
 51 | 	{
 52 | 		"feature": "es2015-classes",
 53 | 		"code": "class A {\n\tfoo() { return false }\n}\nclass B extends A {\n\tbar() { return !super.foo() }\n}\n\nassert(\n\tnew B().bar()\n)\n"
 54 | 	},
 55 | 	{
 56 | 		"feature": "es2015-computed-properties",
 57 | 		"code": "var foo = {[\"b\" + \"ar\"]: true}\n\nassert(\n\tfoo.bar\n)\n"
 58 | 	},
 59 | 	{
 60 | 		"feature": "es2015-constants",
 61 | 		"code": "const foo = true\n\ntry {\n\tfoo = false\n} catch (e) {\n\tassert(\n\t\tfoo\n\t)\n}\n\nassert(\n\tfoo\n)\n"
 62 | 	},
 63 | 	{
 64 | 		"feature": "es2015-destructuring",
 65 | 		"code": "function foo({a, b: b1, c: [x, , y]}) {\n\treturn a === 1 && b1 === 2 && x === 3 && y === 5\n}\n\nassert(\n\tfoo({a: 1, b: 2, c: [3, 4, 5]})\n)\n"
 66 | 	},
 67 | 	{
 68 | 		"feature": "es2015-duplicate-keys",
 69 | 		"code": "var x = {a: 5, a: 6}\nassert(x.a === 6)\n\nvar y = {\n\tget a() { return 1 },\n\ta: 2,\n}\nassert(y.a === 2)\n"
 70 | 	},
 71 | 	{
 72 | 		"feature": "es2015-for-of",
 73 | 		"code": "var o = {}\no[Symbol.iterator] = function () {\n\tvar i = 0\n\treturn {\n\t\tnext: function () {\n\t\t\tif (i < 3) return {value: ++i}\n\t\t\treturn {done: true}\n\t\t}\n\t}\n}\nvar sum = 0\nfor (var x of o) {\n\tsum += x\n}\n\nassert(\n\tsum === 6\n)\n"
 74 | 	},
 75 | 	{
 76 | 		"feature": "es2015-function-name",
 77 | 		"code": "var foo = function () {}\n\nassert(\n\tfoo.name === 'foo'\n)\n\nvar obj = { bar: function () {} }\n\nassert(\n\tobj.bar.name === 'bar'\n)\n"
 78 | 	},
 79 | 	{
 80 | 		"feature": "es2015-literals",
 81 | 		"code": "assert(\n\t0b111 === 0o7\n)\n\nassert(\n\t'\\u{20bb7}' === '𠮷'\n)\n"
 82 | 	},
 83 | 	{
 84 | 		"feature": "es2015-object-super",
 85 | 		"code": "var a = { foo() { return 'f' } }\nvar b = { foo() { return super.foo() + 'oo' } }\nObject.setPrototypeOf(b, a)\n\nassert(\n\tb.foo() === 'foo'\n)\n"
 86 | 	},
 87 | 	{
 88 | 		"feature": "es2015-parameters",
 89 | 		"code": "function foo(x = true) {\n\treturn x\n}\n\nassert(\n\tfoo()\n)\n"
 90 | 	},
 91 | 	{
 92 | 		"feature": "es2015-shorthand-properties",
 93 | 		"code": "var foo = true\nvar bar = {foo}\n\nassert(\n\tbar.foo\n)\n"
 94 | 	},
 95 | 	{
 96 | 		"feature": "es2015-spread",
 97 | 		"code": "function foo(a, b, c) {\n\treturn a + b === c\n}\nvar list = [2, 3]\n\nassert(\n\tfoo(1, ...list)\n)\n"
 98 | 	},
 99 | 	{
100 | 		"feature": "es2015-sticky-regex",
101 | 		"code": "// NOTE: Up to now, there is no runtime polyfill/shim available for sticky,\n//       So this test never pass even with babel plugin applied.\n\nassert(\n\t/o+/y.sticky\n)\n"
102 | 	},
103 | 	{
104 | 		"feature": "es2015-template-literals",
105 | 		"code": "var foo = \"foo\"\nvar bar = `${foo}bar`\n\nassert(\n\tbar === \"foobar\"\n)\n"
106 | 	},
107 | 	{
108 | 		"feature": "es2015-typeof-symbol",
109 | 		"code": "assert(\n\ttypeof Symbol() === 'symbol'\n)\n"
110 | 	},
111 | 	{
112 | 		"feature": "es2015-unicode-regex",
113 | 		"code": "var re = /^.$/u\n\nassert(\n\tre.test(\"𠮷\")\n)\n"
114 | 	},
115 | 	{
116 | 		"feature": "exponentiation-operator",
117 | 		"code": "assert(\n\t2 ** 10 === 1024\n)\n"
118 | 	},
119 | 	{
120 | 		"feature": "trailing-function-commas",
121 | 		"code": "function foo(a, b,) { return a + b }\n\nassert(\n\tfoo(1, 2,) === 3\n)\n"
122 | 	},
123 | 	{
124 | 		"feature": "es3-function-scope",
125 | 		"code": "var foo = function $babel_features_es3_function_scope$() {}\n\nassert(\n\ttypeof $babel_features_es3_function_scope$ === \"undefined\"\n)\n"
126 | 	},
127 | 	{
128 | 		"feature": "es2015-generators",
129 | 		"code": "function* g() {\n\tyield 1\n\tyield 2\n\tyield 3\n}\nvar foo = g()\n\nassert(\n\tfoo.next().value === 1\n)\nassert(\n\tfoo.next().value === 2\n)\nassert(\n\tfoo.next().value === 3\n)\nassert(\n\tfoo.next().done\n)\n\nvar result = function* () { return 1 }().next()\n\nassert(\n\tresult.done && result.value === 1\n)\n"
130 | 	},
131 | 	{
132 | 		"feature": "es2015-generator-return",
133 | 		"code": "var closed\nfunction* g() {\n\ttry {\n\t\tclosed = false\n\t\twhile (true) yield\n\t} finally {\n\t\tclosed = true\n\t}\n}\nvar foo = g()\nfoo.next()\nvar result = foo.return('ok')\n\nassert(\n\tresult.done && result.value === 'ok' && closed\n)\n\nresult = foo.next()\n\nassert(\n\tresult.done && result.value === undefined\n)\n\nresult = function* () {}().return('ok2')\n\nassert(\n\tresult.done && result.value === 'ok2'\n)\n"
134 | 	},
135 | 	{
136 | 		"feature": "async-functions",
137 | 		"code": "async function foo(x) {\n\treturn await x\n}\n\nvar called = false\nvar p = foo({\n\tthen: function () {\n\t\tcalled = true\n\t\tthrow 'test async functions'\n\t}\n})\n\nassert(typeof p.then === 'function')\nassert(called)\n"
138 | 	},
139 | 	{
140 | 		"feature": "async-generators",
141 | 		"code": "async function* foo(x) {\n\treturn await x\n}\n"
142 | 	},
143 | 	{
144 | 		"feature": "function-sent",
145 | 		"code": "function* g() {\n\tassert(function.sent === 1)\n\tyield\n\tassert(function.sent === 2)\n\tvar x = yield\n\tassert(function.sent === x)\n}\n\nvar test = g()\ntest.next(1)\ntest.next(2)\ntest.next(Math.random())\n"
146 | 	},
147 | 	{
148 | 		"feature": "object-rest-spread",
149 | 		"code": "var {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4}\nassert(Object.keys(z).length === 2 && z.a === 3 && z.b === 4)\n\nvar o = {x, y, ...z}\nassert(Object.keys(o).length === 4 && o.a === 3 && o.b === 4)\n"
150 | 	}
151 | ]
152 | 
153 | function test() {
154 | 	var result = {}
155 | 	for (var i = 0; i < tests.length; ++i) {
156 | 		var name = tests[i].feature
157 | 		var code = tests[i].code
158 | 		result[name] = testFeature(code) || testFeature(code, true)
159 | 	}
160 | 	return result
161 | }
162 | 
163 | function testFeature(code, strict) {
164 | 	if (strict) code = '"use strict";' + code
165 | 	try {
166 | 		var r
167 | 		new Function('assert', code)(function assert(test) {
168 | 			if (r === false) return
169 | 			r = !!test
170 | 		})
171 | 		if (r === undefined) throw new Error('no assert for ' + f)
172 | 		if (r) return strict ? 'strict' : true
173 | 	} catch (e) {}
174 | 	return false
175 | }
176 | 
177 | 
178 | var enumerable = {}.propertyIsEnumerable
179 | var PREFIX = 'transform-'
180 | 
181 | function options(opts) {
182 | 	if (opts === undefined) opts = {}
183 | 	var strict = opts.strict === undefined ? true : !!opts.strict
184 | 	var modules = opts.modules === undefined ? true : !!opts.modules
185 | 
186 | 	var plugins = []
187 | 	var testResult = test()
188 | 	var regeneratorOptions = {generators: false, async: false, asyncGenerators: false}
189 | 	for (var f in testResult) {
190 | 		if (!enumerable.call(testResult, f)) continue
191 | 		if (testResult[f] === true) continue
192 | 		if (testResult[f] === 'strict' && strict) continue
193 | 		switch (f) {
194 | 			case 'es2015-constants':
195 | 				plugins.push('check-' + f)
196 | 				break
197 | 			case 'trailing-function-commas':
198 | 			case 'function-sent':
199 | 				plugins.push('syntax-' + f)
200 | 				break
201 | 			case 'object-rest-spread':
202 | 				plugins.push(PREFIX + f)
203 | 				// currently transform-object-rest-spread only enable syntax,
204 | 				// need destructuring transform,
205 | 				// also need parameters transform for destructuring function parameters
206 | 				if (testResult['es2015-destructuring']) {
207 | 					plugins.push(	PREFIX + 'es2015-destructuring',
208 | 						PREFIX + 'es2015-parameters')
209 | 				}
210 | 				break
211 | 			case 'es3-function-scope':
212 | 				plugins.push('jscript')
213 | 				break
214 | 			case 'es2015-generators':
215 | 				regeneratorOptions.generators = true
216 | 				break
217 | 			case 'es2015-generator-return':
218 | 				if (testResult['es2015-generators']) plugins.push(PREFIX + f)
219 | 				break
220 | 			case 'async-functions':
221 | 				plugins.push('syntax-' + f)
222 | 				regeneratorOptions.async = true
223 | 				break
224 | 			case 'async-generators':
225 | 				plugins.push('syntax-' + f)
226 | 				regeneratorOptions.asyncGenerators = true
227 | 				break
228 | 			default:
229 | 				plugins.push(PREFIX + f)
230 | 		}
231 | 	}
232 | 	plugins.push([PREFIX + 'regenerator', regeneratorOptions])
233 | 
234 | 	if (modules) {
235 | 		var m = PREFIX + 'es2015-modules-' + moduleFormat()
236 | 		if (strict) plugins.push(m)
237 | 		else plugins.push([m, {strict: false}])
238 | 	} else if (strict) {
239 | 		plugins.push(PREFIX + 'strict-mode')
240 | 	}
241 | 
242 | 	return {plugins: plugins}
243 | }
244 | 
245 | function moduleFormat() {
246 | 	if (typeof System === 'function' && typeof System.register === 'function') return 'systemjs'
247 | 	if (typeof define === 'function' && define.amd) return 'amd'
248 | 	if (typeof require === 'function' && typeof exports === 'object') return 'commonjs'
249 | 	return 'umd'
250 | }
251 | 
252 | }(this)
253 | 


--------------------------------------------------------------------------------