Compare commits

...

160 Commits

Author SHA1 Message Date
Sebastian McKenzie
2845c1a894 v2.6.0 2015-01-06 17:44:13 +11:00
Sebastian McKenzie
ed51728aba remove unused variable 2015-01-06 17:43:26 +11:00
Sebastian McKenzie
4c8f4121f0 add 2.6.0 changelog 2015-01-06 17:41:57 +11:00
Sebastian McKenzie
b9e4340700 better use strict handling inside of modules 2015-01-06 17:32:00 +11:00
Sebastian McKenzie
4c9e39afa1 replace slice with a loop in rest parameters 2015-01-06 17:05:52 +11:00
Sebastian McKenzie
7439247095 change spread call expression context from null to undefined 2015-01-06 16:45:39 +11:00
Sebastian McKenzie
254424ced5 add npm install to make bootstrap 2015-01-06 12:17:39 +11:00
Sebastian McKenzie
4fc6823ece no ast check on api tests 2015-01-06 12:17:29 +11:00
Sebastian McKenzie
d531c8aa4c add expressionStatement around system module wildcard exports 2015-01-06 12:17:20 +11:00
Sebastian McKenzie
fc59f1ff46 add closure around let scoping return tests 2015-01-06 12:16:34 +11:00
Sebastian McKenzie
7c7cd6f9b8 use thisExpression instead of identifier("this") 2015-01-06 12:08:53 +11:00
Sebastian McKenzie
e3174d5a39 add esvalid validation to transformation tests 2015-01-06 12:08:40 +11:00
Sebastian McKenzie
2558a5e12e better wildcard imports and exports - fixes #224 2015-01-06 11:48:23 +11:00
Sebastian McKenzie
7526ae5486 fix register require in transformation helper 2015-01-06 10:45:10 +11:00
Sebastian McKenzie
811fcf7e1b upgrade acorn-6to5 2015-01-06 10:44:13 +11:00
Sebastian McKenzie
62818d468e Merge branch 'traceur' 2015-01-06 10:40:42 +11:00
Sebastian McKenzie
a88bd69e30 justify disabled traceur tests 2015-01-06 10:39:56 +11:00
Sebastian McKenzie
8164bb17ce don't use interopRequire if noInteropRequire is set for default module formatter 2015-01-06 10:39:47 +11:00
Sebastian McKenzie
3ec97fc86d only check if a function is a declaration in common module hoisting 2015-01-06 10:39:18 +11:00
Sebastian McKenzie
b38a00d70e add destructuring defaults #230 2015-01-06 10:38:55 +11:00
Sebastian McKenzie
1b85607d7d add ability to assert just an error instead of an error message in tests 2015-01-06 10:38:28 +11:00
Sebastian McKenzie
fd6704ac25 update optional bluebird coroutine test to reflect new addImport 2015-01-06 10:38:11 +11:00
Sebastian McKenzie
9c527f9d9c make regenerator test use the ALL environment var 2015-01-06 10:37:40 +11:00
Sebastian McKenzie
6cf318d60f add updated interop modules to tests 2015-01-06 10:37:11 +11:00
Sebastian McKenzie
64f9f4dff5 only check declarations in let scoping reference check 2015-01-06 10:36:49 +11:00
Sebastian McKenzie
145413dbfd Merge pull request #396 from caspervonb/master
Add .es to register extensions
2015-01-05 20:55:36 +11:00
Casper Beyer
8c58e0f14c Add .es extension to util.canCompile 2015-01-05 16:43:00 +08:00
Casper Beyer
d62914e41c Amend require documentation to include '.es' extension 2015-01-05 16:35:01 +08:00
Casper Beyer
85db67edf4 Add .es to register extensions
.es is a known ecmascript file extension and should be handled by the loader
See RFC 4329, 8.2.
2015-01-05 16:10:41 +08:00
Sebastian McKenzie
348ad2e25c better dynamic imports - fixes #393 2015-01-05 12:40:12 +11:00
Sebastian McKenzie
5ce8ee6c2b add inheritance type check to tests 2015-01-05 12:39:46 +11:00
Sebastian McKenzie
98ad5d42e1 add optional typeof symbol test options 2015-01-05 12:39:12 +11:00
Sebastian McKenzie
b12734abd6 only run traceur and esnext on ALL_6TO5_TESTS environment variable 2015-01-05 12:39:01 +11:00
Sebastian McKenzie
f34907d518 add make bootstrap 2015-01-05 12:38:34 +11:00
Sebastian McKenzie
3bd6ec20c1 remove regenerator tests and git submodule regenerator 2015-01-05 12:38:26 +11:00
Sebastian McKenzie
b8d4479333 fix linting error 2015-01-05 10:24:23 +11:00
Sebastian McKenzie
ed833be34a force computed property on number literal property 2015-01-05 10:23:30 +11:00
Sebastian McKenzie
16024242b0 add type check to inherits template 2015-01-05 10:23:06 +11:00
Sebastian McKenzie
77add8704e alias hidden properties onto it's transformer instance 2015-01-05 10:22:27 +11:00
Sebastian McKenzie
9fd1ec0596 more reliable toValidIdentifier checking, including reserved words 2015-01-05 10:22:06 +11:00
Sebastian McKenzie
90ce4e93ed don't break let reference checking on loops in let scoping 2015-01-05 10:21:50 +11:00
Sebastian McKenzie
cf7b9234c1 make typeofSymbol transformer optional 2015-01-05 10:21:32 +11:00
Sebastian McKenzie
f85eeeb93c fix blockHoist and declarations transformers unneccesarily unshifting use strict statements 2015-01-05 10:21:24 +11:00
Sebastian McKenzie
45d0eea842 fix native type constructor spread - closes #373 2015-01-05 10:20:36 +11:00
Sebastian McKenzie
b0c9d3daa4 Merge branch 'master' into traceur 2015-01-05 10:19:41 +11:00
Sebastian McKenzie
3f152bfc3f upgrade core-js from 0.3.3 to 0.40 and regenerator from 0.8.2 to 0.8.3 2015-01-05 10:19:01 +11:00
Sebastian McKenzie
ffbfa5281b move esnext tests into their own fixtures folder 2015-01-05 10:18:42 +11:00
Sebastian McKenzie
7f87ca0d43 move traceur test suite to a git submodule 2015-01-05 10:18:30 +11:00
Sebastian McKenzie
a8fad4b958 add traceur gits ubmodule 2015-01-05 10:17:23 +11:00
Sebastian McKenzie
945ea145e7 remove esnext from differences table 2015-01-05 10:17:09 +11:00
Sebastian McKenzie
4f10bcedda Merge pull request #392 from thejameskyle/changlog-tags
Add tags to top of changelog
2015-01-05 10:15:36 +11:00
James Kyle
601b3d584f Add tags to top of changelog 2015-01-04 14:41:17 -08:00
Sebastian McKenzie
42878f85fe Merge pull request #391 from thejameskyle/extend-null-check
Make parent constructor check explicit when extending from null
2015-01-05 09:14:33 +11:00
James Kyle
3b4c9c415e Make parent constructor check explicit when extending from null - fixes #386 2015-01-04 13:45:13 -08:00
Sebastian McKenzie
7345899343 Merge pull request #389 from caspervonb/master
Make build target the default target
2015-01-05 03:01:32 +11:00
Casper Beyer
316102ab14 Make build target the default target
The top target is implicitly the default target, having this as *clean*
is rather unothodox, usually it would be the executable or library target.
2015-01-04 23:53:28 +08:00
Sebastian McKenzie
4c2b85deec better NewExpression paren insertion 2015-01-05 01:06:41 +11:00
Sebastian McKenzie
108784db20 add typeof and interop-require-wildcard helpers 2015-01-05 01:06:28 +11:00
Sebastian McKenzie
a3b30bae7a better traceur test api 2015-01-05 01:06:16 +11:00
Sebastian McKenzie
6420954c53 remove traceur tests 2015-01-05 01:06:07 +11:00
Sebastian McKenzie
a6fda01fa0 Merge branch 'master' into traceur
Conflicts:
	package.json
2015-01-05 00:53:59 +11:00
Sebastian McKenzie
655cc8fcb9 v2.5.0 2015-01-05 00:17:35 +11:00
Sebastian McKenzie
97a504bbef 2.5.0 changelog 2015-01-05 00:16:39 +11:00
Sebastian McKenzie
bf3443962b disable failing esnext tests 2015-01-05 00:15:46 +11:00
Sebastian McKenzie
a4394494ef remove noDuplicateProperties test 2015-01-05 00:15:37 +11:00
Sebastian McKenzie
2b333de81f add basic support for assignment patterns 2015-01-05 00:07:50 +11:00
Sebastian McKenzie
b81f824b7e normalise wildcard import into a default object 2015-01-05 00:07:22 +11:00
Sebastian McKenzie
9bfb8c440a add optional typeof symbol transformer 2015-01-05 00:06:57 +11:00
Sebastian McKenzie
9a6c13a6a4 Merge branch 'esnext'
Conflicts:
	package.json
2015-01-05 00:03:53 +11:00
Sebastian McKenzie
ac8d77fb45 upgrade acorn-6to5 2015-01-04 21:14:59 +11:00
Sebastian McKenzie
09c88238e1 upgrade acorn-6to5 2015-01-04 20:37:14 +11:00
Sebastian McKenzie
103b619364 remove arity traceur test check 2015-01-04 20:36:35 +11:00
Sebastian McKenzie
c8a404fb72 Merge branch 'master' into traceur 2015-01-04 20:26:41 +11:00
Sebastian McKenzie
05669204dd fix generation expression comment tests 2015-01-04 20:26:07 +11:00
Sebastian McKenzie
38e6abec02 Merge branch 'master' into traceur 2015-01-04 20:23:37 +11:00
Sebastian McKenzie
1abef2c1e2 more intelligent parens wrapping of no line terminator expressions - fixes #376, reference #349 2015-01-04 20:22:24 +11:00
Sebastian McKenzie
cc6678361a comment out arity check 2015-01-04 20:20:03 +11:00
Sebastian McKenzie
2587694d44 Merge branch 'master' into traceur
Conflicts:
	package.json
2015-01-04 19:52:52 +11:00
Sebastian McKenzie
f16079c83f v2.4.10 2015-01-04 19:51:52 +11:00
Sebastian McKenzie
b7132f3529 upgrade acorn-6to5 2015-01-04 19:50:54 +11:00
Sebastian McKenzie
ed41f1652e v2.4.9 2015-01-04 19:49:54 +11:00
Sebastian McKenzie
c522bdb4b9 upgrade acorn-6to5 2015-01-04 19:48:47 +11:00
Sebastian McKenzie
005362a615 update tests to 2.4.9 fixes 2015-01-04 19:48:14 +11:00
Sebastian McKenzie
88e542634f fix linting errors 2015-01-04 19:45:18 +11:00
Sebastian McKenzie
c8304138eb add 2.4.9 changelog 2015-01-04 19:44:04 +11:00
Sebastian McKenzie
35608d497e make comprehension for-of loop a let 2015-01-04 19:42:25 +11:00
Sebastian McKenzie
b5a78355c4 add initProps to single call expression in computed property names - fixes #378 2015-01-04 19:42:16 +11:00
Sebastian McKenzie
223e28ba8f upgrade acorn-6to5 2015-01-04 19:40:51 +11:00
Sebastian McKenzie
6a35bdb42b add traceur test suite 2015-01-04 19:40:09 +11:00
Sebastian McKenzie
18813f26bb Merge branch 'master' into esnext 2015-01-04 15:32:41 +11:00
Sebastian McKenzie
ccabb91f69 add back deleted object-define-properties-closure template 2015-01-04 15:30:59 +11:00
Sebastian McKenzie
35fda899a8 remove spec-no-duplicate-properties transformer 2015-01-04 15:30:40 +11:00
Sebastian McKenzie
e2f01d41a3 fix api test 2015-01-04 13:42:16 +11:00
Sebastian McKenzie
931a80f5b3 rename "declarations" to the more sane "helpers" 2015-01-04 13:34:56 +11:00
Sebastian McKenzie
9a2fd22e91 add newline to esnext super change proto test 2015-01-04 08:35:28 +11:00
Sebastian McKenzie
cbcad22d81 update default parameters transformer to use var a = arguments[0] === undefined ? 1 : arguments[0]; instead of if (a === undefined) a = 1; 2015-01-04 08:35:14 +11:00
Sebastian McKenzie
4d5861cfdc remove invalid strict-mode es6 next class test 2015-01-04 08:34:25 +11:00
Sebastian McKenzie
c578db7ae8 upgrade acorn-6to5 2015-01-04 08:34:14 +11:00
Sebastian McKenzie
dea73b7186 change code assertion to 6to5 output 2015-01-04 08:01:29 +11:00
Sebastian McKenzie
4506e39cf5 add toString key to instance keys as methods are enumerable 2015-01-04 08:01:08 +11:00
Sebastian McKenzie
7ab6df093b use Symbol.iterator instead of @@iterator 2015-01-04 08:00:49 +11:00
Sebastian McKenzie
22eeae1a93 use assert instead of expect 2015-01-04 08:00:40 +11:00
Sebastian McKenzie
a645ae0583 contextLiteral fallback in es6-spread transformer 2015-01-04 07:59:56 +11:00
Sebastian McKenzie
7f4efecb7d support for CallExpression in Scope.prototype.generateUidBasedOnNode 2015-01-04 07:59:43 +11:00
Sebastian McKenzie
0c0f40d14a only automatically assume test is exec if it has a js extension 2015-01-04 07:58:49 +11:00
Sebastian McKenzie
cb54c11d84 add esnext tests 2015-01-04 07:39:11 +11:00
Sebastian McKenzie
55123be7d7 use t.toComputedKey in computed property name transformer 2015-01-04 07:38:49 +11:00
Sebastian McKenzie
324a0b408a add optional protoToAssign transformer 2015-01-04 07:38:36 +11:00
Sebastian McKenzie
8b2788e930 fix es6-property-method-assignment tests name 2015-01-03 21:48:22 +11:00
Sebastian McKenzie
d945379b5b remove isDynamic checks and always execute those expressions **once** 2015-01-03 21:48:06 +11:00
Sebastian McKenzie
5a622ac9c7 update traversal api in optional-bluebird-coroutines transformer 2015-01-03 20:11:21 +11:00
Sebastian McKenzie
0e9eac610b rename es5-property-methods-assignment to es6-property-method-assignment and add function ids to object methods and remap them if they contain a reference to themselves - fixes #308 2015-01-03 20:11:00 +11:00
Sebastian McKenzie
1de94a2705 fix code styling on es6 arrow functions nested test 2015-01-03 20:09:14 +11:00
Sebastian McKenzie
71132c3538 add types.toComputedPropertyKey helper 2015-01-03 20:08:39 +11:00
Sebastian McKenzie
d20ab0eb05 rename traverse stop method to skip and add a stop method that actually breaks the current traversal 2015-01-03 20:08:31 +11:00
Sebastian McKenzie
51f7e75d2e fix formatting of code of conduct paragraph in CONTRIBUTING.md 2015-01-03 11:17:55 +11:00
Sebastian McKenzie
ab4b5ce994 Merge pull request #309 from antn/add-code-of-conduct
add code of conduct
2015-01-03 11:16:05 +11:00
Sebastian McKenzie
f0d50ca9a2 add browser.js to package.json 2015-01-03 08:19:18 +11:00
Sebastian McKenzie
5168355a64 fix differences copytext grammar 2015-01-03 08:19:11 +11:00
Sebastian McKenzie
2f209a9e4e v2.4.8 2015-01-03 07:37:15 +11:00
Sebastian McKenzie
20695eaba6 add 2.4.8 changelog 2015-01-03 07:36:34 +11:00
Sebastian McKenzie
340a4dd1f2 fix code styling #370 2015-01-03 07:35:45 +11:00
Sebastian McKenzie
ef1c7a5c69 Merge pull request #370 from hughsk/browserify-register
Make require("6to5/register") work with browserify
2015-01-03 07:33:15 +11:00
Hugh Kennedy
5a01beaa1f Make require("6to5/register") work with browserify
Previously, you'd have to create a separate file for using 6to5
with both node and browserify, as the latter wasn't able to properly
handle loading 6to5's dependency tree and would crash on attempting
to do so.

