embed acorn
This commit is contained in:
parent
976e8c1cfd
commit
ec526f9224
2
.gitignore
vendored
2
.gitignore
vendored
@ -14,4 +14,4 @@ dist
|
|||||||
packages/babel-runtime/*.js
|
packages/babel-runtime/*.js
|
||||||
packages/babel-runtime/helpers/*.js
|
packages/babel-runtime/helpers/*.js
|
||||||
packages/babel-runtime/regenerator/*.js
|
packages/babel-runtime/regenerator/*.js
|
||||||
lib
|
lib/babel
|
||||||
|
|||||||
32
lib/acorn/AUTHORS
Normal file
32
lib/acorn/AUTHORS
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
List of Acorn contributors. Updated before every release.
|
||||||
|
|
||||||
|
Alistair Braidwood
|
||||||
|
Aparajita Fishman
|
||||||
|
Arian Stolwijk
|
||||||
|
Artem Govorov
|
||||||
|
Brandon Mills
|
||||||
|
Charles Hughes
|
||||||
|
Conrad Irwin
|
||||||
|
David Bonnet
|
||||||
|
impinball
|
||||||
|
Ingvar Stepanyan
|
||||||
|
Jiaxing Wang
|
||||||
|
Johannes Herr
|
||||||
|
Jürg Lehni
|
||||||
|
keeyipchan
|
||||||
|
krator
|
||||||
|
Marijn Haverbeke
|
||||||
|
Martin Carlberg
|
||||||
|
Mathias Bynens
|
||||||
|
Mathieu 'p01' Henri
|
||||||
|
Max Schaefer
|
||||||
|
Mihai Bazon
|
||||||
|
Mike Rennie
|
||||||
|
Oskar Schöldström
|
||||||
|
Paul Harper
|
||||||
|
Peter Rust
|
||||||
|
PlNG
|
||||||
|
r-e-d
|
||||||
|
Rich Harris
|
||||||
|
Sebastian McKenzie
|
||||||
|
zsjforcn
|
||||||
19
lib/acorn/LICENSE
Normal file
19
lib/acorn/LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (C) 2012-2014 by various contributors (see AUTHORS)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
4
lib/acorn/README.md
Normal file
4
lib/acorn/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Acorn
|
||||||
|
|
||||||
|
Embedded version with Babel-specific modifications of the excellent
|
||||||
|
[acorn](https://github.com/marijnh/acorn) parser.
|
||||||
2934
lib/acorn/acorn.js
Normal file
2934
lib/acorn/acorn.js
Normal file
File diff suppressed because it is too large
Load Diff
23
lib/acorn/package.json
Normal file
23
lib/acorn/package.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "acorn",
|
||||||
|
"description": "ECMAScript parser",
|
||||||
|
"homepage": "http://marijnhaverbeke.nl/acorn/",
|
||||||
|
"main": "acorn.js",
|
||||||
|
"version": "0.12.1",
|
||||||
|
"engines": {"node": ">=0.4.0"},
|
||||||
|
"browser": "acorn_csp.js",
|
||||||
|
"maintainers": [{"name": "Marijn Haverbeke",
|
||||||
|
"email": "marijnh@gmail.com",
|
||||||
|
"web": "http://marijnhaverbeke.nl"}],
|
||||||
|
"repository": {"type": "git",
|
||||||
|
"url": "http://marijnhaverbeke.nl/git/acorn"},
|
||||||
|
"licenses": [{"type": "MIT",
|
||||||
|
"url": "http://marijnhaverbeke.nl/acorn/LICENSE"}],
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test/run.js",
|
||||||
|
"prepublish": "node bin/without_eval > acorn_csp.js"
|
||||||
|
},
|
||||||
|
"bin": {"acorn": "./bin/acorn"},
|
||||||
|
"devDependencies": {"regenerate": "~0.6.2",
|
||||||
|
"unicode-7.0.0": "~0.1.5"}
|
||||||
|
}
|
||||||
96
lib/acorn/test/bench.html
Normal file
96
lib/acorn/test/bench.html
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Acorn benchmark</title>
|
||||||
|
<script src="../acorn.js"></script>
|
||||||
|
<script src="compare/esprima.js"></script>
|
||||||
|
<script src="compare/traceur.js"></script>
|
||||||
|
<script src="jquery-string.js"></script>
|
||||||
|
<script src="codemirror-string.js"></script>
|
||||||
|
<style>
|
||||||
|
td { text-align: right; padding-right: 20px; }
|
||||||
|
th { text-align: left; padding-right: 40px; }
|
||||||
|
body { max-width: 50em; padding: 1em 2em; }
|
||||||
|
h1 { font-size: 150%; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<h1>Acorn/Esprima/Traceur speed comparison</h1>
|
||||||
|
|
||||||
|
<p>This will run each of the three ES6 parsers on the source code of
|
||||||
|
jQuery 1.11.1 and CodeMirror 3.0b1 for five seconds, and show a table
|
||||||
|
indicating the number of lines parsed per second. Note that Traceur
|
||||||
|
always stores location data, and is thus not fairly compared by the
|
||||||
|
benchmark <em>without</em> location data.<p>
|
||||||
|
|
||||||
|
<p>Also note that having the developer tools open in Chrome, or
|
||||||
|
Firebug in Firefox <em>heavily</em> influences the numbers you get. In
|
||||||
|
Chrome, the effect even lingers (in the tab) after you close the
|
||||||
|
developer tools. Load in a fresh tab to get (halfway) stable
|
||||||
|
numbers.</p>
|
||||||
|
|
||||||
|
<button onclick="run(false)">Compare <strong>without</strong> location data</button>
|
||||||
|
<button onclick="run(true)">Compare <strong>with</strong> location data</button>
|
||||||
|
<button onclick="run(false, true)">Run only Acorn</button>
|
||||||
|
<span id="running"></span>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var sourceFileName = 'source.js';
|
||||||
|
|
||||||
|
function runAcorn(code, locations) {
|
||||||
|
acorn.parse(code, {ecmaVersion: 6, locations: locations, sourceFile: sourceFileName});
|
||||||
|
}
|
||||||
|
function runEsprima(code, locations) {
|
||||||
|
esprima.parse(code, {loc: locations, source: sourceFileName});
|
||||||
|
}
|
||||||
|
function runTraceur(code) {
|
||||||
|
var file = new traceur.syntax.SourceFile(sourceFileName, code);
|
||||||
|
var parser = new traceur.syntax.Parser(file);
|
||||||
|
parser.parseScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalLines = codemirror30.split("\n").length + jquery111.split("\n").length;
|
||||||
|
|
||||||
|
var nowHost = (typeof performance === 'object' && 'now' in performance) ? performance : Date;
|
||||||
|
|
||||||
|
function benchmark(runner, locations) {
|
||||||
|
// Give it a chance to warm up (first runs are usually outliers)
|
||||||
|
runner(jquery111, locations);
|
||||||
|
runner(codemirror30, locations);
|
||||||
|
var t0 = nowHost.now(), t1, lines = 0;
|
||||||
|
for (;;) {
|
||||||
|
runner(jquery111, locations);
|
||||||
|
runner(codemirror30, locations);
|
||||||
|
lines += totalLines;
|
||||||
|
t1 = nowHost.now();
|
||||||
|
if (t1 - t0 > 5000) break;
|
||||||
|
}
|
||||||
|
return lines / ((t1 - t0) / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOutput(values) {
|
||||||
|
var html = "<hr><table>";
|
||||||
|
for (var i = 0; i < values.length; ++i)
|
||||||
|
html += "<tr><th>" + values[i].name + "</td><td>" + Math.round(values[i].score) + " lines per second</td><td>" +
|
||||||
|
Math.round(values[i].score * 100 / values[0].score) + "%</td></tr>";
|
||||||
|
document.body.appendChild(document.createElement("div")).innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function run(locations, acornOnly) {
|
||||||
|
var running = document.getElementById("running");
|
||||||
|
running.innerHTML = "Running benchmark...";
|
||||||
|
var data = [{name: "Acorn", runner: runAcorn},
|
||||||
|
{name: "Esprima", runner: runEsprima},
|
||||||
|
{name: "Traceur", runner: runTraceur}];
|
||||||
|
if (acornOnly) data.length = 1;
|
||||||
|
var pos = 0;
|
||||||
|
function next() {
|
||||||
|
data[pos].score = benchmark(data[pos].runner, locations);
|
||||||
|
if (++pos == data.length) {
|
||||||
|
running.innerHTML = "";
|
||||||
|
showOutput(data);
|
||||||
|
} else setTimeout(next, 100);
|
||||||
|
}
|
||||||
|
setTimeout(next, 50);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
3995
lib/acorn/test/codemirror-string.js
Normal file
3995
lib/acorn/test/codemirror-string.js
Normal file
File diff suppressed because it is too large
Load Diff
5218
lib/acorn/test/compare/esprima.js
Normal file
5218
lib/acorn/test/compare/esprima.js
Normal file
File diff suppressed because one or more lines are too long
23622
lib/acorn/test/compare/traceur.js
Normal file
23622
lib/acorn/test/compare/traceur.js
Normal file
File diff suppressed because one or more lines are too long
113
lib/acorn/test/driver.js
Normal file
113
lib/acorn/test/driver.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
(function(exports) {
|
||||||
|
var tests = [];
|
||||||
|
|
||||||
|
exports.test = function(code, ast, options) {
|
||||||
|
tests.push({code: code, ast: ast, options: options});
|
||||||
|
};
|
||||||
|
exports.testFail = function(code, message, options) {
|
||||||
|
tests.push({code: code, error: message, options: options});
|
||||||
|
};
|
||||||
|
exports.testAssert = function(code, assert, options) {
|
||||||
|
tests.push({code: code, assert: assert, options: options});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.runTests = function(config, callback) {
|
||||||
|
var parse = config.parse;
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; ++i) {
|
||||||
|
var test = tests[i];
|
||||||
|
if (config.filter && !config.filter(test)) continue;
|
||||||
|
var testOpts = test.options || {locations: true};
|
||||||
|
var expected = {};
|
||||||
|
if (expected.onComment = testOpts.onComment)
|
||||||
|
testOpts.onComment = []
|
||||||
|
if (expected.onToken = testOpts.onToken)
|
||||||
|
testOpts.onToken = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
var ast = parse(test.code, testOpts);
|
||||||
|
} catch(e) {
|
||||||
|
if (!(e instanceof SyntaxError)) throw e;
|
||||||
|
if (test.error) {
|
||||||
|
if (e.message == test.error) callback("ok", test.code);
|
||||||
|
else callback("fail", test.code,
|
||||||
|
"Expected error message: " + test.error + "\nGot error message: " + e.message);
|
||||||
|
} else {
|
||||||
|
callback("error", test.code, e.message || e.toString());
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test.error) {
|
||||||
|
if (config.loose) callback("ok", test.code);
|
||||||
|
else callback("fail", test.code, "Expected error message: " + test.error + "\nBut parsing succeeded.");
|
||||||
|
} else if (test.assert) {
|
||||||
|
var error = test.assert(ast);
|
||||||
|
if (error) callback("fail", test.code, "\n Assertion failed:\n " + error);
|
||||||
|
else callback("ok", test.code);
|
||||||
|
} else {
|
||||||
|
var mis = misMatch(test.ast, ast);
|
||||||
|
for (var name in expected) {
|
||||||
|
if (mis) break;
|
||||||
|
if (expected[name]) {
|
||||||
|
mis = misMatch(expected[name], testOpts[name]);
|
||||||
|
testOpts[name] = expected[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mis) callback("fail", test.code, mis);
|
||||||
|
else callback("ok", test.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); }
|
||||||
|
function addPath(str, pt) {
|
||||||
|
if (str.charAt(str.length-1) == ")")
|
||||||
|
return str.slice(0, str.length-1) + "/" + pt + ")";
|
||||||
|
return str + " (" + pt + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
var misMatch = exports.misMatch = function(exp, act) {
|
||||||
|
if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
|
||||||
|
if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act);
|
||||||
|
} else if (exp instanceof RegExp || act instanceof RegExp) {
|
||||||
|
var left = ppJSON(exp), right = ppJSON(act);
|
||||||
|
if (left !== right) return left + " !== " + right;
|
||||||
|
} else if (exp.splice) {
|
||||||
|
if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act);
|
||||||
|
if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length;
|
||||||
|
for (var i = 0; i < act.length; ++i) {
|
||||||
|
var mis = misMatch(exp[i], act[i]);
|
||||||
|
if (mis) return addPath(mis, i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var prop in exp) {
|
||||||
|
var mis = misMatch(exp[prop], act[prop]);
|
||||||
|
if (mis) return addPath(mis, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function mangle(ast) {
|
||||||
|
if (typeof ast != "object" || !ast) return;
|
||||||
|
if (ast.slice) {
|
||||||
|
for (var i = 0; i < ast.length; ++i) mangle(ast[i]);
|
||||||
|
} else {
|
||||||
|
var loc = ast.start && ast.end && {start: ast.start, end: ast.end};
|
||||||
|
if (loc) { delete ast.start; delete ast.end; }
|
||||||
|
for (var name in ast) if (ast.hasOwnProperty(name)) mangle(ast[name]);
|
||||||
|
if (loc) ast.loc = loc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.printTests = function() {
|
||||||
|
var out = "";
|
||||||
|
for (var i = 0; i < tests.length; ++i) {
|
||||||
|
if (tests[i].error) continue;
|
||||||
|
mangle(tests[i].ast);
|
||||||
|
out += "test(" + JSON.stringify(tests[i].code) + ", " + JSON.stringify(tests[i].ast, null, 2) + ");\n\n";
|
||||||
|
}
|
||||||
|
document.body.innerHTML = "";
|
||||||
|
document.body.appendChild(document.createElement("pre")).appendChild(document.createTextNode(out));
|
||||||
|
};
|
||||||
|
})(typeof exports == "undefined" ? window : exports);
|
||||||
14
lib/acorn/test/index.html
Normal file
14
lib/acorn/test/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Acorn test suite</title>
|
||||||
|
<script src="../acorn.js"></script>
|
||||||
|
<script src="../acorn_loose.js"></script>
|
||||||
|
<script src="driver.js"></script>
|
||||||
|
<script src="tests.js" charset="utf-8"></script>
|
||||||
|
<script src="tests-harmony.js" charset="utf-8"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul id="log"></ul>
|
||||||
|
<script src="run.js"></script>
|
||||||
|
</body>
|
||||||
10315
lib/acorn/test/jquery-string.js
vendored
Normal file
10315
lib/acorn/test/jquery-string.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
109
lib/acorn/test/run.js
Normal file
109
lib/acorn/test/run.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
(function() {
|
||||||
|
var driver;
|
||||||
|
|
||||||
|
if (typeof require !== "undefined") {
|
||||||
|
driver = require("./driver.js");
|
||||||
|
require("./tests.js");
|
||||||
|
require("./tests-harmony.js");
|
||||||
|
} else {
|
||||||
|
driver = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
var htmlLog = typeof document === "object" && document.getElementById('log');
|
||||||
|
var htmlGroup = htmlLog;
|
||||||
|
|
||||||
|
function group(name) {
|
||||||
|
if (htmlGroup) {
|
||||||
|
var parentGroup = htmlGroup;
|
||||||
|
htmlGroup = document.createElement("ul");
|
||||||
|
var item = document.createElement("li");
|
||||||
|
item.textContent = name;
|
||||||
|
item.appendChild(htmlGroup);
|
||||||
|
parentGroup.appendChild(item);
|
||||||
|
}
|
||||||
|
if (typeof console === "object" && console.group) {
|
||||||
|
console.group(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function groupEnd() {
|
||||||
|
if (htmlGroup) {
|
||||||
|
htmlGroup = htmlGroup.parentElement.parentElement;
|
||||||
|
}
|
||||||
|
if (typeof console === "object" && console.groupEnd) {
|
||||||
|
console.groupEnd(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(title, message) {
|
||||||
|
if (htmlGroup) {
|
||||||
|
var elem = document.createElement("li");
|
||||||
|
elem.innerHTML = "<b>" + title + "</b> " + message;
|
||||||
|
htmlGroup.appendChild(elem);
|
||||||
|
}
|
||||||
|
if (typeof console === "object") console.log(title, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stats, modes = {
|
||||||
|
Normal: {
|
||||||
|
config: {
|
||||||
|
parse: (typeof require === "undefined" ? window.acorn : require("../acorn.js")).parse
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Loose: {
|
||||||
|
config: {
|
||||||
|
parse: (typeof require === "undefined" ? window.acorn : require("../acorn_loose")).parse_dammit,
|
||||||
|
loose: true,
|
||||||
|
filter: function (test) {
|
||||||
|
var opts = test.options || {};
|
||||||
|
if (opts.loose === false) return false;
|
||||||
|
return (opts.ecmaVersion || 5) <= 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function report(state, code, message) {
|
||||||
|
if (state != "ok") {++stats.failed; log(code, message);}
|
||||||
|
++stats.testsRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
group("Errors");
|
||||||
|
|
||||||
|
for (var name in modes) {
|
||||||
|
group(name);
|
||||||
|
var mode = modes[name];
|
||||||
|
stats = mode.stats = {testsRun: 0, failed: 0};
|
||||||
|
var t0 = +new Date;
|
||||||
|
driver.runTests(mode.config, report);
|
||||||
|
mode.stats.duration = +new Date - t0;
|
||||||
|
groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
groupEnd();
|
||||||
|
|
||||||
|
function outputStats(name, stats) {
|
||||||
|
log(name + ":", stats.testsRun + " tests run in " + stats.duration + "ms; " +
|
||||||
|
(stats.failed ? stats.failed + " failures." : "all passed."));
|
||||||
|
}
|
||||||
|
|
||||||
|
var total = {testsRun: 0, failed: 0, duration: 0};
|
||||||
|
|
||||||
|
group("Stats");
|
||||||
|
|
||||||
|
for (var name in modes) {
|
||||||
|
var stats = modes[name].stats;
|
||||||
|
outputStats(name + " parser", stats);
|
||||||
|
for (var key in stats) total[key] += stats[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStats("Total", total);
|
||||||
|
|
||||||
|
groupEnd();
|
||||||
|
|
||||||
|
if (total.failed && typeof process === "object") {
|
||||||
|
process.stdout.write("", function() {
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
15378
lib/acorn/test/tests-harmony.js
Normal file
15378
lib/acorn/test/tests-harmony.js
Normal file
File diff suppressed because it is too large
Load Diff
28967
lib/acorn/test/tests.js
Normal file
28967
lib/acorn/test/tests.js
Normal file
File diff suppressed because it is too large
Load Diff
47
lib/acorn/tools/generate-identifier-regex.js
Normal file
47
lib/acorn/tools/generate-identifier-regex.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Note: run `npm install unicode-7.0.0` first.
|
||||||
|
|
||||||
|
// Which Unicode version should be used?
|
||||||
|
var version = '7.0.0';
|
||||||
|
|
||||||
|
var start = require('unicode-' + version + '/properties/ID_Start/code-points')
|
||||||
|
.filter(function(ch) { return ch > 127; });
|
||||||
|
var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/properties/ID_Continue/code-points')
|
||||||
|
.filter(function(ch) { return ch > 127 && start.indexOf(ch) == -1; }));
|
||||||
|
|
||||||
|
function pad(str, width) {
|
||||||
|
while (str.length < width) str = "0" + str;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function esc(code) {
|
||||||
|
var hex = code.toString(16);
|
||||||
|
if (hex.length <= 2) return "\\x" + pad(hex, 2);
|
||||||
|
else return "\\u" + pad(hex, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generate(chars) {
|
||||||
|
var astral = [], re = "";
|
||||||
|
for (var i = 0, at = 0x10000; i < chars.length; i++) {
|
||||||
|
var from = chars[i], to = from;
|
||||||
|
while (i < chars.length - 1 && chars[i + 1] == to + 1) {
|
||||||
|
i++;
|
||||||
|
to++;
|
||||||
|
}
|
||||||
|
if (to <= 0xffff) {
|
||||||
|
if (from == to) re += esc(from);
|
||||||
|
else if (from + 1 == to) re += esc(from) + esc(to);
|
||||||
|
else re += esc(from) + "-" + esc(to);
|
||||||
|
} else {
|
||||||
|
astral.push(from - at, to - from);
|
||||||
|
at = to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {nonASCII: re, astral: astral};
|
||||||
|
}
|
||||||
|
|
||||||
|
var startData = generate(start), contData = generate(cont);
|
||||||
|
|
||||||
|
console.log(" var nonASCIIidentifierStartChars = \"" + startData.nonASCII + "\";");
|
||||||
|
console.log(" var nonASCIIidentifierChars = \"" + contData.nonASCII + "\";");
|
||||||
|
console.log(" var astralIdentifierStartCodes = " + JSON.stringify(startData.astral) + ";");
|
||||||
|
console.log(" var astralIdentifierCodes = " + JSON.stringify(contData.astral) + ";");
|
||||||
@ -36,7 +36,6 @@
|
|||||||
"test": "make test"
|
"test": "make test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn-babel": "0.11.1-38",
|
|
||||||
"ast-types": "~0.7.0",
|
"ast-types": "~0.7.0",
|
||||||
"chalk": "^1.0.0",
|
"chalk": "^1.0.0",
|
||||||
"chokidar": "^0.12.6",
|
"chokidar": "^0.12.6",
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import fs from "fs";
|
|||||||
export { util };
|
export { util };
|
||||||
export { canCompile } from "../util";
|
export { canCompile } from "../util";
|
||||||
|
|
||||||
export { default as acorn } from "acorn-babel";
|
export { default as acorn } from "../../acorn";
|
||||||
export { default as Transformer } from "../transformation/transformer";
|
export { default as Transformer } from "../transformation/transformer";
|
||||||
export { default as transform } from "../transformation";
|
export { default as transform } from "../transformation";
|
||||||
export { default as traverse } from "../traversal";
|
export { default as traverse } from "../traversal";
|
||||||
|
|||||||
@ -10,26 +10,32 @@ export function ImportSpecifier(node, print) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ExportSpecifier(node, print) {
|
export function ExportSpecifier(node, print) {
|
||||||
print(node.id);
|
print(node.local);
|
||||||
if (node.name) {
|
if (node.exported && node.local !== node.exported) {
|
||||||
this.push(" as ");
|
this.push(" as ");
|
||||||
print(node.name);
|
print(node.exported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExportBatchSpecifier() {
|
export function ExportAllDeclaration(node, source) {
|
||||||
this.push("*");
|
this.push("export * from");
|
||||||
|
print(node.source);
|
||||||
|
this.semicolon();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExportDeclaration(node, print) {
|
export function ExportNamedDeclaration(node, print) {
|
||||||
this.push("export ");
|
this.push("export ");
|
||||||
|
ExportDeclaration.call(this, node, print);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExportDefaultDeclaration(node, print) {
|
||||||
|
this.push("export default ");
|
||||||
|
ExportDeclaration.call(this, node, print);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ExportDeclaration(node, print) {
|
||||||
var specifiers = node.specifiers;
|
var specifiers = node.specifiers;
|
||||||
|
|
||||||
if (node.default) {
|
|
||||||
this.push("default ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.declaration) {
|
if (node.declaration) {
|
||||||
print(node.declaration);
|
print(node.declaration);
|
||||||
if (t.isStatement(node.declaration)) return;
|
if (t.isStatement(node.declaration)) return;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import normalizeAst from "./normalize-ast";
|
import normalizeAst from "./normalize-ast";
|
||||||
import estraverse from "estraverse";
|
import estraverse from "estraverse";
|
||||||
import codeFrame from "./code-frame";
|
import codeFrame from "./code-frame";
|
||||||
import acorn from "acorn-babel";
|
import acorn from "../../acorn";
|
||||||
|
|
||||||
export default function (opts, code, callback) {
|
export default function (opts, code, callback) {
|
||||||
try {
|
try {
|
||||||
@ -11,11 +11,12 @@ export default function (opts, code, callback) {
|
|||||||
var ast = acorn.parse(code, {
|
var ast = acorn.parse(code, {
|
||||||
allowImportExportEverywhere: opts.looseModules,
|
allowImportExportEverywhere: opts.looseModules,
|
||||||
allowReturnOutsideFunction: opts.looseModules,
|
allowReturnOutsideFunction: opts.looseModules,
|
||||||
transformers: opts.transformers,
|
transformers: opts.transformers || {},
|
||||||
ecmaVersion: 6,
|
ecmaVersion: 6,
|
||||||
strictMode: opts.strictMode,
|
strictMode: opts.strictMode,
|
||||||
onComment: comments,
|
onComment: comments,
|
||||||
locations: true,
|
locations: true,
|
||||||
|
plugins: opts.plugins || [],
|
||||||
onToken: tokens,
|
onToken: tokens,
|
||||||
ranges: true
|
ranges: true
|
||||||
});
|
});
|
||||||
|
|||||||
728
src/babel/parser/flow.js
Normal file
728
src/babel/parser/flow.js
Normal file
@ -0,0 +1,728 @@
|
|||||||
|
import acorn from "../../acorn";
|
||||||
|
|
||||||
|
var pp = acorn.Parser.prototype;
|
||||||
|
var tt = acorn.tokTypes;
|
||||||
|
|
||||||
|
pp.isRelational = function (op) {
|
||||||
|
return this.type === tt.relational && this.value === op;
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.expectRelational = function (op) {
|
||||||
|
if (this.isRelational(op)) {
|
||||||
|
this.next();
|
||||||
|
} else {
|
||||||
|
this.unexpected();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseDeclareClass = function (node) {
|
||||||
|
this.next();
|
||||||
|
this.flow_parseInterfaceish(node, true);
|
||||||
|
return this.finishNode(node, "DeclareClass");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseDeclareFunction = function (node) {
|
||||||
|
this.next();
|
||||||
|
|
||||||
|
var id = node.id = this.parseIdent();
|
||||||
|
|
||||||
|
var typeNode = this.startNode();
|
||||||
|
var typeContainer = this.startNode();
|
||||||
|
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
typeNode.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
} else {
|
||||||
|
typeNode.typeParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.expect(tt.parenL);
|
||||||
|
var tmp = this.flow_parseFunctionTypeParams();
|
||||||
|
typeNode.params = tmp.params;
|
||||||
|
typeNode.rest = tmp.rest;
|
||||||
|
this.expect(tt.parenR);
|
||||||
|
|
||||||
|
this.expect(tt.colon);
|
||||||
|
typeNode.returnType = this.flow_parseType();
|
||||||
|
|
||||||
|
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
|
||||||
|
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
|
||||||
|
|
||||||
|
this.finishNode(id, id.type);
|
||||||
|
|
||||||
|
this.semicolon();
|
||||||
|
|
||||||
|
return this.finishNode(node, "DeclareFunction");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseDeclare = function (node) {
|
||||||
|
if (this.type === tt._class) {
|
||||||
|
return this.flow_parseDeclareClass(node);
|
||||||
|
} else if (this.type === tt._function) {
|
||||||
|
return this.flow_parseDeclareFunction(node);
|
||||||
|
} else if (this.type === tt._var) {
|
||||||
|
return this.flow_parseDeclareVariable(node);
|
||||||
|
} else if (this.isContextual("module")) {
|
||||||
|
return this.flow_parseDeclareModule(node);
|
||||||
|
} else {
|
||||||
|
this.unexpected();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseDeclareVariable = function (node) {
|
||||||
|
this.next();
|
||||||
|
node.id = this.flow_parseTypeAnnotatableIdentifier();
|
||||||
|
this.semicolon();
|
||||||
|
return this.finishNode(node, "DeclareVariable");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseDeclareModule = function (node) {
|
||||||
|
this.next();
|
||||||
|
|
||||||
|
if (this.type === tt.string) {
|
||||||
|
node.id = this.parseExprAtom();
|
||||||
|
} else {
|
||||||
|
node.id = this.parseIdent();
|
||||||
|
}
|
||||||
|
|
||||||
|
var bodyNode = node.body = this.startNode();
|
||||||
|
var body = bodyNode.body = [];
|
||||||
|
this.expect(tt.braceL);
|
||||||
|
while (this.type !== tt.braceR) {
|
||||||
|
var node2 = this.startNode();
|
||||||
|
|
||||||
|
// todo: declare check
|
||||||
|
this.next();
|
||||||
|
|
||||||
|
body.push(this.flow_parseDeclare(node2));
|
||||||
|
}
|
||||||
|
this.expect(tt.braceR);
|
||||||
|
|
||||||
|
this.finishNode(bodyNode, "BlockStatement");
|
||||||
|
return this.finishNode(node, "DeclareModule");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Interfaces
|
||||||
|
|
||||||
|
pp.flow_parseInterfaceish = function (node, allowStatic) {
|
||||||
|
node.id = this.parseIdent();
|
||||||
|
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
} else {
|
||||||
|
node.typeParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.extends = [];
|
||||||
|
|
||||||
|
if (this.eat(tt._extends)) {
|
||||||
|
do {
|
||||||
|
node.extends.push(this.flow_parseInterfaceExtends());
|
||||||
|
} while(this.eat(tt.comma));
|
||||||
|
}
|
||||||
|
|
||||||
|
node.body = this.flow_parseObjectType(allowStatic);
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseInterfaceExtends = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
|
||||||
|
node.id = this.parseIdent();
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterInstantiation();
|
||||||
|
} else {
|
||||||
|
node.typeParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.finishNode(node, "InterfaceExtends");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseInterface = function (node) {
|
||||||
|
this.flow_parseInterfaceish(node, false);
|
||||||
|
return this.finishNode(node, "InterfaceDeclaration");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type aliases
|
||||||
|
|
||||||
|
pp.flow_parseTypeAlias = function (node) {
|
||||||
|
node.id = this.parseIdent();
|
||||||
|
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
} else {
|
||||||
|
node.typeParameters = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.expect(tt.eq);
|
||||||
|
|
||||||
|
node.right = this.flow_parseType();
|
||||||
|
|
||||||
|
this.semicolon();
|
||||||
|
|
||||||
|
return this.finishNode(node, "TypeAlias");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type annotations
|
||||||
|
|
||||||
|
pp.flow_parseTypeParameterDeclaration = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
node.params = [];
|
||||||
|
|
||||||
|
this.expectRelational("<");
|
||||||
|
while (!this.isRelational(">")) {
|
||||||
|
node.params.push(this.flow_parseTypeAnnotatableIdentifier());
|
||||||
|
if (!this.isRelational(">")) {
|
||||||
|
this.expect(tt.comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.expectRelational(">");
|
||||||
|
|
||||||
|
return this.finishNode(node, "TypeParameterDeclaration");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseTypeParameterInstantiation = function () {
|
||||||
|
var node = this.startNode(), oldInType = this.inType;
|
||||||
|
node.params = [];
|
||||||
|
|
||||||
|
this.inType = true;
|
||||||
|
|
||||||
|
this.expectRelational("<");
|
||||||
|
while (!this.isRelational(">")) {
|
||||||
|
node.params.push(this.flow_parseType());
|
||||||
|
if (!this.isRelational(">")) {
|
||||||
|
this.expect(tt.comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.expectRelational(">");
|
||||||
|
|
||||||
|
this.inType = oldInType;
|
||||||
|
|
||||||
|
return this.finishNode(node, "TypeParameterInstantiation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectPropertyKey = function () {
|
||||||
|
return (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectTypeIndexer = function (node, isStatic) {
|
||||||
|
node.static = isStatic;
|
||||||
|
|
||||||
|
this.expect(tt.bracketL);
|
||||||
|
node.id = this.flow_parseObjectPropertyKey();
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.key = this.flow_parseType();
|
||||||
|
this.expect(tt.bracketR);
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.value = this.flow_parseType();
|
||||||
|
|
||||||
|
return this.finishNode(node, "ObjectTypeIndexer");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectTypeMethodish = function (node) {
|
||||||
|
node.params = [];
|
||||||
|
node.rest = null;
|
||||||
|
node.typeParameters = null;
|
||||||
|
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.expect(tt.parenL);
|
||||||
|
while (this.type === tt.name) {
|
||||||
|
node.params.push(this.flow_parseFunctionTypeParam());
|
||||||
|
if (this.type !== tt.parenR) {
|
||||||
|
this.expect(tt.comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.eat(tt.ellipsis)) {
|
||||||
|
node.rest = this.flow_parseFunctionTypeParam();
|
||||||
|
}
|
||||||
|
this.expect(tt.parenR);
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.returnType = this.flow_parseType();
|
||||||
|
|
||||||
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectTypeMethod = function (start, isStatic, key) {
|
||||||
|
var node = this.startNodeAt(start);
|
||||||
|
node.value = this.flow_parseObjectTypeMethodish(this.startNodeAt(start));
|
||||||
|
node.static = isStatic;
|
||||||
|
node.key = key;
|
||||||
|
node.optional = false;
|
||||||
|
return this.finishNode(node, "ObjectTypeProperty");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectTypeCallProperty = function (node, isStatic) {
|
||||||
|
var valueNode = this.startNode();
|
||||||
|
node.static = isStatic;
|
||||||
|
node.value = this.flow_parseObjectTypeMethodish(valueNode);
|
||||||
|
return this.finishNode(node, "ObjectTypeCallProperty");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseObjectType = function (allowStatic) {
|
||||||
|
var nodeStart = this.startNode();
|
||||||
|
var node;
|
||||||
|
var optional = false;
|
||||||
|
var property;
|
||||||
|
var propertyKey;
|
||||||
|
var propertyTypeAnnotation;
|
||||||
|
var token;
|
||||||
|
var isStatic;
|
||||||
|
|
||||||
|
nodeStart.callProperties = [];
|
||||||
|
nodeStart.properties = [];
|
||||||
|
nodeStart.indexers = [];
|
||||||
|
|
||||||
|
this.expect(tt.braceL);
|
||||||
|
|
||||||
|
while (this.type !== tt.braceR) {
|
||||||
|
var start = this.currentPos();
|
||||||
|
node = this.startNode();
|
||||||
|
if (allowStatic && this.isContextual("static")) {
|
||||||
|
this.next();
|
||||||
|
isStatic = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === tt.bracketL) {
|
||||||
|
nodeStart.indexers.push(this.flow_parseObjectTypeIndexer(node, isStatic));
|
||||||
|
} else if (this.type === tt.parenL || this.isRelational("<")) {
|
||||||
|
nodeStart.callProperties.push(this.flow_parseObjectTypeCallProperty(node, allowStatic));
|
||||||
|
} else {
|
||||||
|
if (isStatic && this.type === tt.colon) {
|
||||||
|
propertyKey = this.parseIdent();
|
||||||
|
} else {
|
||||||
|
propertyKey = this.flow_parseObjectPropertyKey();
|
||||||
|
}
|
||||||
|
if (this.isRelational("<") || this.type === tt.parenL) {
|
||||||
|
// This is a method property
|
||||||
|
nodeStart.properties.push(this.flow_parseObjectTypeMethod(start, isStatic, propertyKey));
|
||||||
|
} else {
|
||||||
|
if (this.eat(tt.question)) {
|
||||||
|
optional = true;
|
||||||
|
}
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.key = propertyKey;
|
||||||
|
node.value = this.flow_parseType();
|
||||||
|
node.optional = optional;
|
||||||
|
node.static = isStatic;
|
||||||
|
nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.eat(tt.semi) && this.type !== tt.braceR) {
|
||||||
|
this.unexpected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.expect(tt.braceR);
|
||||||
|
|
||||||
|
return this.finishNode(nodeStart, "ObjectTypeAnnotation")
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseGenericType = function (start, id) {
|
||||||
|
var node = this.startNodeAt(start);
|
||||||
|
|
||||||
|
node.typeParameters = null;
|
||||||
|
node.id = id;
|
||||||
|
|
||||||
|
while (this.eat(tt.dot)) {
|
||||||
|
var node2 = this.startNodeAt(start);
|
||||||
|
node2.qualification = node.id;
|
||||||
|
node2.id = this.parseIdent();
|
||||||
|
node.id = this.finishNode(node2, "QualifiedTypeIdentifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterInstantiation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.finishNode(node, "GenericTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseVoidType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
this.expect(tt._void);
|
||||||
|
return this.finishNode(node, "VoidTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseTypeofType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
this.expect(tt._typeof);
|
||||||
|
node.argument = this.flow_parsePrimaryType();
|
||||||
|
return this.finishNode(node, "TypeofTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseTupleType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
node.types = [];
|
||||||
|
this.expect(tt.bracketL);
|
||||||
|
// We allow trailing commas
|
||||||
|
while (this.pos < this.input.length && this.type !== tt.bracketR) {
|
||||||
|
node.types.push(this.flow_parseType());
|
||||||
|
if (this.type === tt.bracketR) break;
|
||||||
|
this.expect(tt.comma);
|
||||||
|
}
|
||||||
|
this.expect(tt.bracketR);
|
||||||
|
return this.finishNode(node, "TupleTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseFunctionTypeParam = function () {
|
||||||
|
var optional = false;
|
||||||
|
var node = this.startNode();
|
||||||
|
node.name = this.parseIdent();
|
||||||
|
if (this.eat(tt.question)) {
|
||||||
|
optional = true;
|
||||||
|
}
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.optional = optional;
|
||||||
|
node.typeAnnotation = this.flow_parseType();
|
||||||
|
return this.finishNode(node, "FunctionTypeParam");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseFunctionTypeParams = function () {
|
||||||
|
var ret = { params: [], rest: null };
|
||||||
|
while (this.type === tt.name) {
|
||||||
|
ret.params.push(this.flow_parseFunctionTypeParam());
|
||||||
|
if (this.type !== tt.parenR) {
|
||||||
|
this.expect(tt.comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.eat(tt.ellipsis)) {
|
||||||
|
ret.rest = this.flow_parseFunctionTypeParam();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_identToTypeAnnotation = function (start, node, id) {
|
||||||
|
switch (id.name) {
|
||||||
|
case "any":
|
||||||
|
return this.finishNode(node, "AnyTypeAnnotation");
|
||||||
|
|
||||||
|
case "bool":
|
||||||
|
case "boolean":
|
||||||
|
return this.finishNode(node, "BooleanTypeAnnotation");
|
||||||
|
|
||||||
|
case "number":
|
||||||
|
return this.finishNode(node, "NumberTypeAnnotation");
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
return this.finishNode(node, "StringTypeAnnotation");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return this.flow_parseGenericType(start, id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The parsing of types roughly parallels the parsing of expressions, and
|
||||||
|
// primary types are kind of like primary expressions...they're the
|
||||||
|
// primitives with which other types are constructed.
|
||||||
|
pp.flow_parsePrimaryType = function () {
|
||||||
|
var typeIdentifier = null;
|
||||||
|
var params = null;
|
||||||
|
var returnType = null;
|
||||||
|
var start = this.currentPos();
|
||||||
|
var node = this.startNode();
|
||||||
|
var rest = null;
|
||||||
|
var tmp;
|
||||||
|
var typeParameters;
|
||||||
|
var token;
|
||||||
|
var type;
|
||||||
|
var isGroupedType = false;
|
||||||
|
|
||||||
|
switch (this.type) {
|
||||||
|
case tt.name:
|
||||||
|
return this.flow_identToTypeAnnotation(start, node, this.parseIdent());
|
||||||
|
|
||||||
|
case tt.braceL:
|
||||||
|
return this.flow_parseObjectType();
|
||||||
|
|
||||||
|
case tt.bracketL:
|
||||||
|
return this.flow_parseTupleType();
|
||||||
|
|
||||||
|
case tt.relational:
|
||||||
|
if (this.value === "<") {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
this.expect(tt.parenL);
|
||||||
|
tmp = this.flow_parseFunctionTypeParams();
|
||||||
|
node.params = tmp.params;
|
||||||
|
node.rest = tmp.rest;
|
||||||
|
this.expect(tt.parenR);
|
||||||
|
|
||||||
|
this.expect(tt.arrow);
|
||||||
|
|
||||||
|
node.returnType = this.flow_parseType();
|
||||||
|
|
||||||
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
||||||
|
}
|
||||||
|
|
||||||
|
case tt.parenL:
|
||||||
|
this.next();
|
||||||
|
|
||||||
|
var tmpId;
|
||||||
|
|
||||||
|
// Check to see if this is actually a grouped type
|
||||||
|
if (this.type !== tt.parenR && this.type !== tt.ellipsis) {
|
||||||
|
if (this.type === tt.name) {
|
||||||
|
//raise(tokStart, "Grouped types are currently the only flow feature not supported, request it?");
|
||||||
|
//tmpId = identToTypeAnnotation(start, node, parseIdent());
|
||||||
|
//next();
|
||||||
|
//isGroupedType = this.type !== tt.question && this.type !== tt.colon;
|
||||||
|
} else {
|
||||||
|
isGroupedType = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGroupedType) {
|
||||||
|
if (tmpId && tt.parenR) {
|
||||||
|
type = tmpId;
|
||||||
|
} else {
|
||||||
|
type = this.flow_parseType();
|
||||||
|
this.expect(tt.parenR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we see a => next then someone was probably confused about
|
||||||
|
// function types, so we can provide a better error message
|
||||||
|
if (this.eat(tt.arrow)) {
|
||||||
|
this.raise(node,
|
||||||
|
"Unexpected token =>. It looks like " +
|
||||||
|
"you are trying to write a function type, but you ended up " +
|
||||||
|
"writing a grouped type followed by an =>, which is a syntax " +
|
||||||
|
"error. Remember, function type parameters are named so function " +
|
||||||
|
"types look like (name1: type1, name2: type2) => returnType. You " +
|
||||||
|
"probably wrote (type1) => returnType"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = this.flow_parseFunctionTypeParams();
|
||||||
|
node.params = tmp.params;
|
||||||
|
node.rest = tmp.rest;
|
||||||
|
|
||||||
|
this.expect(tt.parenR);
|
||||||
|
|
||||||
|
this.expect(tt.arrow);
|
||||||
|
|
||||||
|
node.returnType = this.flow_parseType();
|
||||||
|
node.typeParameters = null;
|
||||||
|
|
||||||
|
return this.finishNode(node, "FunctionTypeAnnotation");
|
||||||
|
|
||||||
|
case tt.string:
|
||||||
|
node.value = this.value;
|
||||||
|
node.raw = this.input.slice(this.start, this.end);
|
||||||
|
this.next();
|
||||||
|
return this.finishNode(node, "StringLiteralTypeAnnotation");
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (this.type.keyword) {
|
||||||
|
switch (this.type.keyword) {
|
||||||
|
case "void":
|
||||||
|
return this.flow_parseVoidType();
|
||||||
|
|
||||||
|
case "typeof":
|
||||||
|
return this.flow_parseTypeofType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.unexpected();
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parsePostfixType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
var type = node.elementType = this.flow_parsePrimaryType();
|
||||||
|
if (this.type === tt.bracketL) {
|
||||||
|
this.expect(tt.bracketL);
|
||||||
|
this.expect(tt.bracketR);
|
||||||
|
return this.finishNode(node, "ArrayTypeAnnotation");
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parsePrefixType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
if (this.eat(tt.question)) {
|
||||||
|
node.typeAnnotation = this.flow_parsePrefixType();
|
||||||
|
return this.finishNode(node, "NullableTypeAnnotation");
|
||||||
|
}
|
||||||
|
return this.flow_parsePostfixType();
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseIntersectionType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
var type = this.flow_parsePrefixType();
|
||||||
|
node.types = [type];
|
||||||
|
while (this.eat(tt.bitwiseAND)) {
|
||||||
|
node.types.push(this.flow_parsePrefixType());
|
||||||
|
}
|
||||||
|
return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseUnionType = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
var type = this.flow_parseIntersectionType();
|
||||||
|
node.types = [type];
|
||||||
|
while (this.eat(tt.bitwiseOR)) {
|
||||||
|
node.types.push(this.flow_parseIntersectionType());
|
||||||
|
}
|
||||||
|
return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseType = function () {
|
||||||
|
var oldInType = this.inType;
|
||||||
|
this.inType = true;
|
||||||
|
var type = this.flow_parseUnionType();
|
||||||
|
this.inType = oldInType;
|
||||||
|
return type;
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseTypeAnnotation = function () {
|
||||||
|
var node = this.startNode();
|
||||||
|
|
||||||
|
var oldInType = this.inType;
|
||||||
|
this.inType = true;
|
||||||
|
this.expect(tt.colon);
|
||||||
|
node.typeAnnotation = this.flow_parseType();
|
||||||
|
this.inType = oldInType;
|
||||||
|
|
||||||
|
return this.finishNode(node, "TypeAnnotation");
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.flow_parseTypeAnnotatableIdentifier = function (requireTypeAnnotation, canBeOptionalParam) {
|
||||||
|
var node = this.startNode();
|
||||||
|
var ident = this.parseIdent();
|
||||||
|
var isOptionalParam = false;
|
||||||
|
|
||||||
|
if (canBeOptionalParam && this.eat(tt.question)) {
|
||||||
|
this.expect(tt.question);
|
||||||
|
isOptionalParam = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requireTypeAnnotation || this.type === tt.colon) {
|
||||||
|
ident.typeAnnotation = this.flow_parseTypeAnnotation();
|
||||||
|
this.finishNode(ident, ident.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOptionalParam) {
|
||||||
|
ident.optional = true;
|
||||||
|
this.finishNode(ident, ident.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ident;
|
||||||
|
};
|
||||||
|
|
||||||
|
acorn.plugins.flow = function (instance) {
|
||||||
|
// function name(): string {}
|
||||||
|
instance.extend("parseFunctionBody", function (inner) {
|
||||||
|
return function (node, allowExpression) {
|
||||||
|
if (this.type === tt.colon) {
|
||||||
|
node.returnType = this.flow_parseTypeAnnotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return inner.call(this, node, allowExpression);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.extend("parseExpressionStatement", function (inner) {
|
||||||
|
return function (node, expr) {
|
||||||
|
if (expr.type === "Identifier") {
|
||||||
|
if (expr.name === "declare") {
|
||||||
|
if (this.type === tt._class || this.type === tt.name || this.type === tt._function || this.type === tt._var) {
|
||||||
|
return this.flow_parseDeclare(node);
|
||||||
|
}
|
||||||
|
} else if (this.type === tt.name) {
|
||||||
|
if (expr.name === "interface") {
|
||||||
|
return this.flow_parseInterface(node);
|
||||||
|
} else if (expr.name === "type") {
|
||||||
|
return this.flow_parseTypeAlias(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inner.call(this, node, expr);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.extend("parseParenItem", function (inner) {
|
||||||
|
return function (node, start) {
|
||||||
|
if (this.type === tt.colon) {
|
||||||
|
var typeCastNode = this.startNodeAt(start);
|
||||||
|
typeCastNode.expression = node;
|
||||||
|
typeCastNode.typeAnnotation = this.flow_parseTypeAnnotation();
|
||||||
|
return this.finishNode(typeCastNode, "TypeCastExpression");
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.extend("parseClassId", function (inner) {
|
||||||
|
return function (node, isStatement) {
|
||||||
|
inner.call(this, node, isStatement);
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.extend("parseClassSuper", function (inner) {
|
||||||
|
return function (node, isStatement) {
|
||||||
|
inner.call(this, node, isStatement);
|
||||||
|
if (node.superClass && this.isRelational("<")) {
|
||||||
|
node.superTypeParameters = this.flow_parseTypeParameterInstantiation();
|
||||||
|
}
|
||||||
|
if (this.isContextual("implements")) {
|
||||||
|
this.next();
|
||||||
|
var implemented = node.implements = [];
|
||||||
|
do {
|
||||||
|
var node = this.startNode();
|
||||||
|
node.id = this.parseIdent();
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterInstantiation();
|
||||||
|
} else {
|
||||||
|
node.typeParameters = null;
|
||||||
|
}
|
||||||
|
implemented.push(this.finishNode(node, "ClassImplements"));
|
||||||
|
} while(this.eat(tt.comma));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.extend("parseAssignableListItemTypes", function (inner) {
|
||||||
|
return function (param) {
|
||||||
|
if (this.eat(tt.question)) {
|
||||||
|
param.optional = true;
|
||||||
|
}
|
||||||
|
if (this.type === tt.colon) {
|
||||||
|
param.typeAnnotation = this.flow_parseTypeAnnotation();
|
||||||
|
}
|
||||||
|
this.finishNode(param, param.type);
|
||||||
|
return param;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// function foo<T>() {}
|
||||||
|
instance.extend("parseFunctionParams", function (inner) {
|
||||||
|
return function (node) {
|
||||||
|
if (this.isRelational("<")) {
|
||||||
|
node.typeParameters = this.flow_parseTypeParameterDeclaration();
|
||||||
|
}
|
||||||
|
inner.call(this, node);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// var foo: string = bar;
|
||||||
|
instance.extend("parseVarHead", function (inner) {
|
||||||
|
return function (decl) {
|
||||||
|
inner.call(this, decl);
|
||||||
|
if (this.type === tt.colon) {
|
||||||
|
decl.id.typeAnnotation = this.flow_parseTypeAnnotation();
|
||||||
|
this.finishNode(decl.id, decl.id.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
658
src/babel/parser/jsx.js
Normal file
658
src/babel/parser/jsx.js
Normal file
@ -0,0 +1,658 @@
|
|||||||
|
import acorn from "../../acorn";
|
||||||
|
|
||||||
|
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.currentPos();
|
||||||
|
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.currentPos();
|
||||||
|
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.currentPos();
|
||||||
|
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.currentPos();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -21,6 +21,9 @@ import path from "path";
|
|||||||
import each from "lodash/collection/each";
|
import each from "lodash/collection/each";
|
||||||
import * as t from "../../types";
|
import * as t from "../../types";
|
||||||
|
|
||||||
|
import "../../parser/jsx";
|
||||||
|
import "../../parser/flow";
|
||||||
|
|
||||||
var checkTransformerVisitor = {
|
var checkTransformerVisitor = {
|
||||||
enter(node, parent, scope, state) {
|
enter(node, parent, scope, state) {
|
||||||
checkNode(state.stack, node, scope);
|
checkNode(state.stack, node, scope);
|
||||||
@ -35,7 +38,7 @@ function checkNode(stack, node, scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class File {
|
export default class File {
|
||||||
constructor(opts) {
|
constructor(opts = {}) {
|
||||||
this.dynamicImportedNoDefault = [];
|
this.dynamicImportedNoDefault = [];
|
||||||
this.dynamicImportIds = {};
|
this.dynamicImportIds = {};
|
||||||
this.dynamicImported = [];
|
this.dynamicImported = [];
|
||||||
@ -46,8 +49,8 @@ export default class File {
|
|||||||
this.data = {};
|
this.data = {};
|
||||||
|
|
||||||
this.lastStatements = [];
|
this.lastStatements = [];
|
||||||
|
this.log = new Logger(this, opts.filename || "unknown");
|
||||||
this.opts = this.normalizeOptions(opts);
|
this.opts = this.normalizeOptions(opts);
|
||||||
this.log = new Logger(this);
|
|
||||||
this.ast = {};
|
this.ast = {};
|
||||||
|
|
||||||
this.buildTransformers();
|
this.buildTransformers();
|
||||||
@ -98,7 +101,7 @@ export default class File {
|
|||||||
if (key[0] === "_") continue;
|
if (key[0] === "_") continue;
|
||||||
|
|
||||||
let option = File.options[key];
|
let option = File.options[key];
|
||||||
if (!option) throw new ReferenceError(`Unknown option: ${key}`);
|
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let key in File.options) {
|
for (let key in File.options) {
|
||||||
@ -181,7 +184,7 @@ export default class File {
|
|||||||
each(transform.transformers, function (transformer, key) {
|
each(transform.transformers, function (transformer, key) {
|
||||||
var pass = transformers[key] = transformer.buildPass(file);
|
var pass = transformers[key] = transformer.buildPass(file);
|
||||||
|
|
||||||
if (pass.canRun) {
|
if (pass.canTransform) {
|
||||||
stack.push(pass);
|
stack.push(pass);
|
||||||
|
|
||||||
if (transformer.metadata.secondPass) {
|
if (transformer.metadata.secondPass) {
|
||||||
@ -274,7 +277,7 @@ export default class File {
|
|||||||
this.dynamicImported.push(declar);
|
this.dynamicImported.push(declar);
|
||||||
if (noDefault) this.dynamicImportedNoDefault.push(declar);
|
if (noDefault) this.dynamicImportedNoDefault.push(declar);
|
||||||
|
|
||||||
if (this.transformers["es6.modules"].canRun) {
|
if (this.transformers["es6.modules"].canTransform) {
|
||||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
||||||
} else {
|
} else {
|
||||||
this.dynamicImports.push(declar);
|
this.dynamicImports.push(declar);
|
||||||
@ -382,19 +385,27 @@ export default class File {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
var parseOpts = {};
|
var parseOpts = {
|
||||||
|
filename: opts.filename,
|
||||||
|
plugins: {}
|
||||||
|
};
|
||||||
|
|
||||||
var transformers = parseOpts.transformers = {};
|
var transformers = parseOpts.transformers = {};
|
||||||
for (var key in this.transformers) {
|
for (var key in this.transformers) {
|
||||||
transformers[key] = this.transformers[key].canRun;
|
transformers[key] = this.transformers[key].canParse;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseOpts.looseModules = this.isLoose("es6.modules");
|
parseOpts.looseModules = this.isLoose("es6.modules");
|
||||||
parseOpts.strictMode = this.transformers.strict.canRun;
|
parseOpts.strictMode = transformers.strict;
|
||||||
|
|
||||||
|
if (!opts.standardOnly) {
|
||||||
|
parseOpts.plugins.jsx = true;
|
||||||
|
parseOpts.plugins.flow = true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
return parse(opts, code, (tree) => {
|
return parse(parseOpts, code, (tree) => {
|
||||||
this.transform(tree);
|
this.transform(tree);
|
||||||
return this.generate();
|
return this.generate();
|
||||||
});
|
});
|
||||||
@ -424,7 +435,7 @@ export default class File {
|
|||||||
this.lastStatements = t.getLastStatements(ast.program);
|
this.lastStatements = t.getLastStatements(ast.program);
|
||||||
|
|
||||||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||||
if (modFormatter.init && this.transformers["es6.modules"].canRun) {
|
if (modFormatter.init && this.transformers["es6.modules"].canTransform) {
|
||||||
modFormatter.init();
|
modFormatter.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import * as util from "../../util";
|
import * as util from "../../util";
|
||||||
|
|
||||||
export default class Logger {
|
export default class Logger {
|
||||||
constructor(file: File) {
|
constructor(file: File, filename: string) {
|
||||||
this.filename = file.opts.filename;
|
this.filename = filename;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,6 +12,10 @@ export default class Logger {
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error(msg: string, Constructor = Error) {
|
||||||
|
throw new Constructor(this._buildMessage(msg));
|
||||||
|
}
|
||||||
|
|
||||||
deprecate(msg) {
|
deprecate(msg) {
|
||||||
if (!this.file.opts.suppressDeprecationMessages) {
|
if (!this.file.opts.suppressDeprecationMessages) {
|
||||||
console.error(msg);
|
console.error(msg);
|
||||||
|
|||||||
@ -228,14 +228,14 @@ export default class DefaultFormatter {
|
|||||||
|
|
||||||
// export { foo } from "test";
|
// export { foo } from "test";
|
||||||
nodes.push(this.buildExportsAssignment(
|
nodes.push(this.buildExportsAssignment(
|
||||||
t.getSpecifierName(specifier),
|
node.local,
|
||||||
ref,
|
ref,
|
||||||
node
|
node
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// export { foo };
|
// export { foo };
|
||||||
nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node));
|
nodes.push(this.buildExportsAssignment(specifier.local, specifier.exported, node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,6 @@ export default class AMDFormatter extends DefaultFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
importSpecifier(specifier, node, nodes) {
|
importSpecifier(specifier, node, nodes) {
|
||||||
var key = t.getSpecifierName(specifier);
|
|
||||||
var ref = this.getExternalReference(node);
|
var ref = this.getExternalReference(node);
|
||||||
|
|
||||||
if (includes(this.file.dynamicImportedNoDefault, node)) {
|
if (includes(this.file.dynamicImportedNoDefault, node)) {
|
||||||
@ -86,7 +85,7 @@ export default class AMDFormatter extends DefaultFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nodes.push(t.variableDeclaration("var", [
|
nodes.push(t.variableDeclaration("var", [
|
||||||
t.variableDeclarator(key, ref)
|
t.variableDeclarator(node.local, ref)
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,9 @@
|
|||||||
"EmptyStatement": ["Statement"],
|
"EmptyStatement": ["Statement"],
|
||||||
"LabeledStatement": ["Statement"],
|
"LabeledStatement": ["Statement"],
|
||||||
"VariableDeclaration": ["Statement", "Declaration"],
|
"VariableDeclaration": ["Statement", "Declaration"],
|
||||||
"ExportDeclaration": ["Statement", "Declaration", "ModuleDeclaration"],
|
"ExportAllDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||||
|
"ExportDefaultDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||||
|
"ExportNamedDeclaration": ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"],
|
||||||
"ImportDeclaration": ["Statement", "Declaration", "ModuleDeclaration"],
|
"ImportDeclaration": ["Statement", "Declaration", "ModuleDeclaration"],
|
||||||
"PrivateDeclaration": ["Statement", "Declaration"],
|
"PrivateDeclaration": ["Statement", "Declaration"],
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,6 @@ export function getBindingIdentifiers(node: Object): Object {
|
|||||||
|
|
||||||
if (t.isIdentifier(id)) {
|
if (t.isIdentifier(id)) {
|
||||||
ids[id.name] = id;
|
ids[id.name] = id;
|
||||||
} else if (t.isImportSpecifier(id)) {
|
|
||||||
search.push(id.name || id.id);
|
|
||||||
} else if (t.isExportDeclaration(id)) {
|
} else if (t.isExportDeclaration(id)) {
|
||||||
if (t.isDeclaration(node.declaration)) {
|
if (t.isDeclaration(node.declaration)) {
|
||||||
search.push(node.declaration);
|
search.push(node.declaration);
|
||||||
@ -38,7 +36,8 @@ export function getBindingIdentifiers(node: Object): Object {
|
|||||||
getBindingIdentifiers.keys = {
|
getBindingIdentifiers.keys = {
|
||||||
UnaryExpression: ["argument"],
|
UnaryExpression: ["argument"],
|
||||||
AssignmentExpression: ["left"],
|
AssignmentExpression: ["left"],
|
||||||
ImportBatchSpecifier: ["name"],
|
ImportSpecifier: ["local"],
|
||||||
|
ImportNamespaceSpecifier: ["local"],
|
||||||
VariableDeclarator: ["id"],
|
VariableDeclarator: ["id"],
|
||||||
FunctionDeclaration: ["id"],
|
FunctionDeclaration: ["id"],
|
||||||
FunctionExpression: ["id"],
|
FunctionExpression: ["id"],
|
||||||
@ -83,23 +82,3 @@ export function getLastStatements(node: Object): Array<Object> {
|
|||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Description
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function getSpecifierName(specifier: Object): Object {
|
|
||||||
return specifier.name || specifier.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function getSpecifierId(specifier: Object): Object {
|
|
||||||
if (specifier.default) {
|
|
||||||
return t.identifier("default");
|
|
||||||
} else {
|
|
||||||
return specifier.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -23,8 +23,10 @@
|
|||||||
"DoWhileStatement": ["body", "test"],
|
"DoWhileStatement": ["body", "test"],
|
||||||
"EmptyStatement": [],
|
"EmptyStatement": [],
|
||||||
"ExportBatchSpecifier": [],
|
"ExportBatchSpecifier": [],
|
||||||
"ExportDeclaration": ["declaration", "specifiers", "source"],
|
"ExportAllDeclaration": ["source"],
|
||||||
"ExportSpecifier": ["id", "name"],
|
"ExportDefaultDeclaration": ["declaration"],
|
||||||
|
"ExportNamedDeclaration": ["declaration", "specifiers", "source"],
|
||||||
|
"ExportSpecifier": ["local", "exported"],
|
||||||
"ExpressionStatement": ["expression"],
|
"ExpressionStatement": ["expression"],
|
||||||
"File": ["program"],
|
"File": ["program"],
|
||||||
"ForInStatement": ["left", "right", "body"],
|
"ForInStatement": ["left", "right", "body"],
|
||||||
@ -34,9 +36,9 @@
|
|||||||
"FunctionExpression": ["id", "params", "defaults", "rest", "body", "returnType", "typeParameters"],
|
"FunctionExpression": ["id", "params", "defaults", "rest", "body", "returnType", "typeParameters"],
|
||||||
"Identifier": ["typeAnnotation"],
|
"Identifier": ["typeAnnotation"],
|
||||||
"IfStatement": ["test", "consequent", "alternate"],
|
"IfStatement": ["test", "consequent", "alternate"],
|
||||||
"ImportBatchSpecifier": ["id"],
|
"ImportNamespaceSpecifier": ["local"],
|
||||||
"ImportDeclaration": ["specifiers", "source"],
|
"ImportDeclaration": ["specifiers", "source"],
|
||||||
"ImportSpecifier": ["id", "name"],
|
"ImportSpecifier": ["imported", "local"],
|
||||||
"LabeledStatement": ["label", "body"],
|
"LabeledStatement": ["label", "body"],
|
||||||
"Literal": [],
|
"Literal": [],
|
||||||
"LogicalExpression": ["left", "right"],
|
"LogicalExpression": ["left", "right"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user