Compare commits

...

80 Commits

Author SHA1 Message Date
Sebastian McKenzie
7e6e5d4746 v5.2.10 2015-05-04 22:23:39 +01:00
Sebastian McKenzie
12d650e195 checkSelf() for destructuring catch clauses 2015-05-04 22:22:39 +01:00
Sebastian McKenzie
8fb58492df fix default specifiers not taking into consideration sourced imports 2015-05-04 22:20:52 +01:00
Sebastian McKenzie
2c0c2f12df avoid trying to replace a node with itself, antipattern! 2015-05-04 22:20:52 +01:00
Sebastian McKenzie
01e5354fd9 disallow replacing a node with itself 2015-05-04 22:20:52 +01:00
Sebastian McKenzie
0b100c4273 Merge pull request #1386 from jayphelps/module-id-overload
Added getModuleName() option as a function
2015-05-04 22:20:31 +01:00
Jay Phelps
340e75eb59 Added getModuleName() option as a function, allowing you to manipulate the name as needed 2015-05-04 13:30:57 -07:00
Sebastian McKenzie
53808a6d45 fix test/core/path imports 2015-05-04 15:25:35 +01:00
Sebastian McKenzie
e6326332b6 properly coerce input code to string - fixes #1432 2015-05-04 15:08:18 +01:00
Sebastian McKenzie
9e0cf84505 adds test for #1431 2015-05-04 15:06:27 +01:00
Sebastian McKenzie
b7eea7b08c Merge pull request #1431 from pangratz/fix_replaceWithSourceString
Fix bugs in `replaceWithSourceString`
2015-05-04 15:00:27 +01:00
pangratz
92dd67856e Fix bugs in replaceWithSourceString
This fixes 2 bugs within `replaceWithSourceString`:

- `code` is undefined as it should be `replacement`
- the expression of the parsed replacement hasn't been accessed correctly
2015-05-04 09:33:32 +02:00
Sebastian McKenzie
a2bb587e24 remove embedded jsx plugin and use acorn-jsx 2015-05-04 04:33:46 +01:00
Sebastian McKenzie
0c570cb599 5.2.9 2015-05-04 04:03:41 +01:00
Sebastian McKenzie
db6fab2c8f v5.2.9 2015-05-04 04:02:30 +01:00
Sebastian McKenzie
d92deb52b6 v5.2.8 2015-05-04 04:00:13 +01:00
Sebastian McKenzie
b8b70f2f4a rejigger around parse mechanics 2015-05-04 03:57:28 +01:00
Sebastian McKenzie
a8a3f6d34d Merge branch 'master' of github.com:babel/babel 2015-05-04 03:55:25 +01:00
Sebastian McKenzie
9847d226e1 add transform import - closes babel/babel-eslint#83 2015-05-04 03:54:58 +01:00
Sebastian McKenzie
3d48a16305 Merge pull request #1417 from loganfsmyth/fix-phantom-issue-1405
Explicitly sort instead of relying on key ordering.
2015-05-04 03:29:30 +01:00
Sebastian McKenzie
3d24cc9ae5 Merge pull request #1224 from jcoglan/fix-source-map-pathnames
Correct relative pathnames in source maps.
2015-05-04 00:03:27 +01:00
Sebastian McKenzie
5acc58dd68 5.2.7 2015-05-03 23:48:48 +01:00
Sebastian McKenzie
34f02f06a6 v5.2.7 2015-05-03 23:47:50 +01:00
Sebastian McKenzie
6d3fe5b85c add 5.2.7 changelog 2015-05-03 23:45:33 +01:00
Sebastian McKenzie
3878bd812c remove native super inheritance from classes - fixes #1424 2015-05-03 23:45:26 +01:00
Sebastian McKenzie
0717eaddce normalise Program replacement nodes 2015-05-03 23:35:39 +01:00
Sebastian McKenzie
102cbbe493 fix up crazy parse argument order 2015-05-03 23:31:37 +01:00
Sebastian McKenzie
d981b30194 clean up file transform pipeline 2015-05-03 23:26:37 +01:00
Sebastian McKenzie
0fc02f2cf0 add support for replacing nodes with expression source strings 2015-05-03 23:02:19 +01:00
Sebastian McKenzie
f24b5164d4 add extensions option to babel cli 2015-05-03 22:43:20 +01:00
Sebastian McKenzie
4be27ee72c update bin tests to reflect new helper format 2015-05-03 17:47:31 +01:00
Sebastian McKenzie
f0070e4828 ignore _generated FunctionDeclarations too in es6.spec.symbols transformer 2015-05-03 17:40:30 +01:00
Sebastian McKenzie
ce8beec22c update tests to reflect new helper format 2015-05-03 17:28:32 +01:00
Sebastian McKenzie
b30bdf2294 turn inserted helper declarations into function declarations if possible 2015-05-03 17:22:51 +01:00
Sebastian McKenzie
63b44a3e6e fix transformer and module formatter list in $ babel --help - fixes #1421 2015-05-02 23:16:37 +01:00
Logan Smyth
74aaf848ed Explicitly sort instead of relying on implementation-defined numeric key ordering - fixes #1405. 2015-05-01 20:00:22 -07:00
Sebastian McKenzie
95de5400e6 remove dead if statement explosion code - fixes #1413 2015-05-01 23:30:26 +01:00
Sebastian McKenzie
fe7079802b move deadCodeElimination transformer up - fixes #1409, fixes #1408 2015-05-01 23:24:16 +01:00
Sebastian McKenzie
61ddb14e25 Merge branch 'master' of github.com:babel/babel 2015-05-01 23:14:58 +01:00
Sebastian McKenzie
ca7a93cd64 move utility.deadCodeElimination transformer to minification 2015-05-01 23:13:48 +01:00
Sebastian McKenzie
90a1c81d30 split up es3.xLiterals transformers - fixes #1415 2015-05-01 23:13:30 +01:00
Sebastian McKenzie
5e9089d104 Merge pull request #1411 from hzoo/jshint-cleanup
remove old references to jshint
2015-05-01 22:45:15 +01:00
Henry Zhu
1a716943bc remove old references to jshint 2015-05-01 14:08:47 -04:00
Sebastian McKenzie
c28415c38a handle shorthand objects properly when renaming bindings, create new ones and refresh the stored binding identifier if necessary - fixes #1406 2015-05-01 15:23:46 +01:00
Sebastian McKenzie
e1491de6b8 5.2.6 2015-05-01 13:09:33 +01:00
Sebastian McKenzie
253ea8cd18 v5.2.6 2015-05-01 13:08:28 +01:00
Sebastian McKenzie
d37bad3149 add 5.2.6 changelog 2015-05-01 13:07:38 +01:00
Sebastian McKenzie
a2b912bc77 add BABEL mention to deprecation message 2015-05-01 13:07:31 +01:00
Sebastian McKenzie
f1bfbe44e2 expose Pipeline as TransformerPipeline 2015-05-01 13:00:34 +01:00
Sebastian McKenzie
dbdd07d0b8 fix addAliases call 2015-05-01 13:00:26 +01:00
Sebastian McKenzie
166909998e 5.2.5 2015-05-01 13:00:15 +01:00
Sebastian McKenzie
a8ec4c965c v5.2.5 2015-05-01 11:41:15 +01:00
Sebastian McKenzie
d2aff67c6c 5.2.4 2015-05-01 11:39:43 +01:00
Sebastian McKenzie
3353de225d fix parse API not adding all the correct pipeline transformers 2015-05-01 11:39:38 +01:00
Sebastian McKenzie
203ebeef20 v5.2.4 2015-05-01 11:29:06 +01:00
Sebastian McKenzie
032cf990c3 add 5.2.4 changelog 2015-05-01 11:28:24 +01:00
Sebastian McKenzie
16cdb43c67 expose transform pipeline and require node api inside of the browser one to avoid race conditions 2015-05-01 11:27:23 +01:00
Sebastian McKenzie
6f622033c5 5.2.3 2015-05-01 11:27:02 +01:00
Sebastian McKenzie
531d4f1937 v5.2.3 2015-05-01 09:42:23 +01:00
Sebastian McKenzie
f155bc249c fix Program global reference catching for real this time 2015-05-01 09:41:35 +01:00
Sebastian McKenzie
452d0ef30e fix Program global reference catching 2015-05-01 09:40:03 +01:00
Sebastian McKenzie
005754ba98 Revert "Revert "make dead code elimination smarter and eliminate non-referenced "pure" nodes""
This reverts commit c3c4cf17e3.
2015-05-01 09:39:33 +01:00
Sebastian McKenzie
c3c4cf17e3 Revert "make dead code elimination smarter and eliminate non-referenced "pure" nodes"
This reverts commit 4e87809ff9.
2015-05-01 09:39:07 +01:00
Sebastian McKenzie
0866e5a403 add 5.2.3 changelog 2015-05-01 09:36:48 +01:00
Sebastian McKenzie
15f5e658fc Merge branch 'master' of github.com:babel/babel 2015-05-01 09:32:28 +01:00
Sebastian McKenzie
574e6da132 add Statement and Declaration aliases to flow types - fixes #1401 2015-05-01 09:32:11 +01:00
Sebastian McKenzie
da6d27ed16 Merge pull request #1404 from timbur/master
hopefully fixes #1402
2015-05-01 09:31:46 +01:00
Sebastian McKenzie
4e87809ff9 make dead code elimination smarter and eliminate non-referenced "pure" nodes 2015-05-01 09:31:28 +01:00
Sebastian McKenzie
f4267aaab0 Merge pull request #1403 from wyand/master
fix spelling
2015-05-01 09:28:46 +01:00
Sebastian McKenzie
4f255d103a Merge pull request #1400 from monsanto/flow-object-commas
Support commas as object property separators in flow
2015-05-01 09:24:08 +01:00
Tim Burgess
502cc13aed hopefully fixes #1402 2015-05-01 04:05:22 -04:00
Dan Wyand
0a1154e6fd fix spelling 2015-05-01 01:01:10 -04:00
Christopher Monsanto
f5b3d72730 support commas as obj property separators in flow 2015-05-01 00:09:26 -04:00
Sebastian McKenzie
e9bcccffbd futz the bundler idea 2015-05-01 03:26:12 +01:00
Sebastian McKenzie
aaf4cbf06f start on babel module bundling and type inferrence 2015-05-01 02:59:59 +01:00
Sebastian McKenzie
5080534974 5.2.2 2015-05-01 00:44:48 +01:00
Sebastian McKenzie
02cb397873 v5.2.2 2015-05-01 00:43:39 +01:00
Sebastian McKenzie
d9169a87ad allow util.arrayify to take arbitrary types and coerce it into an array - #1398 2015-05-01 00:41:47 +01:00
Sebastian McKenzie
f3b6f2fc61 5.2.1 2015-05-01 00:41:24 +01:00
James Coglan
1f2f4ce4f3 Correct relative pathnames in source maps.
Say you have a file called `src/thing.js` and you run

    $ babel src/thing.js --out-file lib/thing.js --source-maps true

This generates a source map at `lib/thing.js.map` that contains
"src/thing.js" in its `sources` array. This is incorrect; since browsers
resolve all relative URLs relative to the directory containing the file
that refers to the URL, this resolves to `lib/src/thing.js`.