This change instructs browserify to use "register-browser.js" in place
of "register.js". "register-browser.js" still loads the 6to5 polyfill,
but is otherwise ignored.
2015-01-02 21:30:40 +01:00
Sebastian McKenzie
5a5bf7b4ac v2.4.7 2015-01-03 06:10:52 +11:00
Sebastian McKenzie
88ee15bb4d upgrade acorn-6to5 #367 2015-01-03 06:10:10 +11:00
Sebastian McKenzie
3e51b65095 v2.4.6 2015-01-03 05:29:28 +11:00
Sebastian McKenzie
371df9ad09 add 2.4.6 changelog 2015-01-03 05:25:48 +11:00
Sebastian McKenzie
d43d5ff409 move coreAliasing and undefinedToVoid transformers down 2015-01-03 05:24:43 +11:00
Sebastian McKenzie
c2c8e52430 add modules caveat - fixes #368 2015-01-03 05:23:12 +11:00
Sebastian McKenzie
57c0ebc5f4 v2.4.5 2015-01-02 22:22:52 +11:00
Sebastian McKenzie
339bf82481 avoid printing comments if they've already been output - fixes #365 2015-01-02 22:22:01 +11:00
Sebastian McKenzie
d981c06444 v2.4.4 2015-01-02 19:24:56 +11:00
Sebastian McKenzie
8269e1488b fix incorrect scripts reference in browser 2015-01-02 19:23:50 +11:00
Sebastian McKenzie
ddda7a020f add 2.4.4 changelog 2015-01-02 19:22:03 +11:00
Sebastian McKenzie
7e9340864a lowercase object rest/spread feature name in doc/index 2015-01-02 19:20:14 +11:00
Sebastian McKenzie
5ec19f23c3 add test skeleton for types and add jsdoc comments to types 2015-01-02 19:20:05 +11:00
Sebastian McKenzie
ba48b66458 add types.appendToMemberExpression and types.prependToMemberExpression helpers 2015-01-02 16:46:58 +11:00
Sebastian McKenzie
6e8c73f65f fix incorrect member expression properties 2015-01-02 16:39:35 +11:00
Sebastian McKenzie
b34fcb0cd9 split up method binding and add description for memoization assignment operator 2015-01-02 14:33:51 +11:00
Sebastian McKenzie
ff7129f1aa remove ES5 methods from caveats and change IE classes note to IE 10 and below 2015-01-02 14:33:38 +11:00
Sebastian McKenzie
fbabd193a4 add module type to 6to5 browser 2015-01-02 14:33:18 +11:00
Sebastian McKenzie
876d69798c v2.4.3 2015-01-02 05:19:42 +11:00
Sebastian McKenzie
1a963ddc06 remove unused variable 2015-01-02 05:19:00 +11:00
Sebastian McKenzie
beb5acea6b better addImport with good hoisting etc 2015-01-02 05:18:03 +11:00
Sebastian McKenzie
6a290f233e add 2.4.3 changelog 2015-01-02 05:01:18 +11:00
Sebastian McKenzie
74563d88ed upgrade acorn-6to5 2015-01-02 05:00:23 +11:00
Sebastian McKenzie
a18177026c add support for statements in asyncToGenerator and bluebirdCoroutines transformers 2015-01-02 04:58:59 +11:00
Sebastian McKenzie
a813341433 v2.4.2 2015-01-02 04:25:44 +11:00
Sebastian McKenzie
4968de9803 fix linting errors 2015-01-02 04:24:56 +11:00
Sebastian McKenzie
0de2d33e8d add 2.4.2 changelog 2015-01-02 04:24:19 +11:00
Sebastian McKenzie
6f81ddd0d5 upgrade acorn-6to5 2015-01-02 04:24:19 +11:00
Sebastian McKenzie
6b83055b12 alias flat references in coreAliasing transformer 2015-01-02 04:24:19 +11:00
Sebastian McKenzie
080c23d5ed Merge pull request #360 from mquandalle/patch-1
Extend the license to the new year
2015-01-02 04:06:22 +11:00
Sebastian McKenzie
293bec58d7 remove appveyor badge 2015-01-02 03:53:33 +11:00
Sebastian McKenzie
93ceafc732 better uid names 2015-01-02 03:53:28 +11:00
Sebastian McKenzie
b2bac04b72 update object getter memoization docs to reflect new changes 2015-01-02 03:04:26 +11:00
Maxime Quandalle
c7a02ca289 Extend the license to the new year 2015-01-01 13:03:38 +01:00
antn
f4055612e5 add link to code of conduct [ci skip] 2014-12-16 22:29:37 -08:00
antn
46911bd28c add code of conduct 2014-12-16 22:17:35 -08:00
396 changed files with 3000 additions and 2858 deletions

6
.gitmodules vendored Normal file
View File

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

View File

@@ -1,6 +1,80 @@
# Changelog
Gaps between patch versions are faulty/broken releases.
> **Tags:**
> - [New Feature]
> - [Bug Fix]
> - [Spec Compliancy]
> - [Breaking Change]
> - [Documentation]
> - [Internal]
> - [Misc]
_Note: Gaps between patch versions are faulty/broken releases._
## 2.6.0
* [Internal] Fix incorrect AST node `identifier("this")`.
* [Spec Compliancy] Add `interopRequireWildcard` around wildcard imports and exports to handle non-object exports.
* [Internal] Upgrade `acorn-6to5`.
* [New Feature] Basic destructuring defaults
* [New Feature] Add `.es` to list of supported extensions.
* [New Feature] Add optional `typeofSymbol` transformer.
* [Bug Fix] Better handling of number literal property keys.
* [Bug Fix] [Internal] Better `toIdentifier` method that handles reserved words.
* [Internal] Upgrade to `core-js` 4.0.0.
* [Internal] Upgrade to `regenerator` 0.8.3.
* [Bug Fix] Handle `NewExpression` paren insertion edegcases better.
* [Spec Compliancy] Class inheritance now has a `function` or `null` type check.
* [Misc] Move `"use strict";` to inside module bodies instead of at the top of the file.
## 2.5.0
* Remove `noDuplicateProperties` transformer.
* Better generated UIDs based on nodes.
* Default parameters now use `arguments[i]`, conditionals and variable declarations instead of using long-form if statements.
## 2.4.10
* Upgrade `acorn-6to5`.
## 2.4.9
* Upgrade `acorn-6to5`.
* Add optional `protoToAssign` transformer.
* Fix missing properties from computed property keys.
* Make ES7 comprehensions `let` variables.
## 2.4.8
* Make `require("6to5/register")` work with browserify - [#370](https://github.com/6to5/6to5/pull/370). Thanks [@hughsk](https://github.com/hughsk)!
## 2.4.7
* Upgrade `acorn-6to5`.
## 2.4.6
* Move `coreAliasing` and `undefinedToVoid` transformers down to catch `moduleFormatter` transforms.
## 2.4.5
* Avoid printing comments if they've already been output.
## 2.4.4
* Add `module` type to browser build `<script>` handler.
* Fix some `MemberExpression` modifying incorrectly setting `property` to a `MemberExpression`.
## 2.4.3
* Upgrade `acorn-6to5`.
* Add support for `FunctionDeclaration`s in `bluebirdCoroutines` and `asyncToGenerators` transformers.
## 2.4.2
* Upgrade `acorn-6to5`.
* Better uids generated for various transformers based on parent node.
* Alias flat references in `coreAliasing` transformer.
## 2.4.1

13
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,13 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)

View File

@@ -1,5 +1,7 @@
# Contributing
Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
* **General**
* No ES6 syntax features or methods, exclusively ES5.
* Max of five arguments for functions

View File

@@ -1,4 +1,4 @@
Copyright (c) 2014 Sebastian McKenzie
Copyright (c) 2014-2015 Sebastian McKenzie
MIT License

View File

@@ -6,7 +6,23 @@ MOCHA_CMD = node_modules/mocha/bin/_mocha
export NODE_ENV = test
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build bootstrap
build:
mkdir -p dist
node bin/cache-templates
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
node bin/6to5-runtime >dist/runtime.js
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
rm -rf templates.json
clean:
rm -rf coverage templates.json test/tmp dist
@@ -45,22 +61,6 @@ test-browser:
test -n "`which open`" && open test/browser.html
build:
mkdir -p dist
node bin/cache-templates
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
node bin/6to5-runtime >dist/runtime.js
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
rm -rf templates.json
publish:
git pull --rebase
@@ -81,3 +81,8 @@ publish:
git push --follow-tags
rm -rf templates.json browser.js runtime.js browser-polyfill.js
bootstrap:
npm install
git submodule update --init
cd vendor/regenerator; npm install

3
NOTES.md Normal file
View File

@@ -0,0 +1,3 @@
# Notes
* Wildcard exports/imports wont normalise if `export default` is a non-object.

View File

@@ -11,10 +11,6 @@
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5/master.svg?style=flat&amp;label=travis">
</a>
<a href="https://ci.appveyor.com/project/sebmck/6to5">
<img alt="Appveyor Status" src="http://img.shields.io/appveyor/ci/sebmck/6to5.svg?style=flat&amp;label=appveyor">
</a>
<a href="https://codeclimate.com/github/6to5/6to5">
<img alt="Code Climate Score" src="http://img.shields.io/codeclimate/github/6to5/6to5.svg?style=flat">
</a>

View File

@@ -9,12 +9,15 @@ You may alternatively selectively include what you need:
| Feature | Requirements |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Abstract References | [experimental](experimental.md), `Symbol` |
| Array destructuring | `Array.isArray`, `Array.from` |
| Array destructuring | `Array.from` |
| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) |
| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` |
| Comprehensions | [experimental](experimental.md), `Array.from` |
| For Of | `Symbol`, `prototype[Symbol.iterator]` |
| Modules | `Object.assign`* |
| Object spread/rest | [experimental](experimental.md), `Object.assign` |
| Spread | `Array.isArray`, `Array.from` |
| Spread | `Array.from` |
*Only required for exporting a non-function `default` with additional `export`s.
## ES5
@@ -26,13 +29,13 @@ ES5 such as lower versions of IE then using the
## Internet Explorer
### Classes (9 and below)
### Classes (10 and below)
If you're inheriting from a class then static properties are inherited from it
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
this is widely supported but you may run into problems with much older browsers.
**NOTE:** `__proto__` is not supported on IE <= 9 so static properties
**NOTE:** `__proto__` is not supported in IE <= 10 so static properties
**will not** be inherited. A possible workaround is to use `super();`:
```javascript
@@ -56,4 +59,4 @@ unfortunate as it's required to set getters and setters. Due to this if
you plan on supporting IE8 or below then the user of getters and setters
isn't recommended.
Reference: [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Internet_Explorer_8_specific_notes).
**Reference**: [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Internet_Explorer_8_specific_notes).

View File

@@ -49,13 +49,12 @@ var seattlers = (function() {
}());
```
As you can tell, it's not very pretty, unreadable even. Instead of mapping
directly to a runtime, like other transpilers, 6to5 maps directly to the
equivalent ES5.
As you can tell, it's not very pretty. Instead of mapping directly to a
runtime, like other transpilers, 6to5 maps directly to the equivalent ES5.
Sometimes there are little inline functions that 6to5 needs. These are
placed at the top of your file much like coffee-script does. If these
are bother you then you can use the [optional runtime](optional-runtime.md).
bother you then you can use the [optional runtime](optional-runtime.md).
We promise that these inline functions will never be significant and will
always be used as little as possible.
@@ -79,43 +78,43 @@ that when you turn it off and use your code in a full ES6 environment
### Features
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
| Source maps | ✓ | ✓ | ✓ | ✓ | | ✓ |
| No compiler global pollution | ✓ | | ✓ | ✓ | | ✓ |
| Optional runtime | ✓ | | ✓ | | | ✓ |
| Browser compiler | ✓ | ✓ | | ✓ | | |
| | 6to5 | Traceur | es6-transpiler | es6now | jstransform |
| ---------------------------- | ---- | ------- | -------------- | ------ | ----------- |
| Source maps | ✓ | ✓ | ✓ | | ✓ |
| No compiler global pollution | ✓ | | ✓ | | ✓ |
| Optional runtime | ✓ | | ✓ | | ✓ |
| Browser compiler | ✓ | ✓ | | | |
### Language Support
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
| Abstract references | ✓ | | | | | |
| Array comprehension | ✓ | ✓ | ✓ | | | |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Async functions | ✓ | ✓ | | ✓ | | |
| Async generator functions | ✓ | ✓ | | | | |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | ✓ | | | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Exponentiation operator | ✓ | ✓ | | | | |
| Flow types | ✓ | | | | | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | | ✓ | | |
| Generator comprehension | ✓ | ✓ | | | | |
| JSX | ✓ | | | | | |
| Let scoping | ✓ | ✓ | ✓ | | | |
| Modules | ✓ | ✓ | | | ✓ | |
| Object rest/spread | ✓ | | | | | ✓ |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| React | ✓ | | | | | |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | ✓ | | | |
| | 6to5 | Traceur | es6-transpiler | es6now | jstransform |
| ---------------------------- | ---- | ------- | -------------- | ------ | ----------- |
| Abstract references | ✓ | | | | |
| Array comprehension | ✓ | ✓ | ✓ | | |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ |
| Async functions | ✓ | ✓ | | | |
| Async generator functions | ✓ | ✓ | | | |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | ✓ | | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ |
| Exponentiation operator | ✓ | ✓ | | | |
| Flow types | ✓ | | | | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | | | |
| Generator comprehension | ✓ | ✓ | | | |
| JSX | ✓ | | | | |
| Let scoping | ✓ | ✓ | ✓ | | |
| Modules | ✓ | ✓ | | ✓ | |
| Object rest/spread | ✓ | | | | ✓ |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ |
| React | ✓ | | | | |
| Spread | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | ✓ | | |
### [Traceur](https://github.com/google/traceur-compiler)

View File

@@ -52,7 +52,7 @@ And it doesn't end here! To see all the ways you can use 6to5, check out the
- [Let scoping](features.md#let-scoping)
- [Modules](features.md#modules)
- [Numeric literals](features.md#numeric-literals)
- [Object Rest/Spread](features.md#object-rest-spread) ([experimental](experimental.md))
- [Object rest/spread](features.md#object-rest-spread) ([experimental](experimental.md))
- [Property method assignment](features.md#property-method-assignment)
- [Property name shorthand](features.md#property-name-shorthand)
- [React/JSX](react.md)

View File

@@ -18,11 +18,19 @@ to5.transform("code", { playground: true });
* [Memoization operator](#memoization-operator)
* [Method binding](#method-binding)
* [Method binding function shorthand](#method-binding-function-shorthand)
* [Object getter memoization](#object-getter-memoization)
* [This shorthand](#this-shorthand)
### Memoization assignment operator
The memoization assignment operator allows you to lazily set an object property.
It checks whether there's a property defined on the object and if there isn't then
the right hand value is set.
This means that `obj.x` in the following `var x = { x: undefined }; obj.x ?= 2;`
will still be `undefined` because it's already been defined on the object.
```javascript
var obj = {};
obj.x ?= 2;
@@ -42,7 +50,7 @@ var obj = {};
obj.x ?= 2;
```
equivalent to:
equivalent to
```javascript
var obj = {};
@@ -54,17 +62,25 @@ if (!Object.prototype.hasOwnProperty.call(obj, "x")) obj.x = 2;
```javascript
var fn = obj#method;
var fn = obj#method("foob");
["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"]
[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"]
```
equivalent to:
equivalent to
```javascript
var fn = obj.method.bind(obj);
var fn = obj.method.bind(obj, "foob");
```
### Method binding function shorthand
```javascript
["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"]
[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"]
```
equivalent to
```javascript
["foo", "bar"].map(function (val) { return val.toUpperCase(); });
[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); });
```
@@ -90,23 +106,27 @@ equivalent to
```javascript
var foo = {
get bar() {
if (this._barRan) return this._bar;
this._barRan = true;
return this._bar = complex();
return Object.defineProperty(this, "bar", {
value: complex(),
enumerable: true,
configurable: true,
writable: true
}).bar;
}
};
class Foo {
get bar() {
if (this._barRan) return this._bar;
this._barRan = true;
return this._bar = complex();
return Object.defineProperty(this, "bar", {
value: complex(),
enumerable: true,
configurable: true,
writable: true
}).bar;
}
}
```
**NOTE:** Memoised functions will return the result of the **first** execution, regardless of arguments.
### This shorthand
```javascript

View File

@@ -208,7 +208,7 @@ result.ast;
### Require hook
All subsequent files required by node with the extensions `.es6` and `.js` will
All subsequent files required by node with the extensions `.es6`, `.es` and `.js` will
be transformed by 6to5. The polyfill specified in [Polyfill](polyfill.md) is
also required; but this is automatically loaded when using:

View File

@@ -34,7 +34,7 @@ transform.load = function (url, callback, opts, hold) {
var runScripts = function () {
var scripts = [];
var types = ["text/ecmascript-6", "text/6to5"];
var types = ["text/ecmascript-6", "text/6to5", "module"];
var index = 0;
var exec = function () {
@@ -60,8 +60,9 @@ var runScripts = function () {
}
};
var _scripts = global.document.getElementsByTagName("script");
for (var i in _scripts) {
var _scripts = global.document .getElementsByTagName("script");
for (var i = 0; i < _scripts.length; ++i) {
var _script = _scripts[i];
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
}

View File

@@ -10,14 +10,17 @@ var t = require("./types");
var _ = require("lodash");
function File(opts) {
this.opts = File.normaliseOptions(opts);
this.transformers = this.getTransformers();
this.uids = {};
this.ast = {};
this.dynamicImports = [];
this.dynamicImportIds = {};
this.opts = File.normaliseOptions(opts);
this.transformers = this.getTransformers();
this.uids = {};
this.ast = {};
}
File.declarations = [
File.helpers = [
"inherits",
"defaults",
"prototype-properties",
"apply-constructor",
"tagged-template-literal",
@@ -27,12 +30,17 @@ File.declarations = [
"object-without-properties",
"has-own",
"slice",
"bind",
"define-property",
"async-to-generator"
"async-to-generator",
"interop-require-wildcard",
"typeof",
"exports-wildcard"
];
File.excludeDeclarationsFromRuntime = [
"async-to-generator"
File.excludeHelpersFromRuntime = [
"async-to-generator",
"typeof"
];
File.normaliseOptions = function (opts) {
@@ -96,25 +104,30 @@ File.normaliseOptions = function (opts) {
File.prototype.getTransformers = function () {
var file = this;
var transformers = [];
var secondPassTransformers = [];
_.each(transform.transformers, function (transformer) {
if (transformer.canRun(file)) {
transformers.push(transformer);
if (transformer.secondPass) {
secondPassTransformers.push(transformer);
}
if (transformer.manipulateOptions) {
transformer.manipulateOptions(file.opts, file);
}
}
});
return transformers;
return transformers.concat(secondPassTransformers);
};
File.prototype.toArray = function (node, i) {
if (t.isArrayExpression(node)) {
return node;
} else if (t.isIdentifier(node) && node.name === "arguments") {
return t.callExpression(t.memberExpression(this.addDeclaration("slice"), t.identifier("call")), [node]);
return t.callExpression(t.memberExpression(this.addHelper("slice"), t.identifier("call")), [node]);
} else {
var declarationName = "to-array";
var args = [node];
@@ -122,7 +135,7 @@ File.prototype.toArray = function (node, i) {
args.push(t.literal(i));
declarationName = "sliced-to-array";
}
return t.callExpression(this.addDeclaration(declarationName), args);
return t.callExpression(this.addHelper(declarationName), args);
}
};
@@ -153,14 +166,24 @@ File.prototype.parseShebang = function (code) {
return code;
};
File.prototype.addImport = function (id, source) {
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
this.ast.program.body.unshift(declar);
File.prototype.addImport = function (source, name) {
name = name || source;
var id = this.dynamicImportIds[name];
if (!id) {
id = this.dynamicImportIds[name] = this.generateUidIdentifier(name);
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
declar._blockHoist = 3;
this.dynamicImports.push(declar);
}
return id;
};
File.prototype.addDeclaration = function (name) {
if (!_.contains(File.declarations, name)) {
File.prototype.addHelper = function (name) {
if (!_.contains(File.helpers, name)) {
throw new ReferenceError("unknown declaration " + name);
}
@@ -171,7 +194,7 @@ File.prototype.addDeclaration = function (name) {
var ref;
var runtimeNamespace = this.opts.runtime;
if (runtimeNamespace && !_.contains(File.excludeDeclarationsFromRuntime, name)) {
if (runtimeNamespace && !_.contains(File.excludeHelpersFromRuntime, name)) {
name = t.identifier(t.toIdentifier(name));
return t.memberExpression(t.identifier(runtimeNamespace), name);
} else {
@@ -265,7 +288,7 @@ File.prototype.generate = function () {
};
File.prototype.generateUid = function (name, scope) {
name = t.toIdentifier(name);
name = t.toIdentifier(name).replace(/^_+/, "");
scope = scope || this.scope;

View File

@@ -148,11 +148,11 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
};
if (this[node.type]) {
var needsCommentParens = t.isExpression(node) && node.leadingComments && node.leadingComments.length;
var needsParens = needsCommentParens || n.needsParens(node, parent);
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
var needsParens = needsNoLineTermParens || n.needsParens(node, parent);
if (needsParens) this.push("(");
if (needsCommentParens) this.indent();
if (needsNoLineTermParens) this.indent();
this.printLeadingComments(node, parent);
@@ -163,7 +163,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
this[node.type](node, this.buildPrint(node), parent);
if (needsCommentParens) {
if (needsNoLineTermParens) {
this.newline();
this.dedent();
}
@@ -274,14 +274,21 @@ CodeGenerator.prototype._printComments = function (comments) {
var self = this;
_.each(comments, function (comment) {
var skip = false;
// find the original comment in the ast and set it as displayed
_.each(self.ast.comments, function (origComment) {
if (origComment.start === comment.start) {
// comment has already been output
if (origComment._displayed) skip = true;
origComment._displayed = true;
return false;
}
});
if (skip) return;
// whitespace before
self.newline(self.whitespace.getNewlinesBefore(comment));

View File

@@ -1,5 +1,6 @@
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
exports.UnaryExpression = function (node, print) {
var hasSpace = /[a-z]$/.test(node.operator);
@@ -86,6 +87,7 @@ exports.ExpressionStatement = function (node, print) {
exports.BinaryExpression =
exports.LogicalExpression =
exports.AssignmentPattern =
exports.AssignmentExpression = function (node, print) {
print(node.left);
this.push(" " + node.operator + " ");
@@ -98,7 +100,16 @@ exports.MemberExpression = function (node, print) {
var obj = node.object;
print(obj);
if (node.computed) {
if (!node.computed && t.isMemberExpression(node.property)) {
throw new TypeError("Got a MemberExpression for MemberExpression property");
}
var computed = node.computed;
if (t.isLiteral(node.property) && _.isNumber(node.property.value)) {
computed = true;
}
if (computed) {
this.push("[");
print(node.property);
this.push("]");

View File

@@ -61,14 +61,40 @@ Node.prototype.needsParens = function () {
if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {
return t.isCallExpression(node) || _.some(node, function (val) {
if (t.isCallExpression(node)) return true;
var hasCall = _.some(node, function (val) {
return t.isCallExpression(val);
});
if (hasCall) return true;
}
return find(parens, node, parent);
};
Node.prototype.needsParensNoLineTerminator = function () {
var parent = this.parent;
var node = this.node;
if (!parent) return false;
// no comments
if (!node.leadingComments || !node.leadingComments.length) {
return false;
}
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
return true;
}
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) ||
t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
return true;
}
return false;
};
_.each(Node.prototype, function (fn, key) {
Node[key] = function (node, parent) {
var n = new Node(node, parent);

View File

@@ -13,15 +13,30 @@ _.each([
["<", ">", "<=", ">=", "in", "instanceof"],
[">>", "<<", ">>>"],
["+", "-"],
["*", "/", "%"]
["*", "/", "%"],
["**"]
], function (tier, i) {
_.each(tier, function (op) {
PRECEDENCE[op] = i;
});
});
exports.ObjectExpression = function (node, parent) {
if (t.isExpressionStatement(parent)) {
// ({ foo: "bar" });
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
// ({ foo: "bar" }).foo
return true;
}
return false;
};
exports.Binary = function (node, parent) {
if (t.isCallExpression(parent) && parent.callee === node) {
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
return true;
}

View File

@@ -12,6 +12,12 @@ var types = require("ast-types");
var def = types.Type.def;
var or = types.Type.or;
def("AssignmentPattern")
.bases("Pattern")
.build("left", "right")
.field("left", def("Pattern"))
.field("right", def("Expression"));
// Acorn - Same as ImportNamespaceSpecifier but `id` is `name`
def("ImportBatchSpecifier")
.bases("Specifier")

View File

@@ -0,0 +1,4 @@
// Required to safely use 6to5/register within a browserify codebase.
module.exports = function () {};
require("./polyfill");

View File

@@ -123,7 +123,7 @@ var hookExtensions = function (_exts) {
});
};
hookExtensions([".es6", ".js"]);
hookExtensions([".es6", ".es", ".js"]);
module.exports = function (opts) {
// normalise options

View File

@@ -18,8 +18,8 @@ module.exports = function (namespace) {
)
]));
_.each(File.declarations, function (name) {
if (_.contains(File.excludeDeclarationsFromRuntime, name)) {
_.each(File.helpers, function (name) {
if (_.contains(File.excludeHelpersFromRuntime, name)) {
return false;
}

View File

@@ -51,7 +51,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
traverse(this.file.ast, {
enter: function (node, parent, scope) {
if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) {
this.stop();
this.skip();
// expand to long file assignment expression
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
@@ -79,7 +79,7 @@ DefaultFormatter.prototype.remapAssignments = function () {
}
if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) {
this.stop();
this.skip();
return self.remapExportAssignment(node);
}
}
@@ -141,10 +141,17 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
// export * from "foo";
nodes.push(this._exportsWildcard(getRef(), node));
} else {
var ref;
if (t.isSpecifierDefault(specifier.id) || this.noInteropRequire) {
ref = t.memberExpression(getRef(), specifier.id);
} else {
ref = t.callExpression(this.file.addHelper("interop-require"), [getRef()]);
}
// export { foo } from "test";
nodes.push(this._exportsAssign(
t.getSpecifierName(specifier),
t.memberExpression(getRef(), specifier.id),
ref,
node
));
}
@@ -155,9 +162,9 @@ DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node,
};
DefaultFormatter.prototype._exportsWildcard = function (objectIdentifier) {
return util.template("exports-wildcard", {
OBJECT: objectIdentifier
}, true);
return t.expressionStatement(t.callExpression(this.file.addHelper("exports-wildcard"), [
t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier])
]));
};
DefaultFormatter.prototype._exportsAssign = function (id, init) {

View File

@@ -85,7 +85,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
// import * as bar from "foo";
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
// import foo from "foo";
ref = t.callExpression(this.file.addDeclaration("interop-require"), [ref]);
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
// import {foo} from "foo";
ref = t.memberExpression(ref, specifier.id, false);

View File

@@ -26,24 +26,30 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
if (t.isSpecifierDefault(specifier)) {
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(variableName,
t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", {
t.callExpression(this.file.addHelper("interop-require"), [util.template("require", {
MODULE_NAME: node.source
})])
)
]));
} else {
// import foo from "foo";
var templateName = "require-assign";
// import * as bar from "foo";
if (specifier.type !== "ImportBatchSpecifier") templateName += "-key";
nodes.push(util.template(templateName, {
VARIABLE_NAME: variableName,
MODULE_NAME: node.source,
KEY: specifier.id
}));
if (specifier.type === "ImportBatchSpecifier") {
// import * as bar from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(
variableName,
t.callExpression(this.file.addHelper("interop-require-wildcard"), [
t.callExpression(t.identifier("require"), [node.source])
])
)
]));
} else {
// import foo from "foo";
nodes.push(util.template("require-assign-key", {
VARIABLE_NAME: variableName,
MODULE_NAME: node.source,
KEY: specifier.id
}));
}
}
};
@@ -65,7 +71,7 @@ CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
// exports = module.exports = VALUE;
if (this.hasNonDefaultExports) templateName = "exports-default-module-override";
if (t.isFunction(declar) || !this.hasNonDefaultExports) {
if (t.isFunctionDeclaration(declar) || !this.hasNonDefaultExports) {
assign = util.template(templateName, {
VALUE: this._pushStatement(declar, nodes)
}, true);

View File

@@ -1,6 +1,7 @@
module.exports = SystemFormatter;
var AMDFormatter = require("./amd");
var useStrict = require("../transformers/use-strict");
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
@@ -31,7 +32,7 @@ SystemFormatter.prototype._exportsWildcard = function (objectIdentifier, node) {
var right = objectIdentifier;
var block = t.blockStatement([
this.buildExportCall(leftIdentifier, valIdentifier)
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
]);
return this._addImportSource(t.forInStatement(left, right, block), node);
@@ -114,7 +115,7 @@ SystemFormatter.prototype.transform = function (ast) {
enter: function (node, parent, scope) {
if (t.isFunction(node)) {
// nothing inside is accessible
return this.stop();
return this.skip();
}
if (t.isVariableDeclaration(node)) {
@@ -159,7 +160,7 @@ SystemFormatter.prototype.transform = function (ast) {
// hoist up function declarations for circular references
traverse(block, {
enter: function (node) {
if (t.isFunction(node)) this.stop();
if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || node._blockHoist) {
handlerBody.push(node);
@@ -170,5 +171,9 @@ SystemFormatter.prototype.transform = function (ast) {
handlerBody.push(returnStatement);
if (useStrict._has(block)) {
handlerBody.unshift(block.body.shift());
}
program.body = [runner];
};

View File

@@ -0,0 +1 @@
Function.prototype.bind

View File

@@ -1,3 +1,3 @@
if (SUPER_NAME) {
if (SUPER_NAME !== null) {
SUPER_NAME.apply(this, arguments);
}

View File

@@ -0,0 +1 @@
var VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];

View File

@@ -0,0 +1,8 @@
(function (obj, defaults) {
for (var key in defaults) {
if (obj[key] === undefined) {
obj[key] = defaults[key];
}
}
return obj;
})

View File

@@ -1,5 +1,7 @@
(function (obj) {
for (var i in obj) {
exports[i] = obj[i];
if (exports[i] !== undefined) {
exports[i] = obj[i];
}
}
})(OBJECT);
})

View File

@@ -1 +0,0 @@
if (VARIABLE === undefined) VARIABLE = DEFAULT;

View File

@@ -1,4 +1,7 @@
(function (child, parent) {
if (typeof parent !== "function" && parent !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof parent);
}
child.prototype = Object.create(parent && parent.prototype, {
constructor: {
value: child,

View File

@@ -0,0 +1,3 @@
(function (obj) {
return obj && obj.constructor === Object ? obj : { default: obj };
})

View File

@@ -0,0 +1,5 @@
(function (KEY) {
CONTENT;
return KEY;
})(OBJECT);

View File

@@ -0,0 +1,11 @@
(function (FUNCTION_KEY) {
var WRAPPER_KEY = function FUNCTION_ID() {
return FUNCTION_KEY.apply(this, arguments);
};
WRAPPER_KEY.toString = function () {
return FUNCTION_KEY.toString();
};
return WRAPPER_KEY;
})(FUNCTION)

View File

@@ -1 +0,0 @@
var VARIABLE_NAME = require(MODULE_NAME);

View File

@@ -0,0 +1,3 @@
for (var KEY = START; KEY < ARGUMENTS.length; KEY++) {
ARRAY[$__0] = ARGUMENTS[KEY];
}

View File

@@ -0,0 +1,3 @@
(function (obj) {
return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
});

View File

@@ -42,7 +42,6 @@ _.each({
// spec
specBlockHoistFunctions: require("./transformers/spec-block-hoist-functions"),
specNoForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"),
specNoDuplicateProperties: require("./transformers/spec-no-duplicate-properties"),
// playground
methodBinding: require("./transformers/playground-method-binding"),
@@ -66,7 +65,7 @@ _.each({
exponentiationOperator: require("./transformers/es7-exponentiation-operator"),
spread: require("./transformers/es6-spread"),
templateLiterals: require("./transformers/es6-template-literals"),
propertyMethodAssignment: require("./transformers/es5-property-method-assignment"),
propertyMethodAssignment: require("./transformers/es6-property-method-assignment"),
destructuring: require("./transformers/es6-destructuring"),
defaultParameters: require("./transformers/es6-default-parameters"),
forOf: require("./transformers/es6-for-of"),
@@ -81,15 +80,18 @@ _.each({
generators: require("./transformers/es6-generators"),
restParameters: require("./transformers/es6-rest-parameters"),
protoToAssign: require("./transformers/optional-proto-to-assign"),
_declarations: require("./transformers/_declarations"),
coreAliasing: require("./transformers/optional-core-aliasing"),
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
// wrap up
useStrict: require("./transformers/use-strict"),
_aliasFunctions: require("./transformers/_alias-functions"),
_moduleFormatter: require("./transformers/_module-formatter"),
useStrict: require("./transformers/use-strict"),
typeofSymbol: require("./transformers/optional-typeof-symbol"),
coreAliasing: require("./transformers/optional-core-aliasing"),
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
// spec
specPropertyLiterals: require("./transformers/spec-property-literals"),

View File

@@ -7,20 +7,26 @@ var _ = require("lodash");
function Transformer(key, transformer, opts) {
this.manipulateOptions = transformer.manipulateOptions;
this.experimental = !!transformer.experimental;
this.transformer = Transformer.normalise(transformer);
this.secondPass = !!transformer.secondPass;
this.transformer = this.normalise(transformer);
this.optional = !!transformer.optional;
this.opts = opts || {};
this.key = key;
}
Transformer.normalise = function (transformer) {
Transformer.prototype.normalise = function (transformer) {
var self = this;
if (_.isFunction(transformer)) {
transformer = { ast: transformer };
}
_.each(transformer, function (fns, type) {
// hidden property
if (type[0] === "_") return;
if (type[0] === "_") {
self[type] = fns;
return;
}
if (_.isFunction(fns)) fns = { enter: fns };
@@ -41,16 +47,14 @@ Transformer.normalise = function (transformer) {
Transformer.prototype.astRun = function (file, key) {
var transformer = this.transformer;
var ast = file.ast;
if (transformer.ast && transformer.ast[key]) {
transformer.ast[key](ast, file);
transformer.ast[key](file.ast, file);
}
};
Transformer.prototype.transform = function (file) {
var transformer = this.transformer;
var ast = file.ast;
var build = function (exit) {
return function (node, parent, scope) {
@@ -67,7 +71,7 @@ Transformer.prototype.transform = function (file) {
this.astRun(file, "before");
traverse(ast, {
traverse(file.ast, {
enter: build(),
exit: build(true)
});

View File

@@ -20,7 +20,7 @@ var go = function (getBody, node, file, scope) {
if (!node._aliasFunction) {
if (t.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return this.stop();
return this.skip();
} else {
return;
}
@@ -30,10 +30,10 @@ var go = function (getBody, node, file, scope) {
traverse(node, {
enter: function (node, parent) {
if (t.isFunction(node) && !node._aliasFunction) {
return this.stop();
return this.skip();
}
if (node._ignoreAliasFunctions) return this.stop();
if (node._ignoreAliasFunctions) return this.skip();
var getId;
@@ -49,7 +49,7 @@ var go = function (getBody, node, file, scope) {
}
});
return this.stop();
return this.skip();
}
});
@@ -67,7 +67,7 @@ var go = function (getBody, node, file, scope) {
}
if (thisId) {
pushDeclaration(thisId, t.identifier("this"));
pushDeclaration(thisId, t.thisExpression());
}
};

View File

@@ -1,4 +1,5 @@
var _ = require("lodash");
var useStrict = require("./use-strict");
var _ = require("lodash");
// Priority:
//
@@ -17,13 +18,15 @@ exports.Program = {
}
if (!hasChange) return;
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
var priority = bodyNode._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;
return priority;
});
useStrict._wrap(node, function () {
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
var priority = bodyNode._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;
return priority;
});
node.body = _.flatten(_.values(nodePriorities).reverse());
node.body = _.flatten(_.values(nodePriorities).reverse());
});
}
};

View File

@@ -1,25 +1,32 @@
var t = require("../../types");
var useStrict = require("./use-strict");
var t = require("../../types");
exports.secondPass = true;
exports.BlockStatement =
exports.Program = function (node) {
var kinds = {};
var kind;
for (var i in node._declarations) {
var declar = node._declarations[i];
useStrict._wrap(node, function () {
for (var i in node._declarations) {
var declar = node._declarations[i];
kind = declar.kind || "var";
var declarNode = t.variableDeclarator(declar.id, declar.init);
kind = declar.kind || "var";
var declarNode = t.variableDeclarator(declar.id, declar.init);
if (!declar.init) {
kinds[kind] = kinds[kind] || [];
kinds[kind].push(declarNode);
} else {
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
if (!declar.init) {
kinds[kind] = kinds[kind] || [];
kinds[kind].push(declarNode);
} else {
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
}
}
}
for (kind in kinds) {
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
}
for (kind in kinds) {
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
}
});
node._declarations = null;
};

View File

@@ -1,40 +0,0 @@
var util = require("../../util");
exports.Property = function (node) {
if (node.method) node.method = false;
};
exports.ObjectExpression = function (node, parent, file) {
var mutatorMap = {};
var hasAny = false;
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
hasAny = true;
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
return false;
} else {
return true;
}
});
if (!hasAny) return;
if (node.properties.length) {
var objId = util.getUid(parent, file);
return util.template("object-define-properties-closure", {
KEY: objId,
OBJECT: node,
CONTENT: util.template("object-define-properties", {
OBJECT: objId,
PROPS: util.buildDefineProperties(mutatorMap)
})
});
} else {
return util.template("object-define-properties", {
OBJECT: node,
PROPS: util.buildDefineProperties(mutatorMap)
});
}
};

View File

@@ -87,18 +87,16 @@ Class.prototype.run = function () {
if (superName) {
this.closure = true;
// so we're only evaluating it once
var superRefName = "super";
if (className) superRefName = className.name + "Super";
var superRef = file.generateUidIdentifier(superRefName, this.scope);
// so we're only evaluating it once
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(superRef, superName)
]));
superName = superRef;
this.superName = superName;
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("inherits"), [className, superName])));
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
}
this.buildBody();
@@ -177,7 +175,7 @@ Class.prototype.buildBody = function () {
if (instanceProps) args.push(instanceProps);
body.push(t.expressionStatement(
t.callExpression(this.file.addDeclaration("prototype-properties"), args)
t.callExpression(this.file.addHelper("prototype-properties"), args)
));
}
};
@@ -278,7 +276,7 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
callee.property = t.memberExpression(callee.property, t.identifier("call"));
t.appendToMemberExpression(callee, t.identifier("call"));
node.arguments.unshift(t.thisExpression());
}
}

View File

@@ -1,7 +1,6 @@
var util = require("../../util");
var t = require("../../types");
var t = require("../../types");
exports.ObjectExpression = function (node, parent, file) {
exports.ObjectExpression = function (node, parent, file, scope) {
var hasComputed = false;
var prop;
var key;
@@ -14,7 +13,7 @@ exports.ObjectExpression = function (node, parent, file) {
if (!hasComputed) return;
var objId = util.getUid(parent, file);
var objId = scope.generateUidBasedOnNode(parent, file);
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body));
@@ -45,7 +44,7 @@ exports.ObjectExpression = function (node, parent, file) {
broken = true;
}
if (!broken || t.isLiteral(prop.key, { value: "__proto__" })) {
if (!broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) {
initProps.push(prop);
props[i] = null;
}
@@ -62,13 +61,14 @@ exports.ObjectExpression = function (node, parent, file) {
var bodyNode;
if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) {
// { [Symbol.iterator]: "foo" }
bodyNode = t.assignmentExpression(
"=",
t.memberExpression(objId, key, true),
prop.value
);
} else {
bodyNode = t.callExpression(file.addDeclaration("define-property"), [objId, key, prop.value]);
bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
}
body.push(t.expressionStatement(bodyNode));
@@ -80,7 +80,7 @@ exports.ObjectExpression = function (node, parent, file) {
var first = body[0].expression;
if (t.isCallExpression(first)) {
first.arguments[0] = t.objectExpression([]);
first.arguments[0] = t.objectExpression(initProps);
return first;
}
}

View File

@@ -49,16 +49,29 @@ exports.Function = function (node, parent, file, scope) {
var body = [];
var argsIdentifier = t.identifier("arguments");
argsIdentifier._ignoreAliasFunctions = true;
var lastNonDefaultParam = 0;
for (i in node.defaults) {
def = node.defaults[i];
if (!def) continue;
if (!def) {
lastNonDefaultParam = +i + 1;
continue;
}
body.push(util.template("if-undefined-set-to", {
VARIABLE: node.params[i],
DEFAULT: def
body.push(util.template("default-parameter", {
VARIABLE_NAME: node.params[i],
DEFAULT_VALUE: def,
ARGUMENT_KEY: t.literal(+i),
ARGUMENTS: argsIdentifier
}, true));
}
// we need to cut off all trailing default parameters
node.params = node.params.slice(0, lastNonDefaultParam);
if (iife) {
var container = t.functionExpression(null, [], node.body, node.generator);
container._aliasFunction = true;

View File

@@ -20,11 +20,31 @@ var push = function (opts, nodes, elem, parentId) {
pushObjectPattern(opts, nodes, elem, parentId);
} else if (t.isArrayPattern(elem)) {
pushArrayPattern(opts, nodes, elem, parentId);
} else if (t.isAssignmentPattern(elem)) {
pushAssignmentPattern(opts, nodes, elem, parentId);
} else {
nodes.push(buildVariableAssign(opts, elem, parentId));
}
};
var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
var tempParentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(tempParentId, parentId)
]));
nodes.push(buildVariableAssign(
opts,
pattern.left,
t.conditionalExpression(
t.binaryExpression("===", tempParentId, t.identifier("undefined")),
pattern.right,
tempParentId
)
));
};
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
for (var i in pattern.properties) {
var prop = pattern.properties[i];
@@ -45,9 +65,11 @@ var pushObjectPattern = function (opts, nodes, pattern, parentId) {
}
keys = t.arrayExpression(keys);
var value = t.callExpression(opts.file.addDeclaration("object-without-properties"), [parentId, keys]);
var value = t.callExpression(opts.file.addHelper("object-without-properties"), [parentId, keys]);
nodes.push(buildVariableAssign(opts, prop.argument, value));
} else {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
@@ -75,7 +97,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
var toArray = opts.file.toArray(parentId, !hasSpreadElement && pattern.elements.length);
var _parentId = opts.file.generateUidIdentifier("ref", opts.scope);
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(_parentId, toArray)
]));
@@ -113,7 +135,7 @@ var pushPattern = function (opts) {
var scope = opts.scope;
if (!t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = file.generateUidIdentifier("ref", scope);
var key = scope.generateUidBasedOnNode(parentId, file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, parentId)
@@ -183,6 +205,24 @@ exports.Function = function (node, parent, file, scope) {
block.body = nodes.concat(block.body);
};
exports.CatchClause = function (node, parent, file, scope) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
var ref = file.generateUidIdentifier("ref", scope);
node.param = ref;
var nodes = [];
push({
kind: "var",
file: file,
scope: scope
}, nodes, pattern, ref);
node.body.body = nodes.concat(node.body.body);
};
exports.ExpressionStatement = function (node, parent, file, scope) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;

View File

@@ -280,7 +280,7 @@ LetScoping.prototype.checkLoop = function () {
var replace;
if (t.isFunction(node) || t.isLoop(node)) {
return this.stop();
return this.skip();
}
if (node && !node.label) {
@@ -329,7 +329,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
} else if (isVar(node, parent)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return this.stop();
return this.skip();
}
}
});
@@ -376,7 +376,7 @@ LetScoping.prototype.getLetReferences = function () {
// this scope has a variable with the same name so it couldn't belong
// to our let scope
if (scope.hasOwn(node.name)) return;
if (scope.hasOwn(node.name, true)) return;
closurify = true;
@@ -388,9 +388,7 @@ LetScoping.prototype.getLetReferences = function () {
}
});
return this.stop();
} else if (t.isLoop(node)) {
return this.stop();
return this.skip();
}
}
});

View File

@@ -1,5 +1,11 @@
var t = require("../../types");
exports.ast = {
before: function (ast, file) {
ast.program.body = file.dynamicImports.concat(ast.program.body);
}
};
exports.ImportDeclaration = function (node, parent, file) {
var nodes = [];
@@ -11,6 +17,12 @@ exports.ImportDeclaration = function (node, parent, file) {
file.moduleFormatter.importDeclaration(node, nodes, parent);
}
if (nodes.length === 1) {
// inherit `_blockHoist`
// this for `_blockHoist` in File.prototype.addImport
nodes[0]._blockHoist = node._blockHoist;
}
return nodes;
};

View File

@@ -0,0 +1,82 @@
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
exports.Property = function (node, parent, file, scope) {
if (!node.method) return;
node.method = false;
var key = t.toComputedKey(node, node.key);
if (!t.isLiteral(key)) return; // we can't set a function id with this
var id = t.toIdentifier(key.value);
key = t.identifier(id);
var selfReference = false;
var outerDeclar = scope.get(id, true);
traverse(node, {
enter: function (node, parent, scope) {
// check if this node is an identifier that matches the same as our function id
if (!t.isIdentifier(node, { name: id })) return;
// check if this node is the one referenced
if (!t.isReferenced(node, parent)) return;
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.get(id, true);
if (localDeclar !== outerDeclar) return;
selfReference = true;
this.stop();
}
}, scope);
if (selfReference) {
node.value = util.template("property-method-assignment-wrapper", {
FUNCTION: node.value,
FUNCTION_ID: key,
FUNCTION_KEY: file.generateUidIdentifier(id, scope),
WRAPPER_KEY: file.generateUidIdentifier(id + "Wrapper", scope)
});
} else {
node.value.id = key;
}
};
exports.ObjectExpression = function (node, parent, file, scope) {
var mutatorMap = {};
var hasAny = false;
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
hasAny = true;
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
return false;
} else {
return true;
}
});
if (!hasAny) return;
if (node.properties.length) {
var objId = scope.generateUidBasedOnNode(parent, file);
return util.template("object-define-properties-closure", {
KEY: objId,
OBJECT: node,
CONTENT: util.template("object-define-properties", {
OBJECT: objId,
PROPS: util.buildDefineProperties(mutatorMap)
})
});
} else {
return util.template("object-define-properties", {
OBJECT: node,
PROPS: util.buildDefineProperties(mutatorMap)
});
}
};

View File

@@ -1,4 +1,5 @@
var t = require("../../types");
var util = require("../../util");
var t = require("../../types");
exports.Function = function (node, parent, file) {
if (!node.rest) return;
@@ -8,15 +9,19 @@ exports.Function = function (node, parent, file) {
t.ensureBlock(node);
var call = file.toArray(t.identifier("arguments"));
var argsId = t.identifier("arguments");
argsId._ignoreAliasFunctions = true;
if (node.params.length) {
call.arguments.push(t.literal(node.params.length));
}
node.body.body.unshift(
t.variableDeclaration("var", [
t.variableDeclarator(rest, t.arrayExpression([]))
]),
call._ignoreAliasFunctions = true;
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(rest, call)
]));
util.template("rest", {
ARGUMENTS: argsId,
START: t.literal(node.params.length),
ARRAY: rest,
KEY: file.generateUidIdentifier("key")
})
);
};

View File

@@ -1,4 +1,5 @@
var t = require("../../types");
var _ = require("lodash");
var getSpreadLiteral = function (spread, file) {
return file.toArray(spread.argument);
@@ -58,7 +59,7 @@ exports.CallExpression = function (node, parent, file, scope) {
var args = node.arguments;
if (!hasSpread(args)) return;
var contextLiteral = t.literal(null);
var contextLiteral = t.identifier("undefined");
node.arguments = [];
@@ -77,23 +78,16 @@ exports.CallExpression = function (node, parent, file, scope) {
}
var callee = node.callee;
var temp;
if (t.isMemberExpression(callee)) {
contextLiteral = callee.object;
if (t.isDynamic(contextLiteral)) {
temp = contextLiteral = scope.generateTemp(file);
var temp = scope.generateTempBasedOnNode(callee.object, file);
if (temp) {
callee.object = t.assignmentExpression("=", temp, callee.object);
}
if (callee.computed) {
callee.object = t.memberExpression(callee.object, callee.property, true);
callee.property = t.identifier("apply");
callee.computed = false;
contextLiteral = temp;
} else {
callee.property = t.memberExpression(callee.property, t.identifier("apply"));
contextLiteral = callee.object;
}
t.appendToMemberExpression(callee, t.identifier("apply"));
} else {
node.callee = t.memberExpression(node.callee, t.identifier("apply"));
}
@@ -105,7 +99,14 @@ exports.NewExpression = function (node, parent, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nativeType = t.isIdentifier(node.callee) && _.contains(t.NATIVE_TYPE_NAMES, node.callee.name);
var nodes = build(args, file);
if (nativeType) {
nodes.unshift(t.arrayExpression([t.literal(null)]));
}
var first = nodes.shift();
if (nodes.length) {
@@ -114,5 +115,15 @@ exports.NewExpression = function (node, parent, file) {
args = first;
}
return t.callExpression(file.addDeclaration("apply-constructor"), [node.callee, args]);
if (nativeType) {
return t.newExpression(
t.callExpression(
t.memberExpression(file.addHelper("bind"), t.identifier("apply")),
[node.callee, args]
),
[]
);
} else {
return t.callExpression(file.addHelper("apply-constructor"), [node.callee, args]);
}
};

View File

@@ -17,7 +17,7 @@ exports.TaggedTemplateExpression = function (node, parent, file) {
raw.push(t.literal(elem.value.raw));
}
args.push(t.callExpression(file.addDeclaration("tagged-template-literal"), [
args.push(t.callExpression(file.addHelper("tagged-template-literal"), [
t.arrayExpression(strings),
t.arrayExpression(raw)
]));

View File

@@ -30,10 +30,8 @@ exports.AssignmentExpression = function (node, parent, file, scope) {
// we need to return `node.right`
if (!t.isExpressionStatement(parent)) {
// `node.right` isn't a simple identifier so we need to reference it
if (t.isDynamic(value)) {
temp = value = scope.generateTemp(file);
}
temp = scope.generateTempBasedOnNode(node.right, file);
if (temp) value = temp;
}
if (node.operator !== "=") {
@@ -80,11 +78,7 @@ exports.CallExpression = function (node, parent, file, scope) {
var callee = node.callee;
if (!t.isVirtualPropertyExpression(callee)) return;
var temp;
if (t.isDynamic(callee.object)) {
// we need to save `callee.object` so we can call it again
temp = scope.generateTemp(file);
}
var temp = scope.generateTempBasedOnNode(callee.object, file);
var call = util.template("abstract-expression-call", {
PROPERTY: callee.property,

View File

@@ -4,8 +4,8 @@ var t = require("../../types");
exports.experimental = true;
var build = function (node, file) {
var uid = file.generateUidIdentifier("arr");
var build = function (node, parent, file, scope) {
var uid = scope.generateUidBasedOnNode(parent, file);
var container = util.template("array-comprehension-container", {
KEY: uid
@@ -49,14 +49,14 @@ exports._build = function (node, buildBody) {
}
return t.forOfStatement(
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
t.variableDeclaration("let", [t.variableDeclarator(self.left)]),
self.right,
t.blockStatement([child])
);
};
exports.ComprehensionExpression = function (node, parent, file) {
exports.ComprehensionExpression = function (node, parent, file, scope) {
if (node.generator) return;
return build(node, file);
return build(node, parent, file, scope);
};

View File

@@ -1,5 +1,4 @@
var bluebirdCoroutines = require("./optional-bluebird-coroutines");
var t = require("../../types");
exports.optional = true;
@@ -8,7 +7,5 @@ exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
exports.Function = function (node, parent, file) {
if (!node.async || node.generator) return;
bluebirdCoroutines._Function(node);
return t.callExpression(file.addDeclaration("async-to-generator"), [node]);
return bluebirdCoroutines._Function(node, file.addHelper("async-to-generator"));
};

View File

@@ -8,27 +8,36 @@ exports.manipulateOptions = function (opts) {
exports.optional = true;
exports._Function = function (node) {
exports._Function = function (node, callId) {
node.async = false;
node.generator = true;
traverse(node, {
enter: function (node) {
if (t.isFunction(node)) this.stop();
if (t.isFunction(node)) this.skip();
if (t.isAwaitExpression(node)) {
node.type = "YieldExpression";
}
}
});
var call = t.callExpression(callId, [node]);
if (t.isFunctionDeclaration(node)) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(node.id, call)
]);
declar._blockHoist = true;
return declar;
} else {
return call;
}
};
exports.Function = function (node, parent, file) {
if (!node.async || node.generator) return;
exports._Function(node);
var id = t.identifier("Bluebird");
file.addImport(id, "bluebird");
return t.callExpression(t.memberExpression(id, t.identifier("coroutine")), [node]);
var id = file.addImport("bluebird");
return exports._Function(node, t.memberExpression(id, t.identifier("coroutine")));
};

View File

@@ -4,12 +4,15 @@ var core = require("core-js/library");
var t = require("../../types");
var _ = require("lodash");
var coreHas = function (node) {
return node.name !== "_" && _.has(core, node.name);
};
exports.optional = true;
exports.ast = {
enter: function (ast, file) {
file._coreId = file.generateUidIdentifier("core");
file.addImport(file._coreId, "core-js/library");
file._coreId = file.addImport("core-js/library", "core");
},
exit: function (ast, file) {
@@ -24,11 +27,13 @@ exports.ast = {
if (!t.isReferenced(obj, node)) return;
var coreHasObject = obj.name !== "_" && _.has(core, obj.name);
if (coreHasObject && _.has(core[obj.name], prop.name)) {
this.stop();
return t.memberExpression(file._coreId, node);
if (!node.computed && coreHas(obj) && _.has(core[obj.name], prop.name)) {
this.skip();
return t.prependToMemberExpression(node, file._coreId);
}
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && coreHas(node)) {
// new Promise -> new _core.Promise
return t.memberExpression(file._coreId, node);
} else if (t.isCallExpression(node)) {
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)

View File

@@ -0,0 +1,63 @@
var t = require("../../types");
var _ = require("lodash");
var OBJECT_ASSIGN_MEMBER = t.memberExpression(t.identifier("Object"), t.identifier("assign"));
var isProtoKey = function (node) {
return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" });
};
var isProtoAssignmentExpression = function (node) {
var left = node.left;
return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" });
};
var buildDefaultsCallExpression = function (expr, ref, file) {
return t.expressionStatement(t.callExpression(file.addHelper("defaults"), [ref, expr.right]));
};
exports.optional = true;
exports.secondPass = true;
exports.AssignmentExpression = function (node, parent, file, scope) {
if (t.isExpressionStatement(parent)) return;
if (!isProtoAssignmentExpression(node)) return;
var nodes = [];
var left = node.left.object;
var temp = scope.generateTempBasedOnNode(node.left.object, file);
nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left)));
nodes.push(buildDefaultsCallExpression(node, temp, file));
if (temp) nodes.push(temp);
return t.toSequenceExpression(nodes);
};
exports.ExpressionStatement = function (node, parent, file) {
var expr = node.expression;
if (!t.isAssignmentExpression(expr, { operator: "=" })) return;
if (isProtoAssignmentExpression(expr)) {
return buildDefaultsCallExpression(expr, expr.left.object, file);
}
};
exports.ObjectExpression = function (node) {
var proto;
for (var i in node.properties) {
var prop = node.properties[i];
if (isProtoKey(prop)) {
proto = prop.value;
_.pull(node.properties, prop);
}
}
if (proto) {
var args = [t.objectExpression([]), proto];
if (node.properties.length) args.push(node);
return t.callExpression(OBJECT_ASSIGN_MEMBER, args);
}
};

View File

@@ -0,0 +1,9 @@
var t = require("../../types");
exports.optional = true;
exports.UnaryExpression = function (node, parent, file) {
if (node.operator === "typeof") {
return t.callExpression(file.addHelper("typeof"), [node.argument]);
}
};

View File

@@ -10,7 +10,7 @@ var getPropRef = function (nodes, prop, file, scope) {
if (t.isIdentifier(prop)) {
return t.literal(prop.name);
} else {
var temp = file.generateUidIdentifier("propKey", scope);
var temp = scope.generateUidBasedOnNode(prop, file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, prop)
]));
@@ -19,22 +19,18 @@ var getPropRef = function (nodes, prop, file, scope) {
};
var getObjRef = function (nodes, obj, file, scope) {
if (t.isDynamic(obj)) {
var temp = file.generateUidIdentifier("obj", scope);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, obj)
]));
return temp;
} else {
return obj;
}
var temp = scope.generateUidBasedOnNode(obj, file);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, obj)
]));
return temp;
};
var buildHasOwn = function (obj, prop, file) {
return t.unaryExpression(
"!",
t.callExpression(
t.memberExpression(file.addDeclaration("has-own"), t.identifier("call")),
t.memberExpression(file.addHelper("has-own"), t.identifier("call")),
[obj, prop]
),
true

View File

@@ -1,14 +1,11 @@
var t = require("../../types");
var _ = require("lodash");
exports.BindMemberExpression = function (node, parent, file, scope) {
var object = node.object;
var prop = node.property;
var temp;
if (t.isDynamic(object)) {
temp = object = scope.generateTemp(file);
}
var temp = scope.generateTempBasedOnNode(node.object, file);
if (temp) object = temp;
var call = t.callExpression(
t.memberExpression(t.memberExpression(object, prop), t.identifier("bind")),
@@ -33,16 +30,12 @@ exports.BindFunctionExpression = function (node, parent, file, scope) {
]));
};
if (_.find(node.arguments, t.isDynamic)) {
var temp = scope.generateTemp(file, "args");
var temp = scope.generateTemp(file, "args");
return t.sequenceExpression([
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),
buildCall(node.arguments.map(function (node, i) {
return t.memberExpression(temp, t.literal(i), true);
}))
]);
} else {
return buildCall(node.arguments);
}
return t.sequenceExpression([
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),
buildCall(node.arguments.map(function (node, i) {
return t.memberExpression(temp, t.literal(i), true);
}))
]);
};

View File

@@ -20,7 +20,7 @@ exports.MethodDefinition = function (node, parent, file) {
if (t.isFunction(node)) return;
if (t.isReturnStatement(node) && node.argument) {
node.argument = t.memberExpression(t.callExpression(file.addDeclaration("define-property"), [
node.argument = t.memberExpression(t.callExpression(file.addHelper("define-property"), [
t.thisExpression(),
key,
node.argument

View File

@@ -1,25 +0,0 @@
var t = require("../../types");
exports.ObjectExpression = function (node, parent, file) {
var keys = [];
for (var i in node.properties) {
var prop = node.properties[i];
if (prop.computed || prop.kind !== "init") continue;
var key = prop.key;
if (t.isIdentifier(key)) {
key = key.name;
} else if (t.isLiteral(key)) {
key = key.value;
} else {
continue;
}
if (keys.indexOf(key) >= 0) {
throw file.errorWithNode(prop.key, "Duplicate property key");
} else {
keys.push(key);
}
}
};

View File

@@ -1,14 +1,27 @@
var t = require("../../types");
exports._has = function (node) {
var first = node.body[0];
return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" });
};
exports._wrap = function (node, callback) {
var useStrictNode;
if (exports._has(node)) {
useStrictNode = node.body.shift();
}
callback();
if (useStrictNode) {
node.body.unshift(useStrictNode);
}
};
exports.ast = {
exit: function (ast) {
var body = ast.program.body;
var first = body[0];
var noStrict = !first || !t.isExpressionStatement(first) || !t.isLiteral(first.expression) || first.expression.value !== "use strict";
if (noStrict) {
body.unshift(t.expressionStatement(t.literal("use strict")));
if (!exports._has(ast.program)) {
ast.program.body.unshift(t.expressionStatement(t.literal("use strict")));
}
}
};

View File

@@ -22,12 +22,14 @@ function traverse(parent, opts, scope) {
opts = opts || {};
var stopped = false;
for (var i in keys) {
var key = keys[i];
var nodes = parent[key];
if (!nodes) continue;
var updated = false;
var flatten = false;
var handle = function (obj, key) {
var node = obj[key];
@@ -50,7 +52,8 @@ function traverse(parent, opts, scope) {
// replace the node
node = obj[key] = result;
updated = true;
if (isArray) flatten = true;
// we're replacing a statement or block node with an array of statements so we better
// ensure that it's a block
@@ -59,16 +62,20 @@ function traverse(parent, opts, scope) {
}
};
var stopped = false;
var skipped = false;
var removed = false;
var context = {
stop: function () {
stopped = true;
skipped = stopped = true;
},
skip: function () {
skipped = true;
},
remove: function () {
this.stop();
this.skip();
removed = true;
}
};
@@ -84,11 +91,11 @@ function traverse(parent, opts, scope) {
if (removed) {
obj[key] = null;
updated = true;
flatten = true;
}
// stop iteration
if (stopped) return;
if (skipped) return;
}
// traverse node
@@ -103,9 +110,10 @@ function traverse(parent, opts, scope) {
if (_.isArray(nodes)) {
for (i in nodes) {
handle(nodes, i);
if (stopped) return;
}
if (updated) {
if (flatten) {
parent[key] = _.flatten(parent[key]);
if (key === "body") {
@@ -115,6 +123,7 @@ function traverse(parent, opts, scope) {
}
} else {
handle(parent, key);
if (stopped) return;
}
}
}
@@ -161,7 +170,7 @@ traverse.hasType = function (tree, type, blacklistTypes) {
enter: function (node) {
if (node.type === type) {
has = true;
this.stop();
this.skip();
}
}
});

View File

@@ -31,6 +31,13 @@ Scope.add = function (node, references) {
_.defaults(references, t.getIds(node, true));
};
/**
* Description
*
* @param {File} file
* @param {String} [name="temp"]
*/
Scope.prototype.generateTemp = function (file, name) {
var id = file.generateUidIdentifier(name || "temp", this);
this.push({
@@ -40,6 +47,70 @@ Scope.prototype.generateTemp = function (file, name) {
return id;
};
/*
* Description
*
* @param {Object} parent
* @param {File} file
* @param {Scope} scope
* @returns {Object}
*/
Scope.prototype.generateUidBasedOnNode = function (parent, file) {
var node = parent;
if (t.isAssignmentExpression(parent)) {
node = parent.left;
} else if (t.isVariableDeclarator(parent)) {
node = parent.id;
} else if (t.isProperty(node)) {
node = node.key;
}
var parts = [];
var add = function (node) {
if (t.isMemberExpression(node)) {
add(node.object);
add(node.property);
} else if (t.isIdentifier(node)) {
parts.push(node.name);
} else if (t.isLiteral(node)) {
parts.push(node.value);
} else if (t.isCallExpression(node)) {
add(node.callee);
}
};
add(node);
var id = parts.join("$");
id = id.replace(/^_/, "") || "ref";
return file.generateUidIdentifier(id, this);
};
/**
* Description
*
* @param {Object} node
* @param {File} file
* @returns {Object}
*/
Scope.prototype.generateTempBasedOnNode = function (node, file) {
if (t.isIdentifier(node) && this.has(node.name, true)) {
return null;
}
var id = this.generateUidBasedOnNode(node, file);
this.push({
key: id.name,
id: id
});
return id;
};
Scope.prototype.getInfo = function () {
var block = this.block;
if (block._scopeInfo) return block._scopeInfo;
@@ -93,7 +164,7 @@ Scope.prototype.getInfo = function () {
// this block is a function so we'll stop since none of the variables
// declared within are accessible
if (t.isFunction(node)) return this.stop();
if (t.isFunction(node)) return this.skip();
// function identifier doesn't belong to this scope
if (block.id && node === block.id) return;
@@ -123,6 +194,12 @@ Scope.prototype.getInfo = function () {
return info;
};
/**
* Description
*
* @param {Object} opts
*/
Scope.prototype.push = function (opts) {
var block = this.block;
@@ -143,33 +220,84 @@ Scope.prototype.push = function (opts) {
}
};
/**
* Description
*
* @param {Object} node
*/
Scope.prototype.add = function (node) {
Scope.add(node, this.references);
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
*/
Scope.prototype.get = function (id, decl) {
return id && (this.getOwn(id, decl) || this.parentGet(id, decl));
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
*/
Scope.prototype.getOwn = function (id, decl) {
var refs = this.references;
if (decl) refs = this.declarations;
return _.has(refs, id) && refs[id];
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
*/
Scope.prototype.parentGet = function (id, decl) {
return this.parent && this.parent.get(id, decl);
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.has = function (id, decl) {
return (id && (this.hasOwn(id, decl) || this.parentHas(id, decl))) ||
_.contains(Scope.defaultDeclarations, id);
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.hasOwn = function (id, decl) {
return !!this.getOwn(id, decl);
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.parentHas = function (id, decl) {
return this.parent && this.parent.has(id, decl);
};

View File

@@ -39,8 +39,9 @@
"ForInStatement": ["Statement", "For", "Scope", "Loop"],
"ForStatement": ["Statement", "For", "Scope", "Loop"],
"ObjectPattern": ["Pattern"],
"ArrayPattern": ["Pattern"],
"ObjectPattern": ["Pattern"],
"ArrayPattern": ["Pattern"],
"AssignmentPattern": ["Pattern"],
"Property": ["UserWhitespacable"],
"XJSElement": ["UserWhitespacable", "Expression"],

View File

@@ -3,6 +3,10 @@ var _ = require("lodash");
var t = exports;
t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"];
//
var addAssert = function (type, is) {
t["assert" + type] = function (node, opts) {
opts = opts || {};
@@ -64,7 +68,28 @@ _.each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
addAssert(type, is);
});
//
/**
* Description
*
* @param {Object} node
* @returns {Object}
*/
t.toComputedKey = function (node, key) {
if (!node.computed) {
if (t.isIdentifier(key)) key = t.literal(key.name);
}
return key;
};
/*
* Shallowly checks to see if the passed `node` will evaluate to a
* falsy. This is if `node` is a `Literal` and `value` is falsy or
* `node` is an `Identifier` with a name of `undefiend`.
*
* @param {Object} node
* @returns {Boolean}
*/
t.isFalsyExpression = function (node) {
if (t.isLiteral(node)) {
@@ -75,7 +100,14 @@ t.isFalsyExpression = function (node) {
return false;
};
//
/**
* Turn an array of statement `nodes` into a `SequenceExpression`.
*
* Variable declarations are turned into simple assignments and their
* declarations hoisted to the top of the current scope.
*
* Expression statements are just resolved to their standard expression.
*/
t.toSequenceExpression = function (nodes, scope) {
var exprs = [];
@@ -97,7 +129,11 @@ t.toSequenceExpression = function (nodes, scope) {
}
});
return t.sequenceExpression(exprs);
if (exprs.length === 1) {
return exprs[0];
} else {
return t.sequenceExpression(exprs);
}
};
//
@@ -116,21 +152,43 @@ t.shallowEqual = function (actual, expected) {
return same;
};
//
/**
* Description
*
* @param {Object} member
* @param {Object} append
* @param {Boolean} [computed]
* @returns {Object} member
*/
t.isDynamic = function (node) {
if (t.isExpressionStatement(node)) {
return t.isDynamic(node.expression);
} else if (t.isIdentifier(node) || t.isLiteral(node) || t.isThisExpression(node)) {
return false;
} else if (t.isMemberExpression(node)) {
return t.isDynamic(node.object) || t.isDynamic(node.property);
} else {
return true;
}
t.appendToMemberExpression = function (member, append, computed) {
member.object = t.memberExpression(member.object, member.property, member.computed);
member.property = append;
member.computed = !!computed;
return member;
};
// todo: https://github.com/eventualbuddha/ast-util/blob/9bf91c5ce8/lib/index.js#L454-L507
/**
* Description
*
* @param {Object} member
* @param {Object} append
* @returns {Object} member
*/
t.prependToMemberExpression = function (member, append) {
member.object = t.memberExpression(append, member.object);
return member;
};
/**
* Description
*
* @param {Object} node
* @param {Object} parent
* @returns {Boolean}
*/
t.isReferenced = function (node, parent) {
// we're a property key and we aren't computed so we aren't referenced
if (t.isProperty(parent) && parent.key === node && !parent.computed) return false;
@@ -152,11 +210,31 @@ t.isReferenced = function (node, parent) {
return false;
};
/**
* Description
*
* @param {String} name
* @returns {Boolean}
*/
t.isValidIdentifier = function (name) {
return _.isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isReservedWordES6(name, true);
};
/*
* Description
*
* @param {String} name
* @returns {String}
*/
t.toIdentifier = function (name) {
if (t.isIdentifier(name)) return name.name;
name = name + "";
// replace all non-valid identifiers with dashes
name = name.replace(/[^a-zA-Z0-9]/g, "-");
name = name.replace(/[^a-zA-Z0-9$_]/g, "-");
// remove all dashes and numbers from start of name
name = name.replace(/^[-0-9]+/, "");
@@ -166,18 +244,36 @@ t.toIdentifier = function (name) {
return c ? c.toUpperCase() : "";
});
// remove underscores from start of name
name = name.replace(/^\_/, "");
if (!t.isValidIdentifier(name)) {
name = "_" + name;
}
return name || '_';
};
t.isValidIdentifier = function (name) {
return _.isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isKeywordES6(name, true);
};
/**
* Description
*
* @param {Object} node
* @param {String} key
*/
t.ensureBlock = function (node, key) {
key = key || "body";
node[key] = t.toBlock(node[key], node);
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} [ignore]
* @returns {Object|Boolean}
*/
t.toStatement = function (node, ignore) {
if (t.isStatement(node)) {
return node;
@@ -211,6 +307,14 @@ t.toStatement = function (node, ignore) {
return node;
};
/**
* Description
*
* @param {Object} node
* @param {Object} parent
* @returns {Object}
*/
t.toBlock = function (node, parent) {
if (t.isBlockStatement(node)) {
return node;
@@ -231,6 +335,15 @@ t.toBlock = function (node, parent) {
return t.blockStatement(node);
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} [map]
* @param {Array} [ignoreTypes]
* @returns {Array|Object}
*/
t.getIds = function (node, map, ignoreTypes) {
ignoreTypes = ignoreTypes || [];
@@ -281,10 +394,24 @@ t.getIds.arrays = {
ObjectPattern: ["properties"]
};
/**
* Description
*
* @param {Object} node
* @returns {Boolean}
*/
t.isLet = function (node) {
return t.isVariableDeclaration(node) && (node.kind !== "var" || node._let);
};
/**
* Description
*
* @param {Object} node
* @returns {Boolean}
*/
t.isVar = function (node) {
return t.isVariableDeclaration(node, { kind: "var" }) && !node._let;
};
@@ -293,6 +420,13 @@ t.isVar = function (node) {
t.COMMENT_KEYS = ["leadingComments", "trailingComments"];
/**
* Description
*
* @param {Object} child
* @returns {Object} child
*/
t.removeComments = function (child) {
_.each(t.COMMENT_KEYS, function (key) {
delete child[key];
@@ -300,6 +434,14 @@ t.removeComments = function (child) {
return child;
};
/**
* Description
*
* @param {Object} child
* @param {Object} parent
* @returns {Object} child
*/
t.inheritsComments = function (child, parent) {
_.each(t.COMMENT_KEYS, function (key) {
child[key] = _.uniq(_.compact([].concat(child[key], parent[key])));
@@ -307,7 +449,13 @@ t.inheritsComments = function (child, parent) {
return child;
};
//
/**
* Description
*
* @param {Object} child
* @param {Object} parent
* @returns {Object} child
*/
t.inherits = function (child, parent) {
child.loc = parent.loc;
@@ -318,10 +466,24 @@ t.inherits = function (child, parent) {
return child;
};
/**
* Description
*
* @param {Object} specifier
* @returns {String}
*/
t.getSpecifierName = function (specifier) {
return specifier.name || specifier.id;
};
/**
* Description
*
* @param {Object} specifier
* @returns {Boolean}
*/
t.isSpecifierDefault = function (specifier) {
return t.isIdentifier(specifier.id) && specifier.id.name === "default";
};

View File

@@ -3,6 +3,7 @@
"ArrayPattern": ["elements"],
"ArrowFunctionExpression": ["params", "defaults", "rest", "body"],
"AssignmentExpression": ["left", "right"],
"AssignmentPattern": ["left", "right"],
"AwaitExpression": ["argument"],
"BinaryExpression": ["left", "right"],
"BindFunctionExpression": ["callee", "arguments"],

View File

@@ -12,7 +12,7 @@ var _ = require("lodash");
exports.inherits = util.inherits;
exports.canCompile = function (filename, altExts) {
var exts = altExts || [".js", ".jsx", ".es6"];
var exts = altExts || [".js", ".jsx", ".es6", ".es"];
var ext = path.extname(filename);
return _.contains(exts, ext);
};
@@ -52,22 +52,6 @@ exports.arrayify = function (val) {
throw new TypeError("illegal type for arrayify");
};
exports.getUid = function (parent, file) {
var node;
if (t.isAssignmentExpression(parent)) {
node = parent.left;
} else if (t.isVariableDeclarator(parent)) {
node = parent.id;
}
var id = "ref";
if (t.isIdentifier(node)) id = node.name;
return file.generateUidIdentifier(id);
};
exports.isAbsolute = function (loc) {
if (!loc) return false;
if (loc[0] === "/") return true; // unix

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "2.4.1",
"version": "2.6.0",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://github.com/6to5/6to5",
"repository": {
@@ -18,6 +18,10 @@
"6to5-node": "./bin/6to5-node",
"6to5-runtime": "./bin/6to5-runtime"
},
"browser": {
"./lib/6to5/index.js": "./lib/6to5/browser.js",
"./lib/6to5/register.js": "./lib/6to5/register-browser.js"
},
"keywords": [
"harmony",
"classes",
@@ -35,19 +39,20 @@
"test": "make test"
},
"dependencies": {
"acorn-6to5": "0.11.1-1",
"acorn-6to5": "0.11.1-11",
"ast-types": "~0.6.1",
"chokidar": "0.11.1",
"commander": "2.5.0",
"core-js": "^0.3.3",
"core-js": "^0.4.0",
"estraverse": "1.8.0",
"esutils": "1.1.6",
"esvalid": "^1.1.0",
"fs-readdir-recursive": "0.1.0",
"jshint": "^2.5.10",
"lodash": "2.4.1",
"mkdirp": "0.5.0",
"private": "0.1.6",
"regenerator": "^0.8.2",
"regenerator": "^0.8.3",
"regexpu": "0.3.0",
"roadrunner": "^1.0.4",
"source-map": "0.1.40",

View File

@@ -1,8 +1,9 @@
var fs = require("fs");
var _ = require("lodash");
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var humanise = function (val) {
return val.replace(/-/g, " ");
return path.basename(val, path.extname(val)).replace(/-/g, " ");
};
var readFile = exports.readFile = function (filename) {
@@ -15,11 +16,11 @@ var readFile = exports.readFile = function (filename) {
}
};
exports.get = function (entryName) {
exports.get = function (entryName, entryLoc) {
if (exports.cache[entryName]) return exports.cache[entryName];
var suites = [];
var entryLoc = __dirname + "/fixtures/" + entryName;
var entryLoc = entryLoc || __dirname + "/fixtures/" + entryName;
_.each(fs.readdirSync(entryLoc), function (suiteName) {
if (suiteName[0] === ".") return;
@@ -35,9 +36,18 @@ exports.get = function (entryName) {
var suiteOptsLoc = suite.filename + "/options.json";
if (fs.existsSync(suiteOptsLoc)) suite.options = require(suiteOptsLoc);
_.each(fs.readdirSync(suite.filename), function (taskName) {
var taskDir = suite.filename + "/" + taskName;
if (fs.statSync(taskDir).isFile()) return;
if (fs.statSync(suite.filename).isFile()) {
push(suiteName, suite.filename);
} else {
_.each(fs.readdirSync(suite.filename), function (taskName) {
var taskDir = suite.filename + "/" + taskName;
push(taskName, taskDir);
});
}
function push(taskName, taskDir) {
// tracuer error tests
if (taskName.indexOf("Error_") >= 0) return;
var actualLocAlias = suiteName + "/" + taskName + "/actual.js";
var expectLocAlias = suiteName + "/" + taskName + "/expected.js";
@@ -47,6 +57,13 @@ exports.get = function (entryName) {
var expectLoc = taskDir + "/expected.js";
var execLoc = taskDir + "/exec.js";
if (fs.statSync(taskDir).isFile()) {
var ext = path.extname(taskDir);
if (ext !== ".js" && ext !== ".module.js") return;
execLoc = taskDir;
}
var taskOpts = _.merge({
filenameRelative: expectLocAlias,
sourceFileName: actualLocAlias,
@@ -77,6 +94,18 @@ exports.get = function (entryName) {
}
};
// traceur checks
var shouldSkip = function (code) {
return code.indexOf("// Error:") >= 0 || code.indexOf("// Skip.") >= 0;
};
if (shouldSkip(test.actual.code) || shouldSkip(test.exec.code)) {
return;
} else if (test.exec.code.indexOf("// Async.") >= 0) {
//test.options.asyncExec = true;
}
suite.tests.push(test);
var sourceMappingsLoc = taskDir + "/source-mappings.json";
@@ -90,7 +119,7 @@ exports.get = function (entryName) {
test.options.sourceMap = true;
test.sourceMap = require(sourceMap);
}
});
}
});
return exports.cache[entryName] = suites;
@@ -104,4 +133,5 @@ try {
var cache = exports.cache = {};
cache.transformation = exports.get("transformation");
cache.generation = exports.get("generation");
cache.esnext = exports.get("esnext");
}

View File

@@ -0,0 +1,168 @@
var genHelpers = require("./_generator-helpers");
var transform = require("../lib/6to5/transformation/transform");
var sourceMap = require("source-map");
var esvalid = require("esvalid");
var Module = require("module");
var helper = require("./_helper");
var assert = require("assert");
var chai = require("chai");
var path = require("path");
var util = require("../lib/6to5/util");
var _ = require("lodash");
require("../lib/6to5/polyfill");
global.assertNoOwnProperties = function (obj) {
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
};
global.assertArrayEquals = assert.deepEqual;
global.assert = chai.assert;
global.chai = chai;
global.genHelpers = genHelpers;
// Different Traceur generator message
chai.assert._throw = chai.assert.throw;
chai.assert.throw = function (fn, msg) {
if (msg === '"throw" on executing generator' ||
msg === '"next" on executing generator') {
msg = "Generator is already running";
} else if (msg === "Sent value to newborn generator") {
msg = /^attempt to send (.*?) to newborn generator$/;
}
return chai.assert._throw(fn, msg);
};
var run = function (task, done) {
var actual = task.actual;
var expect = task.expect;
var exec = task.exec;
var opts = task.options;
var getOpts = function (self) {
return _.merge({
filename: self.loc
}, opts);
};
var execCode = exec.code;
var result;
var checkAst = function (result) {
if (opts.noCheckAst) return;
var errors = esvalid.errors(result.ast.program);
if (errors.length) {
var msg = [];
_.each(errors, function (err) {
msg.push(err.message + " - " + JSON.stringify(err.node));
});
throw new Error(msg.join(". "));
}
};
if (execCode) {
result = transform(execCode, getOpts(exec));
checkAst(result);
execCode = result.code;
try {
var fakeRequire = function (loc) {
if (loc === "../../../src/runtime/polyfills/Number.js") {
return Number;
} else if (loc === "../../../src/runtime/polyfills/Math.js") {
return Math;
} else {
return require(path.resolve(exec.loc, "..", loc));
}
};
var fn = new Function("require", "done", execCode);
fn.call(global, fakeRequire, chai.assert, done);
} catch (err) {
err.message = exec.loc + ": " + err.message;
err.message += util.codeFrame(execCode);
throw err;
}
}
var actualCode = actual.code;
var expectCode = expect.code;
if (!execCode || actualCode) {
result = transform(actualCode, getOpts(actual));
checkAst(result);
actualCode = result.code;
chai.expect(actualCode).to.be.equal(expectCode, actual.loc + " !== " + expect.loc);
}
if (task.sourceMap) {
chai.expect(result.map).to.deep.equal(task.sourceMap);
}
if (task.sourceMappings) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
_.each(task.sourceMappings, function (mapping, i) {
var expect = mapping.original;
var actual = consumer.originalPositionFor(mapping.generated);
chai.expect({ line: actual.line, column: actual.column }).to.deep.equal(expect);
});
}
};
module.exports = function (suiteOpts, taskOpts, dynamicOpts) {
taskOpts = taskOpts || {};
require("../register")(taskOpts);
_.each(helper.get(suiteOpts.name, suiteOpts.loc), function (testSuite) {
if (_.contains(suiteOpts.ignoreSuites, testSuite.title)) return;
suite(suiteOpts.name + "/" + testSuite.title, function () {
_.each(testSuite.tests, function (task) {
if (_.contains(suiteOpts.ignoreTasks, task.title) || _.contains(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)) return;
var runTest = function (done) {
var runTask = function () {
try {
run(task, done);
} catch (err) {
if (task.options.after) task.options.after();
throw err;
}
};
_.extend(task.options, taskOpts);
if (dynamicOpts) dynamicOpts(task.options, task);
var throwMsg = task.options.throws;
if (throwMsg) {
// internal api doesn't have this option but it's best not to pollute
// the options object with useless options
delete task.options.throws;
assert.throws(runTask, function (err) {
return throwMsg === true || err.message.indexOf(throwMsg) >= 0;
});
} else {
runTask();
}
};
var callback;
if (task.options.asyncExec) {
callback = runTest;
} else {
callback = function () {
return runTest();
};
}
test(task.title, !task.disabled && callback);
});
});
});
};

View File

@@ -13,10 +13,10 @@ suite("api", function () {
assert.ok(!result.ast);
});
test("addDeclaration unknown", function () {
test("addHelper unknown", function () {
var file = new File;
assert.throws(function () {
file.addDeclaration("foob");
file.addHelper("foob");
}, /unknown declaration foob/);
});
});

19
test/browserify.js Normal file
View File

@@ -0,0 +1,19 @@
var browserify = require("browserify");
var assert = require("assert");
var path = require("path");
var vm = require("vm");
suite("browserify", function() {
test("6to5/register may be used without breaking browserify", function(done) {
var bundler = browserify(path.join(__dirname, "fixtures/browserify/register.js"));
bundler.bundle(function(err, bundle) {
if (err) return done(err);
assert.ok(bundle.length, "bundle output code");
// ensure that the code runs without throwing an exception
vm.runInNewContext(bundle, {});
done();
})
})
});

5
test/esnext.js Normal file
View File

@@ -0,0 +1,5 @@
if (!process.env.ALL_6TO5_TESTS) return;
require("./_transformation-helper")({
name: "esnext"
});

3
test/fixtures/browserify/register.js vendored Normal file
View File

@@ -0,0 +1,3 @@
require("../../../register")({
ignore: false
});

View File

@@ -0,0 +1,57 @@
function makeMultiplier() {
// `arguments` should refer to `makeMultiplier`'s arguments.
return (n) => [].slice.call(arguments).reduce((a, b) => a * b) * n;
}
function toArray() {
// Intentionally nest arrow functions to ensure `arguments` is put inside
// `toArray`'s scope.
return (() => (arguments, (() => [].slice.call(arguments)).call())).call();
}
function returnDotArguments(object) {
// Ensure `arguments` is not treated as a reference to the magic value.
return (() => object.arguments).call();
}
function returnArgumentsObject() {
// Ensure `arguments` is not treated as a reference to the magic value.
return (() => ({arguments: 1})).call();
}
function makeArgumentsReturner() {
return (() => function() {
return [].slice.call(arguments);
}).call();
}
// i.e. 2 * 3 * 4 == 24, not 16 (4 * 4)
assert.equal(
makeMultiplier(2, 3)(4),
24,
'ensure `arguments` is hoisted out to the first non-arrow scope'
);
assert.deepEqual(
toArray(1, 2, 3),
[1, 2, 3],
'ensure `arguments` is hoisted out to the first non-arrow scope'
);
assert.equal(
returnDotArguments({arguments: 1}),
1,
'member accesses with `arguments` property should not be replaced'
);
assert.deepEqual(
returnArgumentsObject(),
{arguments: 1},
'object property keys named `arguments` should not be replaced'
);
assert.deepEqual(
makeArgumentsReturner()(1, 2, 3),
[1, 2, 3],
'arguments should not be hoisted from inside non-arrow functions'
);

View File

@@ -0,0 +1,5 @@
var dynamicThisGetter = () => function () { return this; };
assert.equal(
'(' + dynamicThisGetter.toString() + ')',
'(function () {\n return function () {\n return this;\n };\n})'
);

View File

@@ -0,0 +1,2 @@
var empty = () => {};
assert.equal(empty(), undefined);

View File

@@ -0,0 +1,12 @@
var obj = {
method: function() {
return () => (this, () => this);
},
method2: function() {
return () => () => this;
}
};
assert.strictEqual(obj.method()()(), obj);
assert.strictEqual(obj.method2()()(), obj);

View File

@@ -0,0 +1,2 @@
var square = x => x * x;
assert.equal(square(4), 16);

View File

@@ -0,0 +1,2 @@
var keyMaker = val => ({ key: val });
assert.deepEqual(keyMaker(9), { key: 9 });

View File

@@ -0,0 +1,7 @@
var obj = {
method: function() {
return () => this;
}
};
assert.strictEqual(obj.method()(), obj);

View File

@@ -0,0 +1,2 @@
var odds = [0, 2, 4].map(v => v + 1);
assert.deepEqual(odds, [1, 3, 5]);

View File

@@ -0,0 +1,2 @@
var identity = x => x;
assert.equal(identity(1), 1);

View File

@@ -0,0 +1,29 @@
var Animal = class {
sayHi() {
return 'Hi, I am a '+this.type()+'.';
}
static getName() {
return 'Animal';
}
};
var Dog = class extends Animal {
type() { return 'dog'; }
sayHi() {
return super() + ' WOOF!';
}
static getName() {
return super() + '/Dog';
}
};
assert.equal(new Dog().sayHi(), 'Hi, I am a dog. WOOF!');
assert.equal(Dog.getName(), 'Animal/Dog');
var count = 0;
var Cat = class extends (function(){ count++; return Animal; })() {};
assert.equal(count, 1);

View File

@@ -0,0 +1,21 @@
class Animal {
sayHi() {
return 'I am an animal.'
}
sayOther() {
return 'WAT?!';
}
}
class Horse extends Animal {
sayHi() {
return super.sayOther();
}
sayOther() {
return 'I see dead objects.';
}
}
assert.equal(new Horse().sayHi(), 'WAT?!');

View File

@@ -0,0 +1,9 @@
var Person = (class Person {});
assert.equal(typeof Person, 'function');
assert.equal(
(function(){ return (class Person {}); })().name,
'Person'
);
assert.equal(typeof (class {}), 'function');

View File

@@ -0,0 +1,15 @@
class Animal {
sayHi() {
return 'Hi, I am a '+this.type()+'.';
}
}
class Dog extends Animal {
type() { return 'dog'; }
sayHi() {
return super() + ' WOOF!';
}
}
assert.equal(new Dog().sayHi(), 'Hi, I am a dog. WOOF!');

View File

@@ -0,0 +1,14 @@
class Multiplier {
constructor(n=1) {
this.n = n;
}
multiply(n=1) {
return n * this.n;
}
}
assert.equal(new Multiplier().n, 1);
assert.equal(new Multiplier(6).n, 6);
assert.equal(new Multiplier().multiply(), 1);
assert.equal(new Multiplier(2).multiply(3), 6);

View File

@@ -0,0 +1,10 @@
class Person {
getName() {
return this.firstName + ' ' + this.lastName;
}
}
var me = new Person();
me.firstName = 'Brian';
me.lastName = 'Donovan';
assert.equal(me.getName(), 'Brian Donovan');

View File

@@ -0,0 +1,5 @@
class Foo {
}
assert.equal(new Foo().constructor, Foo, 'Foo instances should have Foo as constructor');
assert.ok(new Foo() instanceof Foo, 'Foo instances should be `instanceof` Foo');

View File

@@ -0,0 +1,20 @@
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(1, 2);
var keys = [];
for (var key in point) {
keys.push(key);
}
assert.equal(point.toString(), '(1, 2)');
assert.deepEqual(keys.sort(), ['toString', 'x', 'y']);

View File

@@ -0,0 +1,15 @@
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ZeroPoint extends Point {
constructor() {
super(0, 0);
}
}
assert.equal(new ZeroPoint().x, 0);
assert.equal(new ZeroPoint().y, 0);

View File

@@ -0,0 +1,4 @@
class Obj extends null {}
assert.strictEqual(Obj.toString, Function.toString);
assert.strictEqual(new Obj().toString, undefined);

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