To make the source map refer to the source files correctly, the
`sources` array should contain "../src/thing.js".
2015-04-13 21:17:11 +01:00
90 changed files with 930 additions and 1277 deletions

View File

@@ -13,6 +13,54 @@ _Note: Gaps between patch versions are faulty/broken releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.2.9
* **Bug Fix**
* Fix `_blockHoist` transformer incorrectly sorting nodes on shitty environments that aren't spec compliant in their key order.
* Fix broken `parse` API method reference to an undeclared import.
## 5.2.7
* **Bug Fix**
* Move `utility.deadCodeElimination` transformer up to avoid race conditions.
* Fix shorthand property scope binding renaming.
* **Polish**
* Turn helper variable declarations into function declarations if possible.
* **Internal**
* Removed native inheritance support from classes.
* Added `replaceWithSourceString` path API.
* Split up `es3.propertyLiterals` and `es3.memberExpressionLiterals` transformers to `minfication.propertyLiterals` and `es3.memberExpressionLiterals`.
## 5.2.6
* **Internal**
* Fix transformer aliases being accidently set as deprecated ones.
* Expose `Pipeline` as `TransformerPipeline` instead.
## 5.2.5
* **Bug Fix**
* Fix `parse` API not adding all the correct pipeline transformers.
## 5.2.4
* **Bug Fix**
* Fix race condition with the Node API being loaded awkwardly and not being able to initialise itself when used in the browser.
* **Internal**
* Expose `transform.pipeline`.
## 5.2.3
* **Bug Fix**
* Fix plugin containers being called with an undefined import. Thanks [@timbur](https://github.com/timbur)!
* Allow Flow object separators to be commas. Thanks [@monsanto](https://github.com/monsanto)!
* Add missing `Statement` and `Declaration` node aliases to flow types.
## 5.2.2
* **Internal**
* Allow `util.arrayify` to take arbitrary types and coerce it into an array.
## 5.2.1
* **Bug Fix**

View File

@@ -3,7 +3,6 @@ BROWSERIFY_CMD = node_modules/browserify/bin/cmd.js
ISTANBUL_CMD = node_modules/istanbul/lib/cli.js cover
UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
#UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
JSHINT_CMD = node_modules/jshint/bin/jshint
MOCHA_CMD = node_modules/mocha/bin/_mocha
BABEL_CMD = node_modules/babel/bin/babel

View File

@@ -1,7 +1,7 @@
{
"name": "babel-core",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.2.1",
"version": "5.2.10",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"repository": "babel/babel",
@@ -27,7 +27,9 @@
"test": "make test"
},
"dependencies": {
"acorn-jsx": "^1.0.0",
"ast-types": "~0.7.0",
"bluebird": "^2.9.25",
"chalk": "^1.0.0",
"convert-source-map": "^1.1.0",
"core-js": "^0.9.0",
@@ -49,6 +51,7 @@
"regenerator": "^0.8.20",
"regexpu": "^1.1.2",
"repeating": "^1.1.2",
"resolve": "^1.1.6",
"shebang-regex": "^1.0.0",
"slash": "^1.0.0",
"source-map": "^0.4.0",

View File

@@ -30,7 +30,7 @@ module.exports = function (commander, filenames, opts) {
var handleFile = function (src, filename) {
if (util.shouldIgnore(src)) return;
if (util.canCompile(filename)) {
if (util.canCompile(filename, commander.extensions)) {
write(src, filename);
} else if (commander.copyFiles) {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));

View File

@@ -27,9 +27,14 @@ module.exports = function (commander, filenames, opts) {
if (result.map) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
var sourceFilename = filename;
map._sources.add(filename);
map.setSourceContent(filename, result.actual);
if (commander.outFile) {
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
}
map._sources.add(sourceFilename);
map.setSourceContent(sourceFilename, result.actual);
consumer.eachMapping(function (mapping) {
map._mappings.add({
@@ -37,7 +42,7 @@ module.exports = function (commander, filenames, opts) {
generatedColumn: mapping.generatedColumn,
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
source: filename
source: sourceFilename
});
});

View File

@@ -1,14 +1,15 @@
#!/usr/bin/env node
var commander = require("commander");
var transform = require("babel-core").transform;
var kebabCase = require("lodash/string/kebabCase");
var options = require("babel-core").options;
var util = require("babel-core").util;
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
var fs = require("fs");
var glob = require("glob");
var moduleFormatters = require("babel-core/lib/babel/transformation/modules");
var commander = require("commander");
var transform = require("babel-core").transform;
var kebabCase = require("lodash/string/kebabCase");
var options = require("babel-core").options;
var util = require("babel-core").util;
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
var fs = require("fs");
var glob = require("glob");
each(options, function (option, key) {
if (option.hidden) return;
@@ -36,6 +37,7 @@ each(options, function (option, key) {
commander.option(arg, desc.join(" "));
})
commander.option("-x, --extensions [extensions]", "List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx]");
commander.option("-w, --watch", "Recompile files on changes");
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
@@ -57,8 +59,8 @@ commander.on("--help", function () {
console.log();
};
outKeys("Transformers", transform.transformers);
outKeys("Module formatters", transform.moduleFormatters);
outKeys("Transformers", transform.pipeline.transformers);
outKeys("Module formatters", moduleFormatters);
});
var pkg = require("../../package.json");

View File

@@ -1,13 +1,13 @@
{
"name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.2.0",
"version": "5.2.9",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.2.0",
"babel-core": "^5.2.9",
"chokidar": "^1.0.0",
"commander": "^2.6.0",
"convert-source-map": "^1.1.0",

View File

@@ -1,7 +1,7 @@
{
"name": "babel-runtime",
"description": "babel selfContained runtime",
"version": "5.2.0",
"version": "5.2.9",
"repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"dependencies": {

View File

@@ -1,3 +1,6 @@
export * from "./src/index";
import "./plugins/flow";
import "./plugins/jsx";
import inject from "acorn-jsx/inject";
import * as acorn from "./src/index";
inject(acorn);

View File

@@ -322,7 +322,7 @@ pp.flow_parseObjectType = function (allowStatic) {
}
pp.flow_objectTypeSemicolon = function () {
if (!this.eat(tt.semi) && this.type !== tt.braceR) {
if (!this.eat(tt.semi) && !this.eat(tt.comma) && this.type !== tt.braceR) {
this.unexpected()
}
}

View File

@@ -1,658 +0,0 @@
var acorn = require("../src/index")
var tt = acorn.tokTypes;
var tc = acorn.tokContexts;
tc.j_oTag = new acorn.TokContext("<tag", false);
tc.j_cTag = new acorn.TokContext("</tag", false);
tc.j_expr = new acorn.TokContext("<tag>...</tag>", true, true);
tt.jsxName = new acorn.TokenType("jsxName");
tt.jsxText = new acorn.TokenType("jsxText", {beforeExpr: true});
tt.jsxTagStart = new acorn.TokenType("jsxTagStart");
tt.jsxTagEnd = new acorn.TokenType("jsxTagEnd");
tt.jsxTagStart.updateContext = function() {
this.context.push(tc.j_expr); // treat as beginning of JSX expression
this.context.push(tc.j_oTag); // start opening tag context
this.exprAllowed = false;
};
tt.jsxTagEnd.updateContext = function(prevType) {
var out = this.context.pop();
if (out === tc.j_oTag && prevType === tt.slash || out === tc.j_cTag) {
this.context.pop();
this.exprAllowed = this.curContext() === tc.j_expr;
} else {
this.exprAllowed = true;
}
};
var pp = acorn.Parser.prototype;
// Reads inline JSX contents token.
pp.jsx_readToken = function() {
var out = "", chunkStart = this.pos;
for (;;) {
if (this.pos >= this.input.length)
this.raise(this.start, "Unterminated JSX contents");
var ch = this.input.charCodeAt(this.pos);
switch (ch) {
case 60: // '<'
case 123: // '{'
if (this.pos === this.start) {
if (ch === 60 && this.exprAllowed) {
++this.pos;
return this.finishToken(tt.jsxTagStart);
}
return this.getTokenFromCode(ch);
}
out += this.input.slice(chunkStart, this.pos);
return this.finishToken(tt.jsxText, out);
case 38: // '&'
out += this.input.slice(chunkStart, this.pos);
out += this.jsx_readEntity();
chunkStart = this.pos;
break;
default:
if (acorn.isNewLine(ch)) {
out += this.input.slice(chunkStart, this.pos);
++this.pos;
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
++this.pos;
out += "\n";
} else {
out += String.fromCharCode(ch);
}
if (this.options.locations) {
++this.curLine;
this.lineStart = this.pos;
}
chunkStart = this.pos;
} else {
++this.pos;
}
}
}
};
pp.jsx_readString = function(quote) {
var out = "", chunkStart = ++this.pos;
for (;;) {
if (this.pos >= this.input.length)
this.raise(this.start, "Unterminated string constant");
var ch = this.input.charCodeAt(this.pos);
if (ch === quote) break;
if (ch === 38) { // '&'
out += this.input.slice(chunkStart, this.pos);
out += this.jsx_readEntity();
chunkStart = this.pos;
} else {
++this.pos;
}
}
out += this.input.slice(chunkStart, this.pos++);
return this.finishToken(tt.string, out);
};
var XHTMLEntities = {
quot: '\u0022',
amp: '&',
apos: '\u0027',
lt: '<',
gt: '>',
nbsp: '\u00A0',
iexcl: '\u00A1',
cent: '\u00A2',
pound: '\u00A3',
curren: '\u00A4',
yen: '\u00A5',
brvbar: '\u00A6',
sect: '\u00A7',
uml: '\u00A8',
copy: '\u00A9',
ordf: '\u00AA',
laquo: '\u00AB',
not: '\u00AC',
shy: '\u00AD',
reg: '\u00AE',
macr: '\u00AF',
deg: '\u00B0',
plusmn: '\u00B1',
sup2: '\u00B2',
sup3: '\u00B3',
acute: '\u00B4',
micro: '\u00B5',
para: '\u00B6',
middot: '\u00B7',
cedil: '\u00B8',
sup1: '\u00B9',
ordm: '\u00BA',
raquo: '\u00BB',
frac14: '\u00BC',
frac12: '\u00BD',
frac34: '\u00BE',
iquest: '\u00BF',
Agrave: '\u00C0',
Aacute: '\u00C1',
Acirc: '\u00C2',
Atilde: '\u00C3',
Auml: '\u00C4',
Aring: '\u00C5',
AElig: '\u00C6',
Ccedil: '\u00C7',
Egrave: '\u00C8',
Eacute: '\u00C9',
Ecirc: '\u00CA',
Euml: '\u00CB',
Igrave: '\u00CC',
Iacute: '\u00CD',
Icirc: '\u00CE',
Iuml: '\u00CF',
ETH: '\u00D0',
Ntilde: '\u00D1',
Ograve: '\u00D2',
Oacute: '\u00D3',
Ocirc: '\u00D4',
Otilde: '\u00D5',
Ouml: '\u00D6',
times: '\u00D7',
Oslash: '\u00D8',
Ugrave: '\u00D9',
Uacute: '\u00DA',
Ucirc: '\u00DB',
Uuml: '\u00DC',
Yacute: '\u00DD',
THORN: '\u00DE',
szlig: '\u00DF',
agrave: '\u00E0',
aacute: '\u00E1',
acirc: '\u00E2',
atilde: '\u00E3',
auml: '\u00E4',
aring: '\u00E5',
aelig: '\u00E6',
ccedil: '\u00E7',
egrave: '\u00E8',
eacute: '\u00E9',
ecirc: '\u00EA',
euml: '\u00EB',
igrave: '\u00EC',
iacute: '\u00ED',
icirc: '\u00EE',
iuml: '\u00EF',
eth: '\u00F0',
ntilde: '\u00F1',
ograve: '\u00F2',
oacute: '\u00F3',
ocirc: '\u00F4',
otilde: '\u00F5',
ouml: '\u00F6',
divide: '\u00F7',
oslash: '\u00F8',
ugrave: '\u00F9',
uacute: '\u00FA',
ucirc: '\u00FB',
uuml: '\u00FC',
yacute: '\u00FD',
thorn: '\u00FE',
yuml: '\u00FF',
OElig: '\u0152',
oelig: '\u0153',
Scaron: '\u0160',
scaron: '\u0161',
Yuml: '\u0178',
fnof: '\u0192',
circ: '\u02C6',
tilde: '\u02DC',
Alpha: '\u0391',
Beta: '\u0392',
Gamma: '\u0393',
Delta: '\u0394',
Epsilon: '\u0395',
Zeta: '\u0396',
Eta: '\u0397',
Theta: '\u0398',
Iota: '\u0399',
Kappa: '\u039A',
Lambda: '\u039B',
Mu: '\u039C',
Nu: '\u039D',
Xi: '\u039E',
Omicron: '\u039F',
Pi: '\u03A0',
Rho: '\u03A1',
Sigma: '\u03A3',
Tau: '\u03A4',
Upsilon: '\u03A5',
Phi: '\u03A6',
Chi: '\u03A7',
Psi: '\u03A8',
Omega: '\u03A9',
alpha: '\u03B1',
beta: '\u03B2',
gamma: '\u03B3',
delta: '\u03B4',
epsilon: '\u03B5',
zeta: '\u03B6',
eta: '\u03B7',
theta: '\u03B8',
iota: '\u03B9',
kappa: '\u03BA',
lambda: '\u03BB',
mu: '\u03BC',
nu: '\u03BD',
xi: '\u03BE',
omicron: '\u03BF',
pi: '\u03C0',
rho: '\u03C1',
sigmaf: '\u03C2',
sigma: '\u03C3',
tau: '\u03C4',
upsilon: '\u03C5',
phi: '\u03C6',
chi: '\u03C7',
psi: '\u03C8',
omega: '\u03C9',
thetasym: '\u03D1',
upsih: '\u03D2',
piv: '\u03D6',
ensp: '\u2002',
emsp: '\u2003',
thinsp: '\u2009',
zwnj: '\u200C',
zwj: '\u200D',
lrm: '\u200E',
rlm: '\u200F',
ndash: '\u2013',
mdash: '\u2014',
lsquo: '\u2018',
rsquo: '\u2019',
sbquo: '\u201A',
ldquo: '\u201C',
rdquo: '\u201D',
bdquo: '\u201E',
dagger: '\u2020',
Dagger: '\u2021',
bull: '\u2022',
hellip: '\u2026',
permil: '\u2030',
prime: '\u2032',
Prime: '\u2033',
lsaquo: '\u2039',
rsaquo: '\u203A',
oline: '\u203E',
frasl: '\u2044',
euro: '\u20AC',
image: '\u2111',
weierp: '\u2118',
real: '\u211C',
trade: '\u2122',
alefsym: '\u2135',
larr: '\u2190',
uarr: '\u2191',
rarr: '\u2192',
darr: '\u2193',
harr: '\u2194',
crarr: '\u21B5',
lArr: '\u21D0',
uArr: '\u21D1',
rArr: '\u21D2',
dArr: '\u21D3',
hArr: '\u21D4',
forall: '\u2200',
part: '\u2202',
exist: '\u2203',
empty: '\u2205',
nabla: '\u2207',
isin: '\u2208',
notin: '\u2209',
ni: '\u220B',
prod: '\u220F',
sum: '\u2211',
minus: '\u2212',
lowast: '\u2217',
radic: '\u221A',
prop: '\u221D',
infin: '\u221E',
ang: '\u2220',
and: '\u2227',
or: '\u2228',
cap: '\u2229',
cup: '\u222A',
'int': '\u222B',
there4: '\u2234',
sim: '\u223C',
cong: '\u2245',
asymp: '\u2248',
ne: '\u2260',
equiv: '\u2261',
le: '\u2264',
ge: '\u2265',
sub: '\u2282',
sup: '\u2283',
nsub: '\u2284',
sube: '\u2286',
supe: '\u2287',
oplus: '\u2295',
otimes: '\u2297',
perp: '\u22A5',
sdot: '\u22C5',
lceil: '\u2308',
rceil: '\u2309',
lfloor: '\u230A',
rfloor: '\u230B',
lang: '\u2329',
rang: '\u232A',
loz: '\u25CA',
spades: '\u2660',
clubs: '\u2663',
hearts: '\u2665',
diams: '\u2666'
};
var hexNumber = /^[\da-fA-F]+$/;
var decimalNumber = /^\d+$/;
pp.jsx_readEntity = function() {
var str = "", count = 0, entity;
var ch = this.input[this.pos];
if (ch !== "&")
this.raise(this.pos, "Entity must start with an ampersand");
var startPos = ++this.pos;
while (this.pos < this.input.length && count++ < 10) {
ch = this.input[this.pos++];
if (ch === ";") {
if (str[0] === "#") {
if (str[1] === "x") {
str = str.substr(2);
if (hexNumber.test(str))
entity = String.fromCharCode(parseInt(str, 16));
} else {
str = str.substr(1);
if (decimalNumber.test(str))
entity = String.fromCharCode(parseInt(str, 10));
}
} else {
entity = XHTMLEntities[str];
}
break;
}
str += ch;
}
if (!entity) {
this.pos = startPos;
return "&";
}
return entity;
};
// Read a JSX identifier (valid tag or attribute name).
//
// Optimized version since JSX identifiers can't contain
// escape characters and so can be read as single slice.
// Also assumes that first character was already checked
// by isIdentifierStart in readToken.
pp.jsx_readWord = function() {
var ch, start = this.pos;
do {
ch = this.input.charCodeAt(++this.pos);
} while (acorn.isIdentifierChar(ch) || ch === 45); // '-'
return this.finishToken(tt.jsxName, this.input.slice(start, this.pos));
};
// Transforms JSX element name to string.
function getQualifiedJSXName(object) {
if (object.type === "JSXIdentifier")
return object.name;
if (object.type === "JSXNamespacedName")
return object.namespace.name + ':' + object.name.name;
if (object.type === "JSXMemberExpression")
return getQualifiedJSXName(object.object) + '.' +
getQualifiedJSXName(object.property);
}
// Parse next token as JSX identifier
pp.jsx_parseIdentifier = function() {
var node = this.startNode();
if (this.type === tt.jsxName)
node.name = this.value;
else if (this.type.keyword)
node.name = this.type.keyword;
else
this.unexpected();
this.next();
return this.finishNode(node, "JSXIdentifier");
};
// Parse namespaced identifier.
pp.jsx_parseNamespacedName = function() {
var start = this.markPosition();
var name = this.jsx_parseIdentifier();
if (!this.eat(tt.colon)) return name;
var node = this.startNodeAt(start);
node.namespace = name;
node.name = this.jsx_parseIdentifier();
return this.finishNode(node, "JSXNamespacedName");
};
// Parses element name in any form - namespaced, member
// or single identifier.
pp.jsx_parseElementName = function() {
var start = this.markPosition();
var node = this.jsx_parseNamespacedName();
while (this.eat(tt.dot)) {
var newNode = this.startNodeAt(start);
newNode.object = node;
newNode.property = this.jsx_parseIdentifier();
node = this.finishNode(newNode, "JSXMemberExpression");
}
return node;
};
// Parses any type of JSX attribute value.
pp.jsx_parseAttributeValue = function() {
switch (this.type) {
case tt.braceL:
var node = this.jsx_parseExpressionContainer();
if (node.expression.type === "JSXEmptyExpression")
this.raise(node.start, "JSX attributes must only be assigned a non-empty expression");
return node;
case tt.jsxTagStart:
case tt.string:
return this.parseExprAtom();
default:
this.raise(this.start, "JSX value should be either an expression or a quoted JSX text");
}
};
// JSXEmptyExpression is unique type since it doesn't actually parse anything,
// and so it should start at the end of last read token (left brace) and finish
// at the beginning of the next one (right brace).
pp.jsx_parseEmptyExpression = function() {
var tmp = this.start;
this.start = this.lastTokEnd;
this.lastTokEnd = tmp;
tmp = this.startLoc;
this.startLoc = this.lastTokEndLoc;
this.lastTokEndLoc = tmp;
return this.finishNode(this.startNode(), "JSXEmptyExpression");
};
// Parses JSX expression enclosed into curly brackets.
pp.jsx_parseExpressionContainer = function() {
var node = this.startNode();
this.next();
node.expression = this.type === tt.braceR
? this.jsx_parseEmptyExpression()
: this.parseExpression();
this.expect(tt.braceR);
return this.finishNode(node, "JSXExpressionContainer");
};
// Parses following JSX attribute name-value pair.
pp.jsx_parseAttribute = function() {
var node = this.startNode();
if (this.eat(tt.braceL)) {
this.expect(tt.ellipsis);
node.argument = this.parseMaybeAssign();
this.expect(tt.braceR);
return this.finishNode(node, "JSXSpreadAttribute");
}
node.name = this.jsx_parseNamespacedName();
node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
return this.finishNode(node, "JSXAttribute");
};
// Parses JSX opening tag starting after '<'.
pp.jsx_parseOpeningElementAt = function(start) {
var node = this.startNodeAt(start);
node.attributes = [];
node.name = this.jsx_parseElementName();
while (this.type !== tt.slash && this.type !== tt.jsxTagEnd)
node.attributes.push(this.jsx_parseAttribute());
node.selfClosing = this.eat(tt.slash);
this.expect(tt.jsxTagEnd);
return this.finishNode(node, "JSXOpeningElement");
};
// Parses JSX closing tag starting after '</'.
pp.jsx_parseClosingElementAt = function(start) {
var node = this.startNodeAt(start);
node.name = this.jsx_parseElementName();
this.expect(tt.jsxTagEnd);
return this.finishNode(node, "JSXClosingElement");
};
// Parses entire JSX element, including it's opening tag
// (starting after '<'), attributes, contents and closing tag.
pp.jsx_parseElementAt = function(start) {
var node = this.startNodeAt(start);
var children = [];
var openingElement = this.jsx_parseOpeningElementAt(start);
var closingElement = null;
if (!openingElement.selfClosing) {
contents: for (;;) {
switch (this.type) {
case tt.jsxTagStart:
start = this.markPosition();
this.next();
if (this.eat(tt.slash)) {
closingElement = this.jsx_parseClosingElementAt(start);
break contents;
}
children.push(this.jsx_parseElementAt(start));
break;
case tt.jsxText:
children.push(this.parseExprAtom());
break;
case tt.braceL:
children.push(this.jsx_parseExpressionContainer());
break;
default:
this.unexpected();
}
}
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name))
this.raise(
closingElement.start,
"Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">");
}
node.openingElement = openingElement;
node.closingElement = closingElement;
node.children = children;
return this.finishNode(node, "JSXElement");
};
// Parses entire JSX element from current position.
pp.jsx_parseElement = function() {
var start = this.markPosition();
this.next();
return this.jsx_parseElementAt(start);
};
acorn.plugins.jsx = function(instance) {
instance.extend("parseExprAtom", function(inner) {
return function(refShortHandDefaultPos) {
if (this.type === tt.jsxText)
return this.parseLiteral(this.value);
else if (this.type === tt.jsxTagStart)
return this.jsx_parseElement();
else
return inner.call(this, refShortHandDefaultPos);
};
});
instance.extend("readToken", function(inner) {
return function(code) {
var context = this.curContext();
if (context === tc.j_expr) return this.jsx_readToken();
if (context === tc.j_oTag || context === tc.j_cTag) {
if (acorn.isIdentifierStart(code)) return this.jsx_readWord();
if (code == 62) {
++this.pos;
return this.finishToken(tt.jsxTagEnd);
}
if ((code === 34 || code === 39) && context == tc.j_oTag)
return this.jsx_readString(code);
}
if (code === 60 && this.exprAllowed) {
++this.pos;
return this.finishToken(tt.jsxTagStart);
}
return inner.call(this, code);
};
});
instance.extend("updateContext", function(inner) {
return function(prevType) {
if (this.type == tt.braceL) {
var curContext = this.curContext();
if (curContext == tc.j_oTag) this.context.push(tc.b_expr);
else if (curContext == tc.j_expr) this.context.push(tc.b_tmpl);
else inner.call(this, prevType);
this.exprAllowed = true;
} else if (this.type === tt.slash && prevType === tt.jsxTagStart) {
this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
this.context.push(tc.j_cTag); // reconsider as closing tag context
this.exprAllowed = false;
} else {
return inner.call(this, prevType);
}
};
});
}

View File

@@ -1,3 +1,4 @@
require("./node");
var transform = module.exports = require("../transformation");
transform.options = require("../transformation/file/options");

View File

@@ -5,10 +5,12 @@ import * as util from "../util";
import fs from "fs";
export { util, acorn, transform };
export { pipeline } from "../transformation";
export { canCompile } from "../util";
export { default as options } from "../transformation/file/options";
export { default as Transformer } from "../transformation/transformer";
export { default as TransformerPipeline } from "../transformation/transformer-pipeline";
export { default as traverse } from "../traversal";
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
export { version } from "../../../package";
@@ -51,10 +53,11 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
export function transformFileSync(filename: string, opts?: Object = {}) {
opts.filename = filename;
return transform(fs.readFileSync(filename), opts);
return transform(fs.readFileSync(filename, "utf8"), opts);
}
export function parse(code, opts = {}) {
opts.allowHashBang = true;
opts.sourceType = "module";
opts.ecmaVersion = Infinity;
opts.plugins = {
@@ -63,7 +66,7 @@ export function parse(code, opts = {}) {
};
opts.features = {};
for (var key in transform.transformers) {
for (var key in transform.pipeline.transformers) {
opts.features[key] = true;
}

View File

@@ -87,7 +87,7 @@ var shouldIgnore = function (filename) {
var istanbulMonkey = {};
if (process.env.running_under_istanbul) { // jshint ignore:line
if (process.env.running_under_istanbul) {
// we need to monkey patch fs.readFileSync so we can hook into
// what istanbul gets, it's extremely dirty but it's the only way
var _readFileSync = fs.readFileSync;
@@ -117,7 +117,7 @@ var registerExtension = function (ext) {
var old = oldHandlers[ext] || oldHandlers[".js"];
var loader = normalLoader;
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
if (process.env.running_under_istanbul) loader = istanbulLoader;
require.extensions[ext] = function (m, filename) {
if (shouldIgnore(filename)) {

View File

@@ -37,7 +37,7 @@ class CodeGenerator {
retainLines: opts.retainLines,
comments: opts.comments == null || opts.comments,
compact: opts.compact,
quotes: CodeGenerator.findCommonStringDelimeter(code, tokens),
quotes: CodeGenerator.findCommonStringDelimiter(code, tokens),
indent: {
adjustMultilineComment: true,
style: style,
@@ -56,7 +56,7 @@ class CodeGenerator {
return format;
}
static findCommonStringDelimeter(code, tokens) {
static findCommonStringDelimiter(code, tokens) {
var occurences = {
single: 0,
double: 0
@@ -232,14 +232,14 @@ class CodeGenerator {
this.map.mark(node, "end");
if (opts.after) opts.after();
this.format.concise = oldConcise;
newline(false);
this.printTrailingComments(node, parent);
} else {
throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
}
this.format.concise = oldConcise;
}
printJoin(print, nodes, opts = {}) {

View File

@@ -1,65 +1,34 @@
import normalizeAst from "./normalize-ast";
import estraverse from "estraverse";
import codeFrame from "./code-frame";
import * as acorn from "../../acorn";
export default function (opts, code, callback) {
try {
var comments = [];
var tokens = [];
export default function (code, opts = {}) {
var comments = [];
var tokens = [];
var parseOpts = {
allowImportExportEverywhere: opts.looseModules,
allowReturnOutsideFunction: opts.looseModules,
ecmaVersion: 6,
strictMode: opts.strictMode,
sourceType: opts.sourceType,
onComment: comments,
locations: true,
features: opts.features || {},
plugins: opts.plugins || {},
onToken: tokens,
ranges: true
};
var parseOpts = {
allowImportExportEverywhere: opts.looseModules,
allowReturnOutsideFunction: opts.looseModules,
allowHashBang: true,
ecmaVersion: 6,
strictMode: opts.strictMode,
sourceType: opts.sourceType,
locations: true,
onComment: comments,
features: opts.features || {},
plugins: opts.plugins || {},
onToken: tokens,
ranges: true
};
if (opts.nonStandard) {
parseOpts.plugins.jsx = true;
parseOpts.plugins.flow = true;
}
var ast = acorn.parse(code, parseOpts);
estraverse.attachComments(ast, comments, tokens);
ast = normalizeAst(ast, comments, tokens);
if (callback) {
return callback(ast);
} else {
return ast;
}
} catch (err) {
if (!err._babel) {
err._babel = true;
var message = err.message = `${opts.filename}: ${err.message}`;
var loc = err.loc;
if (loc) {
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, opts);
message += "\n" + err.codeFrame;
}
if (err.stack) {
var newStack = err.stack.replace(err.message, message);
try {
err.stack = newStack;
} catch (e) {
// `err.stack` may be a readonly property in some environments
}
}
}
throw err;
if (opts.nonStandard) {
parseOpts.plugins.jsx = true;
parseOpts.plugins.flow = true;
}
};
var ast = acorn.parse(code, parseOpts);
estraverse.attachComments(ast, comments, tokens);
ast = normalizeAst(ast, comments, tokens);
return ast;
}

View File

@@ -1,5 +1,6 @@
import convertSourceMap from "convert-source-map";
import * as optionParsers from "./option-parsers";
import moduleFormatters from "../modules";
import PluginManager from "./plugin-manager";
import shebangRegex from "shebang-regex";
import TraversalPath from "../../traversal/path";
@@ -9,6 +10,7 @@ import resolveRc from "../../tools/resolve-rc";
import sourceMap from "source-map";
import transform from "./../index";
import generate from "../../generation";
import codeFrame from "../../helpers/code-frame";
import defaults from "lodash/object/defaults";
import includes from "lodash/collection/includes";
import traverse from "../../traversal";
@@ -38,7 +40,7 @@ function checkPath(stack, path) {
}
export default class File {
constructor(opts = {}) {
constructor(opts = {}, pipeline) {
this.dynamicImportTypes = {};
this.dynamicImportIds = {};
this.dynamicImports = [];
@@ -49,9 +51,10 @@ export default class File {
this.data = {};
this.uids = {};
this.log = new Logger(this, opts.filename || "unknown");
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.pipeline = pipeline;
this.log = new Logger(this, opts.filename || "unknown");
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
}
@@ -133,7 +136,7 @@ export default class File {
}
var optionParser = optionParsers[option.type];
if (optionParser) val = optionParser(key, val);
if (optionParser) val = optionParser(key, val, this.pipeline);
if (option.alias) {
opts[option.alias] = opts[option.alias] || val;
@@ -200,7 +203,7 @@ export default class File {
var stack = [];
// build internal transformers
each(transform.transformers, function (transformer, key) {
each(this.pipeline.transformers, function (transformer, key) {
var pass = transformers[key] = transformer.buildPass(file);
if (pass.canTransform()) {
@@ -234,48 +237,6 @@ export default class File {
this.transformerStack = stack.concat(secondaryStack);
}
getModuleFormatter(type: string) {
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolveRelative(type);
if (loc) ModuleFormatter = require(loc);
}
if (!ModuleFormatter) {
throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`);
}
return new ModuleFormatter(this);
}
parseInputSourceMap(code: string) {
var opts = this.opts;
if (opts.inputSourceMap !== false) {
var inputMap = convertSourceMap.fromSource(code);
if (inputMap) {
opts.inputSourceMap = inputMap.toObject();
code = convertSourceMap.removeComments(code);
}
}
return code;
}
parseShebang(code: string) {
var shebangMatch = shebangRegex.exec(code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
// remove shebang
code = code.replace(shebangRegex, "");
}
return code;
}
set(key: string, val): any {
return this.data[key] = val;
};
@@ -368,13 +329,24 @@ export default class File {
}
var ref = util.template("helper-" + name);
ref._compact = true;
var uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
this.scope.push({
id: uid,
init: ref,
unique: true
});
if (t.isFunctionExpression(ref) && !ref.id) {
ref.body._compact = true;
ref._generated = true;
ref.id = uid;
ref.type = "FunctionDeclaration";
this.path.unshiftContainer("body", ref);
} else {
ref._compact = true;
this.scope.push({
id: uid,
init: ref,
unique: true
});
}
return uid;
}
@@ -385,110 +357,6 @@ export default class File {
return err;
}
addCode(code: string) {
code = (code || "") + "";
code = this.parseInputSourceMap(code);
this.code = code;
return this.parseShebang(code);
}
shouldIgnore() {
var opts = this.opts;
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
}
parse(code: string) {
if (this.shouldIgnore()) {
return {
metadata: {},
code: code,
map: null,
ast: null
};
}
code = this.addCode(code);
var opts = this.opts;
//
var parseOpts = {
highlightCode: opts.highlightCode,
nonStandard: opts.nonStandard,
filename: opts.filename,
plugins: {}
};
var features = parseOpts.features = {};
for (var key in this.transformers) {
var transformer = this.transformers[key];
features[key] = transformer.canTransform();
}
parseOpts.looseModules = this.isLoose("es6.modules");
parseOpts.strictMode = features.strict;
parseOpts.sourceType = "module";
this.log.debug("Parse start");
//
return parse(parseOpts, code, (tree) => {
this.log.debug("Parse stop");
this.transform(tree);
return this.generate();
});
}
setAst(ast) {
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
this.scope = this.path.scope;
this.ast = ast;
this.path.traverse({
enter(node, parent, scope) {
if (this.isScope()) {
for (var key in scope.bindings) {
scope.bindings[key].setTypeAnnotation();
}
}
}
});
}
transform(ast) {
this.log.debug("Start set AST");
this.setAst(ast);
this.log.debug("End set AST");
this.log.debug("Start prepass");
this.checkPath(this.path);
this.log.debug("End prepass");
this.log.debug("Start module formatter init");
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
modFormatter.init();
}
this.log.debug("End module formatter init");
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
this.call("post");
}
call(key: string) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
var fn = transformer[key];
if (fn) fn(this);
}
}
checkPath(path) {
if (Array.isArray(path)) {
for (var i = 0; i < path.length; i++) {
@@ -528,6 +396,180 @@ export default class File {
return map;
}
getModuleFormatter(type: string) {
var ModuleFormatter = isFunction(type) ? type : moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolveRelative(type);
if (loc) ModuleFormatter = require(loc);
}
if (!ModuleFormatter) {
throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`);
}
return new ModuleFormatter(this);
}
parse(code: string) {
var opts = this.opts;
//
var parseOpts = {
highlightCode: opts.highlightCode,
nonStandard: opts.nonStandard,
filename: opts.filename,
plugins: {}
};
var features = parseOpts.features = {};
for (var key in this.transformers) {
var transformer = this.transformers[key];
features[key] = transformer.canTransform();
}
parseOpts.looseModules = this.isLoose("es6.modules");
parseOpts.strictMode = features.strict;
parseOpts.sourceType = "module";
this.log.debug("Parse start");
var tree = parse(code, parseOpts);
this.log.debug("Parse stop");
return tree;
}
_addAst(ast) {
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
this.scope = this.path.scope;
this.ast = ast;
this.path.traverse({
enter(node, parent, scope) {
if (this.isScope()) {
for (var key in scope.bindings) {
scope.bindings[key].setTypeAnnotation();
}
}
}
});
}
addAst(ast) {
this.log.debug("Start set AST");
this._addAst(ast);
this.log.debug("End set AST");
this.log.debug("Start prepass");
this.checkPath(this.path);
this.log.debug("End prepass");
this.log.debug("Start module formatter init");
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
modFormatter.init();
}
this.log.debug("End module formatter init");
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
this.call("post");
}
wrap(code, callback) {
code = code + "";
try {
if (this.shouldIgnore()) {
return {
metadata: {},
code: code,
map: null,
ast: null
};
}
callback();
return this.generate();
} catch (err) {
if (err._babel) {
throw err;
} else {
err._babel = true;
}
var message = err.message = `${this.opts.filename}: ${err.message}`;
var loc = err.loc;
if (loc) {
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, this.opts);
message += "\n" + err.codeFrame;
}
if (err.stack) {
var newStack = err.stack.replace(err.message, message);
try {
err.stack = newStack;
} catch (e) {
// `err.stack` may be a readonly property in some environments
}
}
throw err;
}
}
addCode(code: string, parseCode?) {
code = (code || "") + "";
code = this.parseInputSourceMap(code);
this.code = code;
if (parseCode) {
this.parseShebang();
this.addAst(this.parse(this.code));
}
}
shouldIgnore() {
var opts = this.opts;
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
}
call(key: string) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
var fn = transformer[key];
if (fn) fn(this);
}
}
parseInputSourceMap(code: string) {
var opts = this.opts;
if (opts.inputSourceMap !== false) {
var inputMap = convertSourceMap.fromSource(code);
if (inputMap) {
opts.inputSourceMap = inputMap.toObject();
code = convertSourceMap.removeComments(code);
}
}
return code;
}
parseShebang() {
var shebangMatch = shebangRegex.exec(this.code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
this.code = this.code.replace(shebangRegex, "");
}
}
generate(): {
usedHelpers?: Array<string>;
code: string;

View File

@@ -1,14 +1,13 @@
import transform from "./../index";
import * as util from "../../util";
export function transformerList(key, val) {
export function transformerList(key, val, pipeline) {
val = util.arrayify(val);
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
val = Object.keys(transform.transformers);
val = Object.keys(pipeline.transformers);
}
return transform._ensureTransformerNames(key, val);
return pipeline._ensureTransformerNames(key, val);
}
export function number(key, val) {

View File

@@ -25,6 +25,10 @@
"type": "string"
},
"getModuleName": {
"hidden": true
},
"retainLines": {
"hidden": true,
"type": "boolean",

View File

@@ -1,3 +1,4 @@
import * as node from "../../api/node";
import * as messages from "../../messages";
import * as util from "../../util";

View File

@@ -1,68 +1,34 @@
import normalizeAst from "../helpers/normalize-ast";
import Transformer from "./transformer";
import object from "../helpers/object";
import File from "./file";
import each from "lodash/collection/each";
import Pipeline from "./transformer-pipeline";
export default function transform(code: string, opts?: Object) {
var file = new File(opts);
return file.parse(code);
}
var pipeline = new Pipeline;
transform.fromAst = function (ast, code, opts) {
ast = normalizeAst(ast);
//
var file = new File(opts);
file.addCode(code);
file.transform(ast);
return file.generate();
};
import transformers from "./transformers";
pipeline.addTransformers(transformers);
transform._ensureTransformerNames = function (type: string, rawKeys: Array<string>) {
var keys = [];
//
for (var i = 0; i < rawKeys.length; i++) {
var key = rawKeys[i];
import deprecated from "./transformers/deprecated";
pipeline.addDeprecated(deprecated);
var deprecatedKey = transform.deprecatedTransformerMap[key];
var aliasKey = transform.aliasTransformerMap[key];
if (aliasKey) {
keys.push(aliasKey);
} else if (deprecatedKey) {
// deprecated key, remap it to the new one
console.error(`The transformer ${key} has been renamed to ${deprecatedKey}`);
rawKeys.push(deprecatedKey);
} else if (transform.transformers[key]) {
// valid key
keys.push(key);
} else if (transform.namespaces[key]) {
// namespace, append all transformers within this namespace
keys = keys.concat(transform.namespaces[key]);
} else {
// invalid key
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
}
}
//
return keys;
};
import aliases from "./transformers/aliases";
pipeline.addAliases(aliases);
transform.transformerNamespaces = object();
transform.transformers = object();
transform.namespaces = object();
//
transform.deprecatedTransformerMap = require("./transformers/deprecated");
transform.aliasTransformerMap = require("./transformers/aliases");
transform.moduleFormatters = require("./modules");
import * as filters from "./transformers/filters";
pipeline.addFilter(filters.internal);
pipeline.addFilter(filters.blacklist);
pipeline.addFilter(filters.whitelist);
pipeline.addFilter(filters.stage);
pipeline.addFilter(filters.optional);
import rawTransformers from "./transformers";
//
each(rawTransformers, function (transformer, key) {
var namespace = key.split(".")[0];
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
transform.namespaces[namespace].push(key);
transform.transformerNamespaces[key] = namespace;
transform.transformers[key] = new Transformer(key, transformer);
});
var transform = pipeline.transform.bind(pipeline);
transform.fromAst = pipeline.transformFromAst.bind(pipeline);
transform.pipeline = pipeline;
export default transform;

View File

@@ -8,7 +8,8 @@ import * as t from "../../types";
var remapVisitor = {
enter(node, parent, scope, formatter) {
var remap = formatter.internalRemap[node.name];
if (this.isReferencedIdentifier() && remap) {
if (this.isReferencedIdentifier() && remap && node !== remap) {
if (!scope.hasBinding(node.name) || scope.bindingIdentifierEquals(node.name, formatter.localImports[node.name])) {
return remap;
}
@@ -184,7 +185,10 @@ export default class DefaultFormatter {
getModuleName() {
var opts = this.file.opts;
if (opts.moduleId) return opts.moduleId;
// moduleId is n/a if a `getModuleName()` is provided
if (opts.moduleId && !opts.getModuleName) {
return opts.moduleId;
}
var filenameRelative = opts.filenameRelative;
var moduleName = "";
@@ -213,7 +217,13 @@ export default class DefaultFormatter {
// normalize path separators
moduleName = moduleName.replace(/\\/g, "/");
return moduleName;
if (opts.getModuleName) {
// If return is falsy, assume they want us to use
// our generated default name
return opts.getModuleName(moduleName) || moduleName;
} else {
return moduleName;
}
}
_pushStatement(ref, nodes) {

View File

@@ -23,7 +23,7 @@ export default class AMDFormatter extends DefaultFormatter {
*/
transform(program) {
DefaultFormatter.prototype.transform.apply(this, arguments);
CommonFormatter.prototype.transform.apply(this, arguments);
var body = program.body;
@@ -108,12 +108,16 @@ export default class AMDFormatter extends DefaultFormatter {
exportSpecifier(specifier, node, nodes) {
if (this.doDefaultExportInterop(specifier)) {
this.passModuleArg = true;
nodes.push(util.template("exports-default-assign", {
VALUE: specifier.local
}, true));
} else {
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
if (specifier.exported !== specifier.local && !node.source) {
nodes.push(util.template("exports-default-assign", {
VALUE: specifier.local
}, true));
return;
}
}
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
}
exportDeclaration(node, nodes) {

View File

@@ -17,30 +17,7 @@ export default class TransformerPass {
}
canTransform(): boolean {
var transformer = this.transformer;
var opts = this.file.opts;
var key = transformer.key;
// internal
if (key[0] === "_") return true;
// blacklist
var blacklist = opts.blacklist;
if (blacklist.length && includes(blacklist, key)) return false;
// whitelist
var whitelist = opts.whitelist;
if (whitelist) return includes(whitelist, key);
// stage
var stage = transformer.metadata.stage;
if (stage != null && stage >= opts.stage) return true;
// optional
if (transformer.metadata.optional && !includes(opts.optional, key)) return false;
return true;
return this.file.pipeline.canTransform(this.transformer, this.file.opts);
}
checkPath(path: TraversalPath): boolean {

View File

@@ -0,0 +1,103 @@
import Transformer from "./transformer";
import normalizeAst from "../helpers/normalize-ast";
import assign from "lodash/object/assign";
import object from "../helpers/object";
import File from "./file";
export default class TransformerPipeline {
constructor() {
this.transformers = object();
this.namespaces = object();
this.deprecated = object();
this.aliases = object();
this.filters = [];
}
addTransformers(transformers) {
for (var key in transformers) {
this.addTransformer(key, transformers[key]);
}
return this;
}
addTransformer(key, transformer) {
if (this.transformers[key]) throw new Error(); // todo: error
var namespace = key.split(".")[0];
this.namespaces[namespace] = this.namespaces[namespace] || [];
this.namespaces[namespace].push(key);
this.namespaces[key] = namespace;
this.transformers[key] = new Transformer(key, transformer);
}
addAliases(names) {
assign(this.aliases, names);
return this;
}
addDeprecated(names) {
assign(this.deprecated, names);
return this;
}
addFilter(filter: Function) {
this.filters.push(filter);
return this;
}
canTransform(transformer, fileOpts) {
for (var filter of (this.filters: Array)) {
var result = filter(transformer, fileOpts);
if (result != null) return result;
}
return true;
}
transform(code: string, opts?: Object) {
var file = new File(opts, this);
return file.wrap(code, function () {
file.addCode(code, true);
});
}
transformFromAst(ast, code, opts) {
ast = normalizeAst(ast);
var file = new File(opts, this);
return file.wrap(code, function () {
file.addCode(code);
file.addAst(ast);
});
}
_ensureTransformerNames(type: string, rawKeys: Array<string>) {
var keys = [];
for (var i = 0; i < rawKeys.length; i++) {
var key = rawKeys[i];
var deprecatedKey = this.deprecated[key];
var aliasKey = this.aliases[key];
if (aliasKey) {
keys.push(aliasKey);
} else if (deprecatedKey) {
// deprecated key, remap it to the new one
console.error(`[BABEL] The transformer ${key} has been renamed to ${deprecatedKey}`);
rawKeys.push(deprecatedKey);
} else if (this.transformers[key]) {
// valid key
keys.push(key);
} else if (this.namespaces[key]) {
// namespace, append all transformers within this namespace
keys = keys.concat(this.namespaces[key]);
} else {
// invalid key
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
}
}
return keys;
}
}

View File

@@ -15,7 +15,7 @@ import each from "lodash/collection/each";
*/
export default class Transformer {
constructor(transformerKey: string, transformer: Object, opts: Object) {
constructor(transformerKey: string, transformer: Object) {
transformer = assign({}, transformer);
var take = function (key) {
@@ -40,7 +40,6 @@ export default class Transformer {
//
this.handlers = this.normalize(transformer);
this.opts = this.opts || {};
this.key = transformerKey;
//

View File

@@ -5,7 +5,7 @@
"es6.symbols": "es6.spec.symbols",
"es6.blockScopingTDZ": "es6.spec.blockScoping",
"minification.deadCodeElimination": "utility.deadCodeElimination",
"utility.deadCodeElimination": "minification.deadCodeElimination",
"minification.removeConsoleCalls": "utility.removeConsole",
"minification.removeDebugger": "utility.removeDebugger"
}

View File

@@ -2,11 +2,7 @@ import * as t from "../../../types";
export function MemberExpression(node) {
var prop = node.property;
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
// foo["bar"] => foo.bar
node.property = t.identifier(prop.value);
node.computed = false;
} else if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
// foo.default -> foo["default"]
node.property = t.literal(prop.name);
node.computed = true;

View File

@@ -2,11 +2,7 @@ import * as t from "../../../types";
export function Property(node) {
var key = node.key;
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
// "foo": "bar" -> foo: "bar"
node.key = t.identifier(key.value);
node.computed = false;
} else if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
// default: "bar" -> "default": "bar"
node.key = t.literal(key.name);
}

View File

@@ -8,6 +8,4 @@ export function ArrowFunctionExpression(node) {
node.expression = false;
node.type = "FunctionExpression";
node.shadow = true;
return node;
}

View File

@@ -96,10 +96,6 @@ var verifyConstructorVisitor = traverse.explode({
if (state.hasSuper && !state.hasBareSuper) {
throw this.errorWithNode("'this' is not allowed before super()");
}
if (state.isNativeSuper) {
return state.nativeSuperRef;
}
}
}
});
@@ -154,15 +150,6 @@ class ClassTransformer {
//
var superClass = this.node.superClass;
this.isNativeSuper = superClass && t.isIdentifier(superClass) && t.NATIVE_TYPE_NAMES.indexOf(superClass.name) >= 0;
if (this.isNativeSuper) {
this.nativeSuperRef = this.scope.generateUidIdentifier("this");
}
//
var body = this.body;
//
@@ -234,12 +221,6 @@ class ClassTransformer {
}
}
if (this.isNativeSuper) {
// we've determined this is inheriting from a native class so return the constructed
// instance
constructorBody.body.push(t.returnStatement(this.nativeSuperRef));
}
if (this.className) {
// named class with only a constructor
if (body.length === 1) return t.toExpression(body[0]);
@@ -344,9 +325,7 @@ class ClassTransformer {
if (!this.hasConstructor && this.hasSuper) {
var helperName = "class-super-constructor-call";
if (this.isLoose) helperName += "-loose";
if (this.isNativeSuper) helperName = "class-super-native-constructor-call";
constructorBody.body.push(util.template(helperName, {
NATIVE_REF: this.nativeSuperRef,
CLASS_NAME: this.classRef,
SUPER_NAME: this.superName
}, true));
@@ -475,12 +454,10 @@ class ClassTransformer {
verifyConstructor(path: TraversalPath) {
var state = {
nativeSuperRef: this.nativeSuperRef,
isNativeSuper: this.isNativeSuper,
hasBareSuper: false,
bareSuper: null,
hasSuper: this.hasSuper,
file: this.file
hasBareSuper: false,
bareSuper: null,
hasSuper: this.hasSuper,
file: this.file
};
path.get("value").traverse(verifyConstructorVisitor, state);
@@ -490,22 +467,7 @@ class ClassTransformer {
if (!state.hasBareSuper && this.hasSuper) {
throw path.errorWithNode("Derived constructor must call super()");
}
if (this.isNativeSuper && this.bareSuper) {
this.bareSuper.replaceWithMultiple([
t.variableDeclaration("var", [
t.variableDeclarator(this.nativeSuperRef, t.newExpression(this.superName, this.bareSuper.node.arguments))
]),
t.expressionStatement(t.assignmentExpression(
"=",
t.memberExpression(this.nativeSuperRef, t.identifier("__proto__")),
t.memberExpression(this.classRef, t.identifier("prototype"))
)),
t.expressionStatement(this.nativeSuperRef)
]);
}
}
}
/**
* Push a method to its respective mutatorMap.
@@ -605,10 +567,6 @@ class ClassTransformer {
fnPath.scope.rename(this.classRef.name);
}
if (this.isNativeSuper) {
fnPath.traverse(constructorVisitor, this.nativeSuperRef);
}
var construct = this.constructor;
var fn = method.value;

View File

@@ -82,7 +82,7 @@ exports.Function = function (node, parent, scope, file) {
var block = node.body;
block.body = nodes.concat(block.body);
return node;
this.checkSelf();
};
export function CatchClause(node, parent, scope, file) {
@@ -104,7 +104,7 @@ export function CatchClause(node, parent, scope, file) {
node.body.body = nodes.concat(node.body.body);
return node;
this.checkSelf();
}
export function ExpressionStatement(node, parent, scope, file) {

View File

@@ -97,5 +97,5 @@ exports.Function = function (node, parent, scope, file) {
node.body.body = body.concat(node.body.body);
}
return node;
this.checkSelf();
};

View File

@@ -96,7 +96,8 @@ exports.Function = function (node, parent, scope, file) {
candidate.replaceWith(argsId);
optimizeMemberExpression(candidate.parent, node.params.length);
}
return node;
this.checkSelf();
return;
}
//
@@ -137,5 +138,5 @@ exports.Function = function (node, parent, scope, file) {
});
loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop);
return node;
this.checkSelf();
};

View File

@@ -16,27 +16,13 @@ function loose(node, body, objId) {
function spec(node, body, objId, initProps, file) {
var props = node.properties;
var prop, key;
// normalize key
for (var i = 0; i < props.length; i++) {
prop = props[i];
if (prop.kind !== "init") continue;
key = prop.key;
if (!prop.computed && t.isIdentifier(key)) {
prop.key = t.literal(key.name);
}
}
// add all non-computed properties and `__proto__` properties to the initializer
var broken = false;
for (i = 0; i < props.length; i++) {
prop = props[i];
for (let i = 0; i < props.length; i++) {
let prop = props[i];
if (prop.computed) {
broken = true;
@@ -51,24 +37,17 @@ function spec(node, body, objId, initProps, file) {
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
// otherwise use Object.defineProperty
for (i = 0; i < props.length; i++) {
prop = props[i];
for (let i = 0; i < props.length; i++) {
let prop = props[i];
if (!prop) continue;
key = prop.key;
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.addHelper("define-property"), [objId, key, prop.value]);
let key = prop.key;
if (t.isIdentifier(key) && !prop.computed) {
key = t.literal(key.name);
}
var bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
body.push(t.expressionStatement(bodyNode));
}

View File

@@ -33,3 +33,5 @@ export function BinaryExpression(node, parent, scope, file) {
export function VariableDeclaration(node) {
if (node._generated) this.skip();
}
export { VariableDeclaration as FunctionDeclaration };

View File

@@ -18,15 +18,7 @@ function returnBlock(expr) {
// looks for and replaces tail recursion calls
var firstPass = {
enter(node, parent, scope, state) {
if (this.isIfStatement()) {
if (this.get("alternate").isReturnStatement()) {
t.ensureBlock(node, "alternate");
}
if (this.get("consequent").isReturnStatement()) {
t.ensureBlock(node, "consequent");
}
} else if (this.isReturnStatement()) {
if (this.isReturnStatement()) {
this.skip();
return state.subTransform(node.argument);
} else if (t.isTryStatement(parent)) {

View File

@@ -0,0 +1,24 @@
import includes from "lodash/collection/includes";
export function internal(transformer, opts) {
if (transformer.key[0] === "_") return true;
}
export function blacklist(transformer, opts) {
var blacklist = opts.blacklist;
if (blacklist.length && includes(blacklist, transformer.key)) return false;
}
export function whitelist(transformer, opts) {
var whitelist = opts.whitelist;
if (whitelist) return includes(whitelist, transformer.key);
}
export function stage(transformer, opts) {
var stage = transformer.metadata.stage;
if (stage != null && stage >= opts.stage) return true;
}
export function optional(transformer, opts) {
if (transformer.metadata.optional && !includes(opts.optional, transformer.key)) return false;
}

View File

@@ -1,5 +1,6 @@
export default {
_modules: require("./internal/modules"),
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
"es7.classProperties": require("./es7/class-properties"),
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
@@ -113,7 +114,9 @@ export default {
"utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"),
"utility.inlineExpressions": require("./utility/inline-expressions"),
"utility.deadCodeElimination": require("./utility/dead-code-elimination"),
"minification.memberExpressionLiterals": require("./minification/member-expression-literals"),
"minification.propertyLiterals": require("./minification/property-literals"),
jscript: require("./other/jscript"),
flow: require("./other/flow")

View File

@@ -1,6 +1,4 @@
import groupBy from "lodash/collection/groupBy";
import flatten from "lodash/array/flatten";
import values from "lodash/object/values";
import sortBy from "lodash/collection/sortBy";
// Priority:
//
@@ -18,14 +16,14 @@ export var BlockStatement = {
}
if (!hasChange) return;
var nodePriorities = groupBy(node.body, function (bodyNode) {
node.body = sortBy(node.body, function(bodyNode){
var priority = bodyNode && bodyNode._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;
return priority;
});
node.body = flatten(values(nodePriorities).reverse());
// Higher priorities should move toward the top.
return -1 * priority;
});
}
};

View File

@@ -21,6 +21,38 @@ export var metadata = {
optional: true
};
export function Identifier(node, parent, scope) {
if (!this.isReferenced()) return;
var binding = scope.getBinding(node.name);
if (!binding || binding.references > 1 || !binding.constant) return;
var replacement = binding.path.node;
if (t.isVariableDeclarator(replacement)) {
replacement = replacement.init;
}
t.toExpression(replacement);
scope.removeBinding(node.name);
binding.path.remove();
return replacement;
}
export function FunctionDeclaration(node, parent, scope) {
var bindingInfo = scope.getBinding(node.id.name);
if (bindingInfo && !bindingInfo.referenced) {
this.remove();
}
}
export { FunctionDeclaration as ClassDeclaration };
export function VariableDeclarator(node, parent, scope) {
if (!t.isIdentifier(node.id) || !scope.isPure(node.init)) return;
FunctionDeclaration.apply(this, arguments);
}
export function ConditionalExpression(node, parent, scope) {
var evaluateTest = this.get("test").evaluateTruthy();
if (evaluateTest === true) {

View File

@@ -0,0 +1,14 @@
import * as t from "../../../types";
export var metadata = {
optional: true
};
export function MemberExpression(node) {
var prop = node.property;
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
// foo["bar"] => foo.bar
node.property = t.identifier(prop.value);
node.computed = false;
}
}

View File

@@ -0,0 +1,14 @@
import * as t from "../../../types";
export var metadata = {
optional: true
};
export function Property(node) {
var key = node.key;
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
// "foo": "bar" -> foo: "bar"
node.key = t.identifier(key.value);
node.computed = false;
}
}

View File

@@ -9,6 +9,6 @@ export var Program = {
enter(ast) {
regenerator.transform(ast);
this.stop();
return ast; // force a checkPath, this really needs to be optimised
this.checkSelf();
}
};

View File

@@ -3,6 +3,8 @@ import * as t from "../types";
export default class Binding {
constructor({ identifier, scope, path, kind }) {
this.identifier = identifier;
this.references = 0;
this.referenced = false;
this.constant = true;
this.scope = scope;
this.path = path;
@@ -58,6 +60,15 @@ export default class Binding {
}
}
/**
* Description
*/
reference() {
this.referenced = true;
this.references++;
}
/**
* Description
*/

View File

@@ -3,6 +3,8 @@ import isBoolean from "lodash/lang/isBoolean";
import isNumber from "lodash/lang/isNumber";
import isRegExp from "lodash/lang/isRegExp";
import isString from "lodash/lang/isString";
import codeFrame from "../../helpers/code-frame";
import parse from "../../helpers/parse";
import traverse from "../index";
import includes from "lodash/collection/includes";
import assign from "lodash/object/assign";
@@ -116,7 +118,7 @@ export default class TraversalPath {
} else if (this.isStatementOrBlock()) {
if (this.node) nodes.push(this.node);
this.container[this.key] = t.blockStatement(nodes);
this.checkPaths(this);
this.checkSelf();
} else {
throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?");
}
@@ -214,7 +216,7 @@ export default class TraversalPath {
} else if (this.isStatementOrBlock()) {
if (this.node) nodes.unshift(this.node);
this.container[this.key] = t.blockStatement(nodes);
this.checkPaths(this);
this.checkSelf();
} else {
throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?");
}
@@ -319,6 +321,12 @@ export default class TraversalPath {
var parent = this.parent;
if (!parentPath) return;
// we've just removed the last declarator of a variable declaration so there's no point in
// keeping it
if (parentPath.isVariableDeclaration() && parent.declarations.length === 0) {
return parentPath.remove();
}
// we're the child of an expression statement so we should remove the parent
if (parentPath.isExpressionStatement()) {
return parentPath.remove();
@@ -470,7 +478,29 @@ export default class TraversalPath {
* Description
*/
replaceWith(replacement, arraysAllowed) {
replaceWithSourceString(replacement) {
try {
replacement = `(${replacement})`;
replacement = parse(replacement);
} catch (err) {
var loc = err.loc;
if (loc) {
err.message += " - make sure this is an expression.";
err.message += "\n" + codeFrame(replacement, loc.line, loc.column + 1);
}
throw err;
}
replacement = replacement.program.body[0].expression;
traverse.removeProperties(replacement);
return this.replaceWith(replacement);
}
/**
* Description
*/
replaceWith(replacement, whateverAllowed) {
if (this.removed) {
throw new Error("You can't replace this node, we've already removed it");
}
@@ -479,14 +509,38 @@ export default class TraversalPath {
throw new Error("You passed `path.replaceWith()` a falsy node, use `path.remove()` instead");
}
if (this.node === replacement) {
throw new Error("You're trying to replace a node with itself which doesn't make any sense. If you're trying to do a transformer recache then use `this.checkSelf()`");
}
// normalise inserting an entire AST
if (t.isProgram(replacement)) {
replacement = replacement.body;
whateverAllowed = true;
}
if (Array.isArray(replacement)) {
if (arraysAllowed) {
if (whateverAllowed) {
return this.replaceWithMultiple(replacement);
} else {
throw new Error("Don't use `path.replaceWith()` with an array of nodes, use `path.replaceWithMultiple()`");
}
}
if (typeof replacement === "string") {
if (whateverAllowed) {
return this.replaceWithSourceString(replacement);
} else {
throw new Error("Don't use `path.replaceWith()` with a string, use `path.replaceWithSourceString()`");
}
}
// replacing a statement with an expression so wrap it in an expression statement
if (this.isPreviousType("Statement") && t.isExpression(replacement)) {
replacement = t.expressionStatement(replacement);
}
// replacing an expression with a statement so let's explode it
if (this.isPreviousType("Expression") && t.isStatement(replacement)) {
return this.replaceExpressionWithStatements([replacement]);
}
@@ -501,6 +555,14 @@ export default class TraversalPath {
// potentially create new scope
this.setScope();
this.checkSelf();
}
/**
* Description
*/
checkSelf() {
this.checkPaths(this);
}
@@ -650,6 +712,10 @@ export default class TraversalPath {
return this.shouldStop;
}
/**
* Description
*/
getSibling(key) {
return TraversalPath.get(this.parentPath, null, this.parent, this.container, key, this.file);
}

View File

@@ -40,8 +40,13 @@ var functionVariableVisitor = {
var programReferenceVisitor = {
enter(node, parent, scope, state) {
if (t.isReferencedIdentifier(node, parent) && !scope.hasBinding(node.name)) {
state.addGlobal(node);
if (t.isReferencedIdentifier(node, parent)) {
var bindingInfo = scope.getBinding(node.name);
if (bindingInfo) {
bindingInfo.reference();
} else {
state.addGlobal(node);
}
} else if (t.isLabeledStatement(node)) {
state.addGlobal(node);
} else if (t.isAssignmentExpression(node)) {
@@ -69,8 +74,15 @@ var renameVisitor = explode({
Identifier(node, parent, scope, state) {
if (this.isReferenced() && node.name === state.oldName) {
if (this.parentPath.isProperty() && this.key === "key" && parent.shorthand) {
var value = t.identifier(state.newName);;
if (parent.value === state.binding) {
state.info.identifier = state.binding = value;
}
parent.shorthand = false;
parent.value = t.identifier(state.newName);
parent.value = value;
parent.key = t.identifier(state.oldName);
} else {
node.name = state.newName;
}
@@ -482,6 +494,19 @@ export default class Scope {
this.crawl();
}
/**
* Description
*/
isPure(node) {
if (t.isIdentifier(node)) {
var bindingInfo = this.getBinding(node.name);
return bindingInfo.constant;
} else {
return t.isPure(node);
}
}
/**
* Description
*/

View File

@@ -26,9 +26,9 @@
"ExportNamedDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
"ImportDeclaration": ["Statement", "Declaration", "ModuleDeclaration"],
"ArrowFunctionExpression": ["Scopable", "Function", "Expression"],
"FunctionDeclaration": ["Scopable", "Function", "Statement", "Declaration"],
"FunctionExpression": ["Scopable", "Function", "Expression"],
"ArrowFunctionExpression": ["Scopable", "Function", "Expression", "Pure"],
"FunctionDeclaration": ["Scopable", "Function", "Statement", "Pure", "Declaration"],
"FunctionExpression": ["Scopable", "Function", "Expression", "Pure"],
"BlockStatement": ["Scopable", "Statement"],
"Program": ["Scopable"],
@@ -41,8 +41,8 @@
"SpreadProperty": ["UnaryLike"],
"SpreadElement": ["UnaryLike"],
"ClassDeclaration": ["Scopable", "Class", "Statement", "Declaration"],
"ClassExpression": ["Scopable", "Class", "Expression"],
"ClassDeclaration": ["Scopable", "Class", "Pure", "Statement", "Declaration"],
"ClassExpression": ["Scopable", "Class", "Pure", "Expression"],
"ForOfStatement": ["Scopable", "Statement", "For", "Loop"],
"ForInStatement": ["Scopable", "Statement", "For", "Loop"],
@@ -62,7 +62,7 @@
"ConditionalExpression": ["Expression"],
"DoExpression": ["Expression"],
"Identifier": ["Expression"],
"Literal": ["Expression"],
"Literal": ["Expression", "Pure"],
"MemberExpression": ["Expression"],
"MetaProperty": ["Expression"],
"NewExpression": ["Expression"],
@@ -80,15 +80,15 @@
"ArrayTypeAnnotation": ["Flow"],
"BooleanTypeAnnotation": ["Flow"],
"ClassImplements": ["Flow"],
"DeclareClass": ["Flow"],
"DeclareFunction": ["Flow"],
"DeclareModule": ["Flow"],
"DeclareVariable": ["Flow"],
"DeclareClass": ["Flow", "Statement"],
"DeclareFunction": ["Flow", "Statement"],
"DeclareModule": ["Flow", "Statement"],
"DeclareVariable": ["Flow", "Statement"],
"FunctionTypeAnnotation": ["Flow"],
"FunctionTypeParam": ["Flow"],
"GenericTypeAnnotation": ["Flow"],
"InterfaceExtends": ["Flow"],
"InterfaceDeclaration": ["Flow"],
"InterfaceDeclaration": ["Flow", "Statement", "Declaration"],
"IntersectionTypeAnnotation": ["Flow"],
"NullableTypeAnnotation": ["Flow"],
"NumberTypeAnnotation": ["Flow"],
@@ -96,7 +96,7 @@
"StringTypeAnnotation": ["Flow"],
"TupleTypeAnnotation": ["Flow"],
"TypeofTypeAnnotation": ["Flow"],
"TypeAlias": ["Flow"],
"TypeAlias": ["Flow", "Statement"],
"TypeAnnotation": ["Flow"],
"TypeCastExpression": ["Flow"],
"TypeParameterDeclaration": ["Flow"],

View File

@@ -88,7 +88,7 @@ export function arrayify(val: any, mapFn?: Function): Array {
return val;
}
throw new TypeError("illegal type for arrayify");
return [val];
}
export function booleanify(val: any): boolean {
@@ -155,7 +155,7 @@ export function template(name: string, nodes?: Array<Object>, keepExpression?: b
}
export function parseTemplate(loc: string, code: string): Object {
var ast = parse({ filename: loc, looseModules: true }, code).program;
var ast = parse(code, { filename: loc, looseModules: true }).program;
ast = traverse.removeProperties(ast);
return ast;
}

View File

@@ -18,8 +18,79 @@ suite("api", function () {
assert.ok(!result.ast);
});
suite("getModuleName() {} option", function () {
// As of this commit, `getModuleName` is the only option that isn't JSON
// compatible which is why it's not inside /test/core/fixtures/transformation
function getModuleNameTest(moduleFormat, expected) {
var result = transform("foo('bar');", {
filename: "foo/bar/index",
modules: moduleFormat,
moduleIds: true,
getModuleName: function (name) {
return name.replace(/\/index$/, "");
}
});
assert.equal(result.code, expected);
}
test("{ modules: \"amd\" }", function () {
var expected = [
"define('foo/bar', ['exports'], function (exports) {",
" 'use strict';",
"",
" foo('bar');",
"});"
].join("\n");
getModuleNameTest("amd", expected);
});
test("{ modules: \"umd\" }", function () {
var expected = [
"(function (global, factory) {",
" if (typeof define === 'function' && define.amd) {",
" define('foo/bar', ['exports'], factory);",
" } else if (typeof exports !== 'undefined') {",
" factory(exports);",
" } else {",
" var mod = {",
" exports: {}",
" };",
" factory(mod.exports);",
" global.fooBar = mod.exports;",
" }",
"})(this, function (exports) {",
" 'use strict';",
"",
" foo('bar');",
"});",
].join("\n");
getModuleNameTest("umd", expected);
});
test("{ modules: \"system\" }", function () {
var expected = [
"System.register('foo/bar', [], function (_export) {",
" return {",
" setters: [],",
" execute: function () {",
" 'use strict';",
"",
" foo('bar');",
" }",
" };",
"});",
].join("\n");
getModuleNameTest("system", expected);
});
});
test("addHelper unknown", function () {
var file = new File;
var file = new File({}, transform.pipeline);
assert.throws(function () {
file.addHelper("foob");
}, /Unknown helper foob/);
@@ -40,11 +111,11 @@ suite("api", function () {
});
test("extra options", function () {
var file1 = new File({ extra: { foo: "bar" } });
var file1 = new File({ extra: { foo: "bar" } }, transform.pipeline);
assert.equal(file1.opts.extra.foo, "bar");
var file2 = new File;
var file3 = new File;
var file2 = new File({}, transform.pipeline);
var file3 = new File({}, transform.pipeline);
assert.ok(file2.opts.extra !== file3.opts.extra);
});

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
_classCallCheck(this, Test);

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
_classCallCheck(this, Test);

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
_classCallCheck(this, Test);

View File

@@ -0,0 +1,3 @@
import foo from "./fixtures/foo";
foo();

View File

@@ -0,0 +1,7 @@
"use strict";
function fixtures$foo() {
return "foobar";
}
fixtures$foo();

View File

@@ -0,0 +1,3 @@
export default function () {
return "foobar";
}

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
_classCallCheck(this, Test);

View File

@@ -1,5 +1,5 @@
class Test {
constructor() {
arr.map(x => x * x);
arr.map(x => x * x);
}
}

View File

@@ -1,6 +1,4 @@
obj["x"] = 2;
test.catch;
test.catch["foo"];
test.catch.foo;
test["catch"];
test["catch"]["foo"];
test["catch"].foo;

View File

@@ -1,7 +1,5 @@
"use strict";
obj.x = 2;
test["catch"];
test["catch"].foo;
test["catch"];

View File

@@ -1,7 +1,7 @@
"use strict";
var obj = {
test: "foob",
"test": "foob",
"!@#$": "foob",
"33rd": "foob",
fooBar: "foob"

View File

@@ -1,17 +0,0 @@
class Foo extends Array {
}
class Bar extends Array {
constructor() {
super();
this.foo = "bar";
}
}
class Baz extends Array {
constructor() {
super();
(() => this)
}
}

View File

@@ -1,27 +0,0 @@
class Foo extends Array {
}
class Bar extends Array {
constructor() {
super();
this.foo = "bar";
}
}
var foo = new Foo;
assert.ok(Array.isArray(foo));
foo.push(1);
foo.push(2);
assert.equal(foo[0], 1);
assert.equal(foo[1], 2);
assert.equal(foo.length, 2);
var bar = new Bar;
assert.ok(Array.isArray(bar));
assert.equal(bar.foo, "bar");
bar.push(1);
bar.push(2);
assert.equal(bar[0], 1);
assert.equal(bar[1], 2);
assert.equal(bar.length, 2);

View File

@@ -1,53 +0,0 @@
"use strict";
var Foo = (function (_Array) {
function Foo() {
babelHelpers.classCallCheck(this, Foo);
if (_Array != null) {
var _this = new (babelHelpers.bind.apply(_Array, [null].concat(babelHelpers.slice.call(arguments))))();
_this.__proto__ = Foo.prototype;
return _this;
}
return _this;
}
babelHelpers.inherits(Foo, _Array);
return Foo;
})(Array);
var Bar = (function (_Array2) {
function Bar() {
babelHelpers.classCallCheck(this, Bar);
var _this2 = new _Array2();
_this2.__proto__ = Bar.prototype;
_this2.foo = "bar";
return _this2;
}
babelHelpers.inherits(Bar, _Array2);
return Bar;
})(Array);
var Baz = (function (_Array3) {
function Baz() {
babelHelpers.classCallCheck(this, Baz);
var _this3 = new _Array3();
_this3.__proto__ = Baz.prototype;
(function () {
return _this3;
});
return _this3;
}
babelHelpers.inherits(Baz, _Array3);
return Baz;
})(Array);

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _default = (function () {
var _class = function _default() {

View File

@@ -1,6 +1,6 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var foo = 1;
var foo = 1,

View File

@@ -1,10 +1,10 @@
System.register([], function (_export) {
var _default, Foo;
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
_export("default", foo);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function foo() {}
return {

View File

@@ -1,10 +1,10 @@
System.register([], function (_export) {
var foo, foo2, foo3, foo4, foo5, foo6, foo8;
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
_export("foo7", foo7);
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function foo7() {}
return {

View File

@@ -2,4 +2,4 @@
var _obj;
var obj = (_obj = {}, _obj.first = "first", _obj.second = "second", _obj);
var obj = (_obj = {}, _obj.first = "first", _obj["second"] = "second", _obj);

View File

@@ -1,5 +1,3 @@
"use strict";
var _foo;
var foo = (_foo = {}, _foo[Symbol.iterator] = "foobar", _foo);
var foo = babelHelpers.defineProperty({}, Symbol.iterator, "foobar");

View File

@@ -1,5 +1,5 @@
"use strict";
var _taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; };
function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
var foo = bar(_taggedTemplateLiteralLoose(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar());

View File

@@ -1,5 +1,5 @@
"use strict";
var _taggedTemplateLiteral = function (strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); };
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var foo = bar(_taggedTemplateLiteral(["wow\na", "b ", ""], ["wow\\na", "b ", ""]), 42, _.foobar());

View File

@@ -0,0 +1,2 @@
foo["default"];
foo["import"];

View File

@@ -0,0 +1,4 @@
"use strict";
foo["default"];
foo["import"];

View File

@@ -0,0 +1,3 @@
{
"optional": ["minification.memberExpressionLiterals"]
}

View File

@@ -0,0 +1,4 @@
foo["bar"];
foo["foo"];
foo.bar;
foo.foo;

View File

@@ -0,0 +1,6 @@
"use strict";
foo.bar;
foo.foo;
foo.bar;
foo.foo;

View File

@@ -0,0 +1,4 @@
({
"default": null,
"import": null
});

View File

@@ -0,0 +1,6 @@
"use strict";
({
"default": null,
"import": null
});

View File

@@ -0,0 +1,3 @@
{
"optional": ["minification.propertyLiterals"]
}

View File

@@ -0,0 +1,4 @@
var obj = {
foo: "foo",
"bar": "bar"
};

View File

@@ -0,0 +1,6 @@
"use strict";
var obj = {
foo: "foo",
bar: "bar"
};

View File

@@ -0,0 +1,9 @@
var obj = {
search: function({search}) {
console.log(search);
}
};
function search({search}) {
console.log(search);
}

View File

@@ -0,0 +1,15 @@
"use strict";
var obj = {
search: function search(_ref) {
var _search = _ref.search;
console.log(_search);
}
};
function search(_ref2) {
var search = _ref2.search;
console.log(search);
}

View File

@@ -1,6 +1,6 @@
"use strict";
var _defaults = function (obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; };
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
var _foo, _foo$bar, _foo$bar2;

View File

@@ -1,5 +1,5 @@
"use strict";
var _defaults = function (obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; };
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
_defaults(obj, bar);

View File

@@ -1,10 +1,10 @@
"use strict";
var _defaults = function (obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; };
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) _defaults(subClass, superClass); };
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) _defaults(subClass, superClass); }
var Foo = (function (_Bar) {
function Foo() {
@@ -18,4 +18,4 @@ var Foo = (function (_Bar) {
_inherits(Foo, _Bar);
return Foo;
})(Bar);
})(Bar);

View File

@@ -26,7 +26,7 @@ _.each(helper.get("generation"), function (testSuite) {
var expect = task.expect;
var actual = task.actual;
var actualAst = parse({
var actualAst = parse(actual.code, {
filename: actual.loc,
nonStandard: true,
strictMode: false,
@@ -36,7 +36,7 @@ _.each(helper.get("generation"), function (testSuite) {
"es7.asyncFunctions": true,
"es7.exportExtensions": true
}
}, actual.code);
});
var actualCode = generate(actualAst, task.options, actual.code).code;
chai.expect(actualCode).to.equal(expect.code, actual.loc + " !== " + expect.loc);

21
test/core/path.js Normal file
View File

@@ -0,0 +1,21 @@
var Transformer = require("../../lib/babel/transformation/transformer");
var transform = require("../../lib/babel/transformation");
var babel = require("../../lib/babel/api/node");
var chai = require("chai");
suite("traversal path", function () {
test("replaceWithSourceString", function () {
var expectCode = "function foo() {}";
var actualCode = transform(expectCode, {
blacklist: "strict",
plugins: [new Transformer("foobar", {
FunctionDeclaration: function () {
return "console.whatever()";
}
})]
}).code;
chai.expect(actualCode).to.be.equal("console.whatever();");
});
});

View File

@@ -11,19 +11,18 @@ suite("util", function () {
});
test("templates do not recurse", function () {
var key = __filename;
var KEY = parse({ loc: key }, "replacedKey").program.body[0].expression;
var VALUE = parse({ loc: key }, "+KEY").program.body[0].expression;
var key = __filename;
var KEY = parse("replacedKey").program.body[0].expression;
var VALUE = parse("+KEY").program.body[0].expression;
util.templates[key] = util.parseTemplate(key, "KEY = VALUE;");
var result = util.template(key, {KEY: KEY, VALUE: VALUE});
var result = util.template(key, { KEY: KEY, VALUE: VALUE });
delete util.templates[key];
assert.strictEqual(
result.right.argument.name,
"KEY",
"template should not recurse into replaced nodes, " +
"replacing KEY inside VALUE"
"template should not recurse into replaced nodes, replacing KEY inside VALUE"
);
});
@@ -72,10 +71,7 @@ suite("util", function () {
assert.deepEqual(util.arrayify("foo"), ["foo"]);
assert.deepEqual(util.arrayify("foo,bar"), ["foo", "bar"]);
assert.deepEqual(util.arrayify(["foo", "bar"]), ["foo", "bar"]);
assert.throws(function () {
util.arrayify({});
}, /illegal type for arrayify/);
assert.deepEqual(util.arrayify({ foo: "bar" }), [{ foo: "bar" }]);
});
test("regexify", function () {