initial commit

This commit is contained in:
Mahdi Dibaiee 2015-07-24 11:14:18 +04:30
commit a7e7ca0350
916 changed files with 101220 additions and 0 deletions

5
.jshintrc Normal file
View File

@ -0,0 +1,5 @@
{
"esnext": true,
"globalstrict": true,
"globals": ["module", "console", "process", "require"]
}

47
.tmp/test.js Normal file
View File

@ -0,0 +1,47 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var chai = _interopRequire(require("chai"));
var _dataStructuresTrie = require("../data-structures/trie");
var Node = _dataStructuresTrie.Node;
var Trie = _dataStructuresTrie.Trie;
chai.should();
test("Construct new Trie", function () {
var trie = new Trie();
trie.root.children.length.should.equal(0);
});
test("Add new parent values", function () {
var trie = new Trie();
trie.add("a");
trie.add("b");
trie.add("c");
trie.add("t");
trie.root.children.length.should.equal(4);
});
test("Adding values with existing parents", function () {
var trie = new Trie();
trie.add("a");
trie.add("ab");
trie.add("aba");
trie.add("abas");
var parent = trie.root;
for (var i = 0; i < 3; i++) {
parent.children.length.should.equal(1);
parent = parent.children[0];
}
parent.children.length.should.equal(0);
});

7
README.md Normal file
View File

@ -0,0 +1,7 @@
The algorithms are written in ES6, use `babel-node` to run them.
Most algorithms have a `-debug` version which includes logs and stuff to understand the algorithm runtime better.
I wanted to add tests for all algorithms but I haven't yet.
Feel free to fill an issue or create a pull request! 😜

View File

@ -0,0 +1,95 @@
'use strict';
import _ from '../utils';
class Node {
constructor(value) {
this.value = value;
this.right = null;
this.left = null;
}
}
class BinaryTree {
constructor(value) {
this.root = new Node(value);
this.length = 1;
}
search(key, node = this.root) {
if (!node || node.value === key) {
return node;
} else if (node.value > key) {
return this.search(key, node.left);
} else {
return this.search(key, node.right);
}
}
insert(value, node = this.root, parent = null, dir) {
if (!node) {
parent[dir] = new Node(value);
} else if (node.value > value) {
this.insert(value, node.left, node, 'left');
} else {
this.insert(value, node.right, node, 'right');
}
}
remove(value, node = this.root, parent = null) {
if (!node) {
return null;
}
// specified parent means we're recursing to delete, and
// checking has been already done
if (node.value === value || parent) {
// number of children, !! converts to boolean, + converts to number
// false yields 0, true yields 1
const children = +!!node.left + +!!node.right;
if (!children) {
parent.right = null;
} else if (children === 1) {
node = node.left || node.right;
} else {
node.value = node.right.value;
return this.remove(value, node.right, node, true);
}
} else if (node.value > value) {
return this.remove(value, node.left);
} else {
return this.remove(value, node.right);
}
}
// in-order
traverse(cb, node = this.root) {
if (!node) {
return;
}
// left
this.traverse(cb, node.left);
// parent
cb(node.value);
// right
this.traverse(cb, node.right);
}
}
let test = new BinaryTree(10);
test.insert(6);
test.insert(18);
test.insert(4);
test.insert(8);
test.insert(15);
test.insert(21);
_.inspect(test);
_.log('Traverse: ');
test.traverse(value => {
_.print(value + ' ');
});

View File

@ -0,0 +1,144 @@
'use strict';
import _ from '../utils';
export class Node {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
}
export class List {
constructor(root) {
this.root = root;
this.length = 1;
}
append(value) {
let node = this.root;
while (node.next !== null) {
node = node.next;
}
this.length++;
let newNode = new Node(value);
node.next = newNode;
return newNode;
}
delete(value, node = this.root) {
if (node === this.root && node.value === value) {
this.root = this.root.next;
return;
}
while (node.next) {
if (node.next.value === value) {
node.next = node.next.next;
this.length--;
}
node = node.next;
}
}
// Cracking the Coding Interview challenges
deleteDuplicates() {
let node = this.root;
do {
this.delete(node.value, node.next);
node = node.next;
} while (node.next !== null)
}
last(n) {
let target = this.length - n;
let i = 0;
let node = this.root;
while (i < target && node.next !== null) {
node = node.next;
i++;
}
return node;
}
partition(x) {
let less = [],
greater = [];
let node = this.root;
while (node !== null) {
if (node.value < x) {
less.push(node.value);
} else {
greater.push(node.value);
}
node = node.next;
}
this.root = new Node(less[0]);
less.slice(1).concat(greater).reduce((a, b) => {
a.next = new Node(b);
return a.next;
}, this.root);
}
}
// Cracking the Coding Interview 2.5
// Numbers are reversed (617 == 7 -> 1 -> 6 )
const addLists = (first, last) => {
let num = 0;
let nodes = [first.root, last.root];
let place = 1;
while (nodes[0] !== null) {
let currentSum = (nodes[0].value + nodes[1].value) * place;
place *= 10;
num += currentSum;
nodes = [nodes[0].next, nodes[1].next];
}
return num;
};
let test = new List(new Node(10, new Node(5)));
test.append(20);
test.append(8);
test.delete(10);
test.delete(20);
// Test deleteDuplicates
test.append(21);
let testNode = test.append(32);
test.append(21);
test.append(42);
test.append(21);
test.append(7);
test.deleteDuplicates();
// Test last-nth
_.log(test.last(2).value === 42);
// Test partition
_.log('Partition around 8');
test.partition(8);
_.log('Sum 7 -> 1 -> 6 AND 5 -> 9 -> 2');
let n1 = new List(new Node(7, new Node(1, new Node(6))));
let n2 = new List(new Node(5, new Node(9, new Node(2))));
_.log(addLists(n1, n2) === 912);
_.inspect(test);

View File

@ -0,0 +1,11 @@
import chai from 'chai';
import {Node, List} from '../linked-lists';
chai.should();
test('Constructing new Lists', () => {
let list = new List(new Node(10, new Node(5)));
list.root.value.should.equal(10);
list.root.next.value.should.equal(5);
});

View File

@ -0,0 +1,38 @@
import chai from 'chai';
import {Node, Trie} from '../trie';
chai.should();
test('Construct new Trie', () => {
let trie = new Trie();
trie.root.children.length.should.equal(0);
});
test('Add new parent values', () => {
let trie = new Trie();
trie.add('a');
trie.add('b');
trie.add('c');
trie.add('t');
trie.root.children.length.should.equal(4);
});
test('Adding values with existing parents', () => {
let trie = new Trie();
trie.add('a');
trie.add('ab');
trie.add('aba');
trie.add('abas');
let parent = trie.root;
for (let i = 0; i < 3; i++) {
parent.children.length.should.equal(1);
parent = parent.children[0];
}
parent.children.length.should.equal(0);
});

28
data-structures/trie.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
import _ from '../utils';
export class Node {
constructor(value) {
this.value = value;
this.children = [];
}
}
export class Trie {
constructor() {
this.root = new Node();
}
add(value, node = this.root, iteration = 0) {
let parent = node.children.find(n => {
return n.value[iteration] === value[iteration];
});
if (parent) {
this.add(value, parent, iteration + 1);
} else {
node.children.push(new Node(value));
}
}
}

10
index.js Normal file
View File

@ -0,0 +1,10 @@
var child = require('child_process'),
args = process.argv.slice(1);
if (args.indexOf('test') > -1) {
var path = args[2];
var tmp = '.tmp/test.js';
child.execSync('babel ' + path + ' > ' + tmp);
child.execSync('mocha ' + tmp);
}

View File

@ -0,0 +1,85 @@
'use strict';
import _ from '../utils';
let width = parseInt(_.args[0], 10) || 10,
height = parseInt(_.args[1], 10) || 10;
// Generate the two-dimensional array
let grid = new Array(width);
for(let i = 0; i < width; i++) {
grid[i] = new Array(height);
}
grid.width = width;
grid.height = height;
// define directions in bits so we can use bitwise flags
// to merge and compare
// left 1 right 2
// top 4 bottom 8
let directions = [1, 2, 4, 8];
let opposite = {
1: 2,
2: 1,
4: 8,
8: 4
};
// Used to sort randomly
const randomSort = () =>
Math.random() > 0.5 ? 1 : -1;
function walker(cx, cy, grid) {
_.debug(`walker running for ${cx}, ${cy}`);
let destination = directions.sort(randomSort);
destination.forEach(function(dir) {
_.debug(` - direction: ${dir}`);
// find the next block
let nx = cx + (dir === 1 ? -1 : dir === 2 ? 1 : 0),
ny = cy + (dir === 4 ? -1 : dir === 8 ? 1 : 0);
_.debug(` - trying next block nx=${nx} ny=${ny}`);
// Make sure the next block is in grid and we haven't visited it before
if(nx < grid.width && nx >= 0 && ny < grid.height && ny >= 0 && !grid[nx][ny]) {
_.debug(` - ${grid[cx][cy]} |= ${dir}`);
_.debug(` - ${grid[nx][ny]} |= ${opposite[dir]}`);
grid[cx][cy] |= dir;
grid[nx][ny] = opposite[dir];
walker(nx, ny, grid);
}
});
}
walker(0, 0, grid);
_.debug(grid);
function draw(grid) {
_.log(' ' + '_'.repeat(grid.width*2 - 1));
for(let i = 0; i < grid.width; i++) {
_.print('|');
for(let j = 0; j < grid.height; j++) {
let c = grid[i][j];
// bottom lines
if((c & 8) === 0) _.print(" ");
else _.print("_");
// right lines
if((c & 2) === 0) _.print(" ");
else _.print("|");
}
_.print('|');
_.print('\n');
}
}
draw(grid);

View File

@ -0,0 +1,75 @@
'use strict';
import _ from '../utils';
let width = parseInt(_.args[0], 10) || 10,
height = parseInt(_.args[1], 10) || 10;
// Generate the two-dimensional array
let grid = new Array(width);
for(let i = 0; i < width; i++) {
grid[i] = new Array(height);
}
grid.width = width;
grid.height = height;
// define directions in bits so we can use bitwise flags
// to merge and compare
// left 1 right 2
// top 4 bottom 8
let directions = [1, 2, 4, 8];
let opposite = {
1: 2,
2: 1,
4: 8,
8: 4
};
// Used to sort randomly
const randomSort = () =>
Math.random() > 0.5 ? 1 : -1;
function walker(cx, cy, grid) {
let destination = directions.sort(randomSort);
destination.forEach(function(dir) {
// find the next block
let nx = cx + (dir === 1 ? -1 : dir === 2 ? 1 : 0),
ny = cy + (dir === 4 ? -1 : dir === 8 ? 1 : 0);
// Make sure the next block is in grid and we haven't visited it before
if(nx < grid.width && nx >= 0 && ny < grid.height && ny >= 0 && !grid[nx][ny]) {
grid[cx][cy] |= dir;
grid[nx][ny] = opposite[dir];
walker(nx, ny, grid);
}
});
}
walker(0, 0, grid);
function draw(grid) {
_.log(' ' + '_'.repeat(grid.width*2 - 1));
for(let i = 0; i < grid.width; i++) {
_.print('|');
for(let j = 0; j < grid.height; j++) {
let c = grid[i][j];
// bottom lines
if((c & 8) === 0) _.print(" ");
else _.print("_");
// right lines
if((c & 2) === 0) _.print(" ");
else _.print("|");
}
_.print('|');
_.print('\n');
}
}
draw(grid);

5
node_modules/babel/README.md generated vendored Normal file
View File

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

142
node_modules/babel/bin/_babel-node generated vendored Normal file
View File

@ -0,0 +1,142 @@
#!/usr/bin/env node
var pathIsAbsolute = require("path-is-absolute");
var commander = require("commander");
var Module = require("module");
var babel = require("babel-core");
var inspect = require("util").inspect;
var path = require("path");
var repl = require("repl");
var util = require("babel-core").util;
var vm = require("vm");
var _ = require("lodash");
var program = new commander.Command("babel-node");
program.option("-e, --eval [script]", "Evaluate script");
program.option("-p, --print [code]", "Evaluate script and print result");
program.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx]");
program.option("-r, --stage [stage]", "Enable support for specific ECMAScript stages");
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
program.option("-o, --optional [optional]", "List of optional transformers to enable", util.list);
var pkg = require("../package.json");
program.version(pkg.version);
program.usage("[options] [ -e script | script.js ] [arguments]");
program.parse(process.argv);
//
babel.register({
extensions: program.extensions,
blacklist: program.blacklist,
whitelist: program.whitelist,
optional: program.optional,
ignore: program.ignore,
stage: program.stage,
});
//
var _eval = function (code, filename) {
if (!code) return undefined;
code = babel.transform(code, {
filename: filename,
blacklist: program.blacklist,
whitelist: program.whitelist,
optional: program.optional,
stage: program.stage
}).code;
return vm.runInThisContext(code, {
filename: filename
});
};
if (program.eval || program.print) {
var code = program.eval;
if (!code || code === true) code = program.print;
global.__filename = "[eval]";
global.__dirname = process.cwd();
var module = new Module(global.__filename);
module.filename = global.__filename;
module.paths = Module._nodeModulePaths(global.__dirname);
global.exports = module.exports;
global.module = module;
global.require = module.require.bind(module);
var result = _eval(code, global.__filename);
if (program.print) {
var output = _.isString(result) ? result : inspect(result);
process.stdout.write(output + "\n");
}
} else {
if (program.args.length) {
// slice all arguments up to the first filename since they're babel args that we handle
var args = process.argv.slice(2);
var i = 0;
var ignoreNext = false;
_.each(args, function (arg, i2) {
if (ignoreNext) {
ignoreNext = false;
return;
}
if (arg[0] === "-") {
var parsedArg = program[arg.slice(2)];
if (parsedArg && parsedArg !== true) {
ignoreNext = true;
}
} else {
i = i2;
return false;
}
});
args = args.slice(i);
// make the filename absolute
var filename = args[0];
if (!pathIsAbsolute(filename)) args[0] = path.join(process.cwd(), filename);
// add back on node and concat the sliced args
process.argv = ["node"].concat(args);
Module.runMain();
} else {
replStart();
}
}
function replStart() {
repl.start({
prompt: "> ",
input: process.stdin,
output: process.stdout,
eval: replEval,
useGlobal: true
});
}
function replEval(code, context, filename, callback) {
var err;
var result;
try {
if (code[0] === "(" && code[code.length - 1] === ")") {
code = code.slice(1, -1); // remove "(" and ")"
}
result = _eval(code, filename);
} catch (e) {
err = e;
}
callback(err, result);
}

13
node_modules/babel/bin/babel-external-helpers generated vendored Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env node
var commander = require("commander");
var util = require("babel-core").util;
var runtime = require("babel-core").buildExternalHelpers;
commander.option("-l, --whitelist [whitelist]", "Whitelist of helpers to ONLY include", util.list);
commander.option("-t, --output-type [type]", "Type of output (global|umd|var)", "global");
commander.usage("[options]");
commander.parse(process.argv);
console.log(runtime(commander.whitelist, commander.outputType));

448
node_modules/babel/bin/babel-node generated vendored Executable file
View File

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

78
node_modules/babel/bin/babel/dir.js generated vendored Normal file
View File

@ -0,0 +1,78 @@
var outputFileSync = require("output-file-sync");
var chokidar = require("chokidar");
var path = require("path");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
module.exports = function (commander, filenames, opts) {
var write = function (src, relative) {
// remove extension and then append back on .js
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
var dest = path.join(commander.outDir, relative);
var data = util.compile(src, {
sourceFileName: path.relative(dest + "/..", src)
});
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
var mapLoc = dest + ".map";
data.code = util.addSourceMappingUrl(data.code, mapLoc);
outputFileSync(mapLoc, JSON.stringify(data.map));
}
outputFileSync(dest, data.code);
console.log(src + " -> " + dest);
};
var handleFile = function (src, filename) {
if (util.shouldIgnore(src)) return;
if (util.canCompile(filename)) {
write(src, filename);
} else if (commander.copyFiles) {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
}
};
var handle = function (filename) {
if (!fs.existsSync(filename)) return;
var stat = fs.statSync(filename);
if (stat.isDirectory(filename)) {
var dirname = filename;
_.each(util.readdir(dirname), function (filename) {
var src = path.join(dirname, filename);
handleFile(src, filename);
});
} else {
write(filename, filename);
}
};
_.each(filenames, handle);
if (commander.watch) {
_.each(filenames, function (dirname) {
var watcher = chokidar.watch(dirname, {
persistent: true,
ignoreInitial: true
});
_.each(["add", "change"], function (type) {
watcher.on(type, function (filename) {
var relative = path.relative(dirname, filename) || filename;
try {
handleFile(filename, relative);
} catch (err) {
console.error(err.stack);
}
});
});
});
}
};

143
node_modules/babel/bin/babel/file.js generated vendored Normal file
View File

@ -0,0 +1,143 @@
var convertSourceMap = require("convert-source-map");
var sourceMap = require("source-map");
var chokidar = require("chokidar");
var path = require("path");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
module.exports = function (commander, filenames, opts) {
if (commander.sourceMaps === "inline") {
opts.sourceMaps = true;
}
var results = [];
var buildResult = function () {
var map = new sourceMap.SourceMapGenerator({
file: commander.outFile || "stdout"
});
var code = "";
var offset = 0;
_.each(results, function (result) {
var filename = result.filename;
code += result.code + "\n";
if (result.map) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
map._sources.add(filename);
map.setSourceContent(filename, result.actual);
consumer.eachMapping(function (mapping) {
map._mappings.add({
generatedLine: mapping.generatedLine + offset,
generatedColumn: mapping.generatedColumn,
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
source: filename
});
});
offset = code.split("\n").length;
}
});
if (commander.sourceMaps === "inline" || (!commander.outFile && commander.sourceMaps)) {
code += "\n" + convertSourceMap.fromObject(map).toComment();
}
return {
map: map,
code: code
};
};
var output = function () {
var result = buildResult();
if (commander.outFile) {
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
var mapLoc = commander.outFile + ".map";
result.code = util.addSourceMappingUrl(result.code, mapLoc);
fs.writeFileSync(mapLoc, JSON.stringify(result.map));
}
fs.writeFileSync(commander.outFile, result.code);
} else {
process.stdout.write(result.code + "\n");
}
};
var stdin = function () {
var code = "";
process.stdin.setEncoding("utf8");
process.stdin.on("readable", function () {
var chunk = process.stdin.read();
if (chunk !== null) code += chunk;
});
process.stdin.on("end", function () {
results.push(util.transform(commander.filename, code));
output();
});
};
var walk = function () {
var _filenames = [];
results = [];
_.each(filenames, function (filename) {
if (!fs.existsSync(filename)) return;
var stat = fs.statSync(filename);
if (stat.isDirectory()) {
var dirname = filename;
_.each(util.readdirFilter(filename), function (filename) {
_filenames.push(path.join(dirname, filename));
});
} else {
_filenames.push(filename);
}
});
_.each(_filenames, function (filename) {
if (util.shouldIgnore(filename)) return;
results.push(util.compile(filename));
});
output();
};
var files = function () {
walk();
if (commander.watch) {
chokidar.watch(filenames, {
persistent: true,
ignoreInitial: true
}).on("all", function (type, filename) {
if (type === "add" || type === "change") {
console.log(type, filename);
try {
walk();
} catch (err) {
console.error(err.stack);
}
}
});
}
};
if (filenames.length) {
files();
} else {
stdin();
}
};

122
node_modules/babel/bin/babel/index.js generated vendored Executable file
View File

@ -0,0 +1,122 @@
#!/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");
each(options, function (option, key) {
if (option.hidden) return;
var arg = kebabCase(key);
if (option.type !== "boolean") {
arg += " [" + (option.type || "string") + "]";
}
if (option.type === "boolean" && option.default === true) {
arg = "no-" + arg;
}
arg = "--" + arg;
if (option.shorthand) {
arg = "-" + option.shorthand + ", " + arg;
}
var desc = [];
if (option.deprecated) desc.push("[DEPRECATED] " + option.deprecated);
if (option.description) desc.push(option.description);
commander.option(arg, desc.join(" "));
})
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");
commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files");
commander.on("--help", function () {
var outKeys = function (title, obj) {
console.log(" " + title + ":");
console.log();
each(keys(obj).sort(), function (key) {
if (key[0] === "_") return;
if (obj[key].optional) key = "[" + key + "]";
console.log(" - " + key);
});
console.log();
};
outKeys("Transformers", transform.transformers);
outKeys("Module formatters", transform.moduleFormatters);
});
var pkg = require("../../package.json");
commander.version(pkg.version);
commander.usage("[options] <files ...>");
commander.parse(process.argv);
//
var errors = [];
var filenames = commander.args;
each(filenames, function (filename) {
if (!fs.existsSync(filename)) {
errors.push(filename + " doesn't exist");
}
});
if (commander.outDir && !filenames.length) {
errors.push("filenames required for --out-dir");
}
if (commander.outFile && commander.outDir) {
errors.push("cannot have --out-file and --out-dir");
}
if (commander.watch) {
if (!commander.outFile && !commander.outDir) {
errors.push("--watch requires --out-file or --out-dir");
}
if (!filenames.length) {
errors.push("--watch requires filenames");
}
}
if (errors.length) {
console.error(errors.join(". "));
process.exit(2);
}
//
var opts = exports.opts = {};
each(options, function (opt, key) {
opts[key] = commander[key];
});
opts.ignore = util.arrayify(opts.ignore, util.regexify);
opts.only = util.arrayify(opts.only, util.regexify);
var fn;
if (commander.outDir) {
fn = require("./dir");
} else {
fn = require("./file");
}
fn(commander, filenames, exports.opts);

42
node_modules/babel/bin/babel/util.js generated vendored Normal file
View File

@ -0,0 +1,42 @@
var readdir = require("fs-readdir-recursive");
var index = require("./index");
var babel = require("babel-core");
var util = require("babel-core").util;
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
exports.readdirFilter = function (filename) {
return readdir(filename).filter(function (filename) {
return util.canCompile(filename);
});
};
exports.readdir = readdir;
exports.canCompile = util.canCompile;
exports.shouldIgnore = function (loc) {
return util.shouldIgnore(loc, index.opts.ignore, index.opts.only);
};
exports.addSourceMappingUrl = function (code, loc) {
return code + "\n//# sourceMappingURL=" + path.basename(loc);
};
exports.transform = function (filename, code, opts) {
opts = _.defaults(opts || {}, index.opts);
opts.filename = filename;
opts.ignore = null;
opts.only = null;
var result = babel.transform(code, opts);
result.filename = filename;
result.actual = code;
return result;
};
exports.compile = function (filename, opts) {
var code = fs.readFileSync(filename, "utf8");
return exports.transform(filename, code, opts);
};

1
node_modules/babel/index.js generated vendored Normal file
View File

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

File diff suppressed because it is too large Load Diff

517
node_modules/babel/node_modules/babel-core/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,517 @@
# Changelog
> **Tags:**
> - [New Feature]
> - [Bug Fix]
> - [Spec Compliancy]
> - [Breaking Change]
> - [Documentation]
> - [Internal]
> - [Polish]
_Note: Gaps between patch versions are faulty/broken releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.1.11
* **Bug Fix**
* Memoise and bind member expression decorators.
* Move JSX children cleaning to opening element visitor. Fixes elements not being cleaned in certain scenarios.
* Consider `SwitchStatement`s to be `Scopable`.
* Fix `bluebirdCoroutines` calling `interopRequireWildcard` before it's defined.
* Add space to `do...while` code generation.
* Validate `super` use before `this` on `super` exit rather than entrance.
* **Polish**
* Add Babel name to logger.
## 5.1.10
* **Bug Fix**
* Remove `makePredicate` from acorn in favor of an `indexOf`.
* Remove statements to expression explosion when inserting a block statement.
* **Internal**
* Remove runtime compatibility check.
## 5.1.9
* **Bug Fix**
* Fix class property initializers with `undefined` values not being correctly writable.
* Fix self inferring generators incorrectly causing a stack error.
* Fix default export specifiers not triggering AMD `module` argument inclusion.
* Fix assignments not having their module references properly remapped.
* **Internal**
* Upgrade to latest `acorn`.
* **Polish**
* Make invalid LHS pattern error messages nicer.
## 5.1.8
* **Bug Fix**
* Only make parenthesized object pattern LHS illegal.
## 5.1.7
* **Internal**
* Add `parse` node API.
## 5.1.6
* **Bug Fix**
* Fix `runtime` built-in catchall not properly checking for local variables.
## 5.1.5
* **Internal**
* Bump `core-js` version.
## 5.1.4
* **Polish**
* Add missing `Reflect` methods to runtime transformer.
## 5.1.3
* **Internal**
* Switch entirely to vanilla regenerator.
* Clean up and make the parsing of decorators stateless.
* **Bug Fix**
* Don't do TCO on generators and async functions.
* Add missing `core-js` runtime definitions.
## 5.1.2
* **Bug Fix**
* Add `getIterator` and `isIterable` to `babel-runtime` build script.
## 5.1.1
* **Bug Fix**
* Add missing runtime symbol definitions.
## 5.1.0
* **Bug Fix**
* Fix super reference when using decorators.
* Don't do array unpack optimisation when member expressions are present.
* Add missing descriptors for undecorated class properties.
* Don't consider `arguments` and `eval` valid function names when doing function name inferrence.
* Fix scope tracking of constants in loop heads.
* Parse `AwaitExpression` as a unary instead of an assignment.
* Fix regex evaluation when attempting static evaluation.
* Don't emit tokens when doing a lookahead.
* Add missing `test` declaration to `utility.deadCodeElimination` transformer.
* **Internal**
* Upgrade `regenerator` to the latest and use my branch with the hope of eventually switching to vanilla regenerator.
* Add support for the replacement of for loop `init`s with statements.
* Upgrade dependencies.
* **Polish**
* When adding the scope IIFE when using default parameters, don't shadow the function expression, just `apply` `this` and `arguments` if necessary.
* Use path basename as non-default import fallback.
* **New Feature**
* Add [trailing function comma proposal](https://github.com/jeffmo/es-trailing-function-commas). Thanks [@AluisioASG](https://github.com/AluisioASG)!
* Add support for object literal decorators.
* Make core-js modular when using the `runtime` transformer.
## 5.0.12
* **Bug Fix**
* Fix incorrect remapping of module references inside of a function id redirection container.
## 5.0.11
* **Bug Fix**
* Fix new `for...of` loops not properly inheriting their original loop.
* **Internal**
* Disable scope instance cache.
* **Polish**
* Allow comments in `.babelrc` JSON.
## 5.0.9
* **Polish**
* Use `moduleId` for UMD global name if available.
* **Bug Fix**
* Fix UMD global `module` variable shadowing the `amd`/`common` `module` variable.
* Fix Flow param type annotation regression.
* Fix function name collision `toString` wrapper. Thanks [@alawatthe](https://github.com/alawatthe)!
## 5.0.8
* **Bug Fix**
* Fix falsy static class properties not being writable.
* Fix block scoping collisions not properly detecting modules and function clashes.
* Skip `this` before `super` for derived constructors on functions.
## 5.0.7
* **New Feature**
* Add `--ignore` and `--only` support to the CLI.
* **Bug Fix**
* Remove `HOMEPATH` environment variable from home resolution in `babel/register` cache.
* **Internal**
* Disable WIP path resolution introducing infinite recursion in some code examples.
* **Polish**
* Add live binding to CommonJS default imports.
## 5.0.6
* **Bug Fix**
* Fix mangling of import references that collide with properties on `Object.prototype`.
* Fix duplicate declarations incorrectly being reported for `var`.
## 5.0.5
* **Internal**
* Upgrade `core-js`.
* **Bug Fix**
* Fix arrays not being supported in `util.list`.
## 5.0.4
* **Polish**
* Check for top level `breakConfig` in `resolveRc`.
## 5.0.3
* **Bug Fix**
* Make relative location absolute before calling `resolveRc`.
* **Internal**
* Switch to global UID registry.
* Add `breakConfig` option to prevent Babel from erroring when hitting that option.
## 5.0.1
* **Bug Fix**
* Fix duplicate declaration regression.
* Fix not being able to call non-writable methods.
## 5.0.0
* **New Feature**
* Decorators based on [@wycat's](https://github.com/wycats) [stage 1 proposal](https://github.com/wycats/javascript-decorators).
* Class property initializers based on [@jeffmo's](https://github.com/jeffmo) [stage 0 proposal](https://gist.github.com/jeffmo/054df782c05639da2adb).
* Export extensions based on [@leebyron's](https://github.com/leebyron) [stage 1 proposal](https://github.com/leebyron/ecmascript-more-export-from).
* UMD module formatter now supports globals.
* Add `es3.runtime`, `optimisation.react.inlineElements` and `optimisation.react.constantElements` transformers.
* Add stage option that replaces the experimental one.
* Allow ES7 transformer to be enabled via `optional` instead of only via `stage`.
* Infer string quotes to use in the code generator.
* Consider `export { foo as default };` to be the same as `export default foo;`.
* Add `nonStandard` option that can be set to `false` to remove parser support for JSX and Flow.
* Add `jsxPragma` option.
* Automatically generate CLI options based on internal API options.
* Add support for `.babelrc` on absolute paths.
* Plugin API!
* **Internal**
* Export `options` in browser API.
* Rewritten parser.
* Don't block hoist when runtime transformer is enabled in system module formatter.
* Rewritten the internal traversal and node replacement API to use "paths" that abstracts out node relationships.
* **Polish**
* JSX output is now more inline with the official JSX transformer.
* Hoist block scoping IIFE - this improves memory usage and performance.
* Better IIFE detection - references are now checked to see if they're referencing the binding we're searching for.
* Check for import reassignments in constants transformer.
* Make method definitions with expression bodies illegal.
* Save register cache on tick instead of `SIGINT`.
* Enable strict mode on babel-node eval flag.
* **Bug Fixes**
* Add support for live bindings. This change also increases the reliablity of export specifier renaming.
* Add support for super update and non equals assignment expressions.
* Rename shadow constructor binding in classes.
* Seed next iteration bindings with previous fresh bindings when reassinging loop block scoped variables.
* Fix new expression spread referencing the wrong constructor.
* Call `resolveModuleSource` on dynamic imports.
* Added `param` to list of duplicate declaration kinds.
* **Breaking Changes**
* The Babel playground has been removed.
* ES7 Abstract References have been removed.
* Experimental option has been removed in favor of a stage option.
* Rename `returnUsedHelpers` to `metadataUsedHelpers`.
## 4.7.16
* **Bug Fix**
* Fix constructor spreading of typed arrays.
* Fix break/continue/return aliasing of non-loops in block scoping transformer.
## 4.7.15
* **Bug Fix**
* Fix constructor spreading of collections.
## 4.7.14
* **Bug Fix**
* Fix constructor spreading of `Promise`.
* **Internal**
* Deprecate remaining playground transformers and abstract references.
## 4.7.13
* **Bug Fix**
* Handle comments on use strict directives.
* Fix assignment patterns with a left side pattern.
* **Polish**
* Special case `this` when doing expression memoisation.
## 4.7.12
* **Bug Fix**
* Deprecate `playground.methodBinding`.
## 4.7.11
* **Bug Fix**
* Fix unicode regexes stripping their unicode flag before being passed on two `regexpu`.
## 4.7.10
* **Internal**
* Deprecate `playground.methodBinding` and `playground.objectGetterMemoization`.
* **Bug Fix**
* Fix `inputSourceMap` option. Thanks [@Rich-Harris](https://github.com/Rich-Harris)!
## 4.7.9
* **Polish**
* Allow `inputSourceMap` to be set to `false` to skip the source map inference.
* Infer computed literal property names.
* **Bug Fix**
* Fix nested labeled for-ofs.
* Fix block scoping `break` colliding with the parent switch case.
* **Internal**
* Upgrade `acorn-babel`.
## 4.7.8
* **Bug Fix**
* Fix computed classes not properly setting symbols.
## 4.7.7
* **Bug Fix**
* Fix `types` API exposure.
## 4.7.6
* **Bug Fix**
* Fix non-Identifier/Literal computed class methods.
* **Polish**
* Add a fallback if `stack` on an error is unconfigurable.
* Hoist `esModule` module declarations to the top of the file to handle circular dependencies better.
## 4.7.5
* **Bug Fix**
* Don't remap` break`s to call the iterator return.
* **Polish**
* Use a different helper for computed classes for much nicer output. Also fixes a bug in symbols being non-enumerable so they wouldn't be set on the class.
## 4.7.4
* **Bug Fix**
* Rewrite named function expressions in optional async function transformers.
* Hoist directives.
* Remove `Number` from the list of valid `runtime` constructors.
* **Internal**
* `spec.typeofSymbol` transformer has been renamed to `es6.symbols`.
## 4.7.2
* **New Feature**
* `"both"` option for `sourceMap`.
* Add output types to external helpers. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
* **Bug Fix**
* Fix node duplication sometimes resulting in a recursion error.
* Ignore `break`s within cases inside `for...of`.
* **Polish**
* Split up variable declarations and export declarations to allow easier transformation.
## 4.7.0
* **Bug Fix**
* Add `alternate` to list of `STATEMENT_OR_BLOCK` keys.
* Add support for module specifiers to `t.isReferenced`.
* **New Feature**
* Add `inputSourceMap` option.
* **Polish**
* Throw an error on different `babel` and `babel-runtime` versions.
* Replicate module environment for `babel-node` eval.
* Clean up classes output.
* **Spec Compliancy**
* Make it illegal to use a rest parameter on a setter.
## 4.6.6
* **Bug Fix**
* Fix incorrect method call in `utility.deadCodeElimination` transformer.
* Fix `es6.blockScopingTDZ` transformer duplicating binding nodes.
## 4.6.5
* **Internal**
* `useStrict` transformer has been renamed to `strict`.
## 4.6.4
* **Bug Fix**
* Fix `ForOfStatement` not proplery inheriting labels.
* When in closure mode in block scoping transformer, properly check for variable shadowing.
* **New Feature**
* New `utility.inlineEnvironmentVariables` and `utility.inlineExpression` transformers.
## 4.6.3
* **Bug Fix**
* Fix `arguments` being incorrectly aliased in arrow function rest parameter optimisation.
* Make deoptimisation trigger safer.
* **New Feature**
* Flow types are now retained when blacklisting the `flow` transformer.
## 4.6.1
* **Bug Fix**
* Fix generators in template directory being transformed.
* Fix exposure of `util` for plugins.
## 4.6.0
* **New Feature**
* Desugar sticky regexes to a new constructor expression so it can be handled by a polyfill.
* **Spec Compliancy**
* `for...of` now outputs in a lengthy `try...catch` this is to ensure spec compliancy in regards to iterator returns and abrupt completions. See [google/traceur-compiler#1773](https://github.com/google/traceur-compiler/issues/1773) and [babel/babel/#838](https://github.com/babel/babel/issues/838) for more information.
* **Polish**
* Rest parameters that are only refered to via number properties on member expressions are desugared into a direct `arguments` reference. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
* `$ babel` no longer exits on syntax errors.
* **Internal**
* Upgrade `browserify`.
* Upgrade `source-map`.
* Publicly expose more internals.
## 4.5.5
* **Polish**
* Delete old extensions when overriding them in `babel/register`.
## 4.5.3
* **Bug Fix**
* Fix whitelisting logic for helper build script.
## 4.5.2
* **New Feature**
* `returnUsedHelpers` option and add whitelist to `buildHelpers`.
* **Bug Fix**
* Fix function arity on self referencing inferred named functions.
* **Internal**
* Bump `acorn-babel`.
* Start converting source to ES6...
## 4.5.1
**Babel now compiles itself!**
![holy shit](http://gifsec.com/wp-content/uploads/GIF/2014/03/OMG-GIF_2.gif)
## 4.5.0
* **New Feature**
* Add `.babelrc` support.
* **Bug Fix**
* Move use strict directives to the module formatter bodies.
* **Internal**
* Make default `bin/babel` behaviour to ignore non-compilable files and add a `--copy-files` flag to revert to the old behaviour.
## 4.4.6
* **Bug Fix**
* Fix extending a class expression with no methods/only constructor. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
* Allow `MemberExpression` as a valid `left` of `ForOfStatement`.
* **Polish**
* Throw an error when people try and transpile code with the `@jsx React.DOM` pragma as it conflicts with the custom jsx constructo method detection.
* Crawl all comments for `@jsx` pragma.
* **Internal**
* Upgrade `chalk`.
* Upgrade `core-js`.
## 4.4.5
* **Internal**
* Remove function self reference optimisation.
## 4.4.4
* **Bug Fix**
* Handle inferred function ids to be reassigned and deopt to a slower but working equivalent.
* Don't unpack array patterns that have more elements than their right hand array expression.
* **Polish**
* Improve syntax highlighting in the code frame. Thanks [@lydell](https://github.com/lydell)!
* **Internal**
* Upgrade `acorn-babel`.
## 4.4.3
* **Bug Fix**
* Fix `for...of` iterator break returns being duplicated.
* Only call `return` on the iterator if it exists.
* **Internal**
* Rename `selfContained` transformer to `runtime`.
## 4.4.2
* **New Feature**
* Add `moduleId` option for specifying a custom module id.
## 4.4.0
* **New Feature**
* `/*** @jsx NAMESPACE **/` comments are now honored by the `react` transformer.
* `getModuleName` option.
* Infer function expression names. Thanks [@RReverser](https://github.com/RReverser)!
* **Bug Fix**
* Add proper control flow for tail recursion optimisation.
* **Internal**
* Remove useless `format` options and move the `format.compact` option to `format`.
* **Polish**
* Newline handling of the code generator has been heavily improved.
* Code generator now deopts whitespace if the input size is >100KB.
## 4.3.0
* **Breaking Change**
* Remove `commonStandard` module formatter and make it the default behaviour of all the strict module formatters.
## 4.2.1
* **Polish**
* Add auxiliary comment to let scoping closure flow control.
## 4.2.0
* **Polish**
* Use an assignment instead of a define for `__esModule` in loose mode.
* **Internal**
* Add error for `eval();` usage and enable strict mode for parsing.
## 4.1.0
* **New Feature**
* Add `BABEL_CACHE_PATH` and `BABEL_DISABLE_CACHE` environment variables.
* **Internal**
* Replace many internal util functions with modules. Thanks [@sindresorhus](https://github.com/sindresorhus)!
## 4.0.2
* **Bug Fix**
* Fix generators not properly propagating their internal declarations.
* **Polish**
* Update setter param length error message.
* Use ranges on dependencies.
## 4.0.0
* 6to5 is now known as Babel.
* Global helpers/runtime has now been given the more descriptive name of "external helpers".

View File

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

View File

@ -0,0 +1,166 @@
<p align="center">
<strong><a href="#setup">Setup</a></strong>
|
<strong><a href="#running-tests">Running tests</a></strong>
|
<strong><a href="#workflow">Workflow</a></strong>
|
<strong><a href="#dependencies">Dependencies</a></strong>
|
<strong><a href="#code-standards">Code Standards</a></strong>
</p>
----
# Contributing
Contributions are always welcome, no matter how large or small. Before
contributing, please read the
[code of conduct](https://github.com/babel/babel/blob/master/CODE_OF_CONDUCT.md).
## Developing
#### Setup
```sh
$ git clone https://github.com/babel/babel
$ cd babel
$ make bootstrap
```
Then you need to run:
```sh
$ make watch-core
```
This will compile Babel and then sit in the background and on file modification
recompile the necessary files. Babel itself is written in ES6. The source files
reside in `src/` and transpile to `lib/`
#### Running tests
You can run tests via:
```sh
$ make test
```
This is mostly overkill and you can limit the tests to a select few by directly
running them with `mocha`:
```sh
$ mocha test/core/transformation.js
```
Use mocha's `--grep` option to run a subset of tests by name:
```sh
$ mocha test/core/transformation.js --grep es7
```
If you don't have `mocha` installed globally, you can still use it from Babel's
dependencies in `node_modules`, but make sure `node_modules/.bin` is added to
your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) environment variable.
#### Workflow
* Fork the repository
* Clone your fork and change directory to it (`git clone git@github.com:yourUserName/babel.git && cd babel`)
* Install the project dependencies (`make bootstrap`)
* Link your forked clone (`npm link`)
* Develop your changes ensuring you're fetching updates from upstream often
* Ensure the test are passing (`make test`)
* Create new pull request explaining your proposed change or reference an issue in your commit message
#### Dependencies
+ [ast-types](http://ghub.io/ast-types) This is required to monkeypatch regenerators AST definitions. Could be improved in the future.
+ [chalk](http://ghub.io/chalk) This is used for terminal color highlighting for syntax errors.
+ [convert-source-map](http://ghub.io/convert-source-map) Turns a source map object into a comment etc.
+ [core-js](http://ghub.io/core-js) Used for the polyfill.
+ [debug](http://ghub.io/debug) Used to output debugging information when NODE_DEBUG is set to babel.
+ [detect-indent](http://ghub.io/detect-indent) This is used in the code generator so it can infer indentation.
+ [estraverse](http://ghub.io/estraverse) The only method on this is attachComments. I'd like to implement our own comment attachment algorithm eventually though.
+ [esutils](http://ghub.io/esutils) Various ES related utilities. Check whether something is a keyword etc.
+ [fs-readdir-recursive](http://ghub.io/fs-readdir-recursive) Recursively search a directory for.
+ [globals](http://ghub.io/globals) A list of JavaScript global variables. This is used by the scope tracking to check for colliding variables.
+ [is-integer](http://ghub.io/is-integer) Checks if something is an integer.
+ [js-tokens](http://ghub.io/js-tokens) This is used to get tokens for syntax error highlighting.
+ [leven](http://ghub.io/leven) A levenstein algorithm to determine how close a word is to another. This is used to offer suggestions when using the utility.undeclaredVariableCheck transformer.
+ [line-numbers](http://ghub.io/line-numbers) Used to produce the code frames in syntax errors.
+ [lodash](http://ghub.io/lodash) Used for various utilities.
+ [minimatch](http://ghub.io/minimatch) This is used to match glob-style ignore/only filters.
+ [output-file-sync](http://ghub.io/output-file-sync) Synchronously writes a file and create its ancestor directories if needed.
+ [path-is-absolute](http://ghub.io/path-is-absolute) Checks if a path is absolute. C:\foo and \foo are considered absolute.
+ [regenerator](http://ghub.io/regenerator) This is used to transform generators/async functions.
+ [regexpu](http://ghub.io/regexpu) Used to transform unicode regex patterns.
+ [repeating](http://ghub.io/repeating) Repeats a string.
+ [shebang-regex](http://ghub.io/shebang-regex) Literally just a regex that matches shebangs.
+ [slash](http://ghub.io/slash) Normalises path separators.
+ [source-map](http://ghub.io/source-map) Generates sourcemaps.
+ [source-map-support](http://ghub.io/source-map-support) Adds source map support to babel-node/babel/register.
+ [strip-json-comments](http://ghub.io/strip-json-comments) Remove comments from a JSON string. This is used for .babelrc files.
+ [to-fast-properties](http://ghub.io/to-fast-properties) A V8 trick to put an object into fast properties mode.
+ [trim-right](http://ghub.io/trim-right) Trims the rightside whitespace.
+ [user-home](http://ghub.io/user-home) Gets the users home directory. This is used to resolve the babel-node/babel/register cache.
#### Code Standards
* **General**
* Max of five arguments for functions
* Max depth of four nested blocks
* 2-spaced soft tabs
* **Naming**
* CamelCase all class names
* camelBack all variable names
* **Spacing**
* Spaces after all keywords
* Spaces before all left curly braces
* **Comments**
* Use JSDoc-style comments for methods
* Single-line comments for ambiguous code
* **Quotes**
* Always use double quotes
* Only use single quotes when the string contains a double quote
* **Declaration**
* No unused variables
* No pollution of global variables and prototypes

22
node_modules/babel/node_modules/babel-core/LICENSE generated vendored Normal file
View File

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

17
node_modules/babel/node_modules/babel-core/README.md generated vendored Normal file
View File

@ -0,0 +1,17 @@
<p align="center">
<a href="https://babeljs.io/">
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/logo.png" width="546">
</a>
</p>
<p align="center">
<strong>Babel</strong> is a compiler for writing next generation JavaScript.
</p>
<p align="center">
For questions and support please visit the <a href="https://gitter.im/babel/babel">gitter room</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
</p>
<p align="center">
For documentation and website issues please visit the <a href="https://github.com/babel/babel.github.io">babel.github.io</a> repo.
</p>

File diff suppressed because one or more lines are too long

72
node_modules/babel/node_modules/babel-core/browser.js generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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

View 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.

View File

@ -0,0 +1,44 @@
{
"name": "acorn",
"description": "ECMAScript parser",
"homepage": "https://github.com/marijnh/acorn",
"main": "src/index.js",
"version": "1.0.0",
"engines": {
"node": ">=0.4.0"
},
"maintainers": [
{
"name": "Marijn Haverbeke",
"email": "marijnh@gmail.com",
"web": "http://marijnhaverbeke.nl"
},
{
"name": "Ingvar Stepanyan",
"email": "me@rreverser.com",
"web": "http://rreverser.com/"
}
],
"repository": {
"type": "git",
"url": "https://github.com/marijnh/acorn.git"
},
"licenses": [
{
"type": "MIT",
"url": "https://raw.githubusercontent.com/marijnh/acorn/master/LICENSE"
}
],
"scripts": {
"test": "node test/run.js",
"prepublish": "node bin/prepublish.sh"
},
"bin": {
"acorn": "./bin/acorn"
},
"devDependencies": {
"babelify": "^5.0.4",
"browserify": "^9.0.3",
"unicode-7.0.0": "~0.1.5"
}
}

View File

@ -0,0 +1,826 @@
"use strict";
var acorn = require("..");
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();
this.flow_objectTypeSemicolon();
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;
this.flow_objectTypeSemicolon();
return this.finishNode(node, "ObjectTypeProperty");
};
pp.flow_parseObjectTypeCallProperty = function (node, isStatic) {
var valueNode = this.startNode();
node["static"] = isStatic;
node.value = this.flow_parseObjectTypeMethodish(valueNode);
this.flow_objectTypeSemicolon();
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.markPosition();
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;
this.flow_objectTypeSemicolon();
nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty"));
}
}
}
this.expect(tt.braceR);
return this.finishNode(nodeStart, "ObjectTypeAnnotation");
};
pp.flow_objectTypeSemicolon = function () {
if (!this.eat(tt.semi) && this.type !== tt.braceR) {
this.unexpected();
}
};
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.markPosition();
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();
// Check to see if this is actually a grouped type
if (this.type !== tt.parenR && this.type !== tt.ellipsis) {
if (this.type === tt.name) {
var token = this.lookahead().type;
isGroupedType = token !== tt.question && token !== tt.colon;
} else {
isGroupedType = true;
}
}
if (isGroupedType) {
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("parseStatement", function (inner) {
return function (declaration, topLevel) {
// strict mode handling of `interface` since it's a reserved word
if (this.strict && this.type === tt.name && this.value === "interface") {
var node = this.startNode();
this.next();
return this.flow_parseInterface(node);
} else {
return inner.call(this, declaration, topLevel);
}
};
});
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("shouldParseExportDeclaration", function (inner) {
return function () {
return this.isContextual("type") || inner.call(this);
};
});
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("readToken", function (inner) {
return function (code) {
if (this.inType && (code === 62 || code === 60)) {
return this.finishOp(tt.relational, 1);
} else {
return inner.call(this, code);
}
};
});
instance.extend("jsx_readToken", function (inner) {
return function () {
if (!this.inType) return inner.call(this);
};
});
instance.extend("parseParenArrowList", function (inner) {
return function (start, exprList, isAsync) {
for (var i = 0; i < exprList.length; i++) {
var listItem = exprList[i];
if (listItem.type === "TypeCastExpression") {
var expr = listItem.expression;
expr.typeAnnotation = listItem.typeAnnotation;
exprList[i] = expr;
}
}
return inner.call(this, start, exprList, isAsync);
};
});
instance.extend("parseClassProperty", function (inner) {
return function (node) {
if (this.type === tt.colon) {
node.typeAnnotation = this.flow_parseTypeAnnotation();
}
return inner.call(this, node);
};
});
instance.extend("isClassProperty", function (inner) {
return function () {
return this.type === tt.colon || inner.call(this);
};
});
instance.extend("parseClassMethod", function (inner) {
return function (classBody, method, isGenerator, isAsync) {
var typeParameters;
if (this.isRelational("<")) {
typeParameters = this.flow_parseTypeParameterDeclaration();
}
method.value = this.parseMethod(isGenerator, isAsync);
method.value.typeParameters = typeParameters;
classBody.body.push(this.finishNode(method, "MethodDefinition"));
};
});
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("parseObjPropValue", function (inner) {
return function (prop) {
var typeParameters;
if (this.isRelational("<")) {
typeParameters = this.flow_parseTypeParameterDeclaration();
if (this.type !== tt.parenL) this.unexpected();
}
inner.apply(this, arguments);
prop.value.typeParameters = typeParameters;
};
});
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;
};
});
instance.extend("parseImportSpecifiers", function (inner) {
return function (node) {
node.isType = false;
if (this.isContextual("type")) {
var start = this.markPosition();
var typeId = this.parseIdent();
if (this.type === tt.name && this.value !== "from" || this.type === tt.braceL || this.type === tt.star) {
node.isType = true;
} else {
node.specifiers.push(this.parseImportSpecifierDefault(typeId, start));
if (this.isContextual("from")) return;
this.eat(tt.comma);
}
}
inner.call(this, node);
};
});
// 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);
}
};
});
};

View File

@ -0,0 +1,637 @@
"use strict";
var acorn = require("..");
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: "\"",
amp: "&",
apos: "'",
lt: "<",
gt: ">",
nbsp: " ",
iexcl: "¡",
cent: "¢",
pound: "£",
curren: "¤",
yen: "¥",
brvbar: "¦",
sect: "§",
uml: "¨",
copy: "©",
ordf: "ª",
laquo: "«",
not: "¬",
shy: "­",
reg: "®",
macr: "¯",
deg: "°",
plusmn: "±",
sup2: "²",
sup3: "³",
acute: "´",
micro: "µ",
para: "¶",
middot: "·",
cedil: "¸",
sup1: "¹",
ordm: "º",
raquo: "»",
frac14: "¼",
frac12: "½",
frac34: "¾",
iquest: "¿",
Agrave: "À",
Aacute: "Á",
Acirc: "Â",
Atilde: "Ã",
Auml: "Ä",
Aring: "Å",
AElig: "Æ",
Ccedil: "Ç",
Egrave: "È",
Eacute: "É",
Ecirc: "Ê",
Euml: "Ë",
Igrave: "Ì",
Iacute: "Í",
Icirc: "Î",
Iuml: "Ï",
ETH: "Ð",
Ntilde: "Ñ",
Ograve: "Ò",
Oacute: "Ó",
Ocirc: "Ô",
Otilde: "Õ",
Ouml: "Ö",
times: "×",
Oslash: "Ø",
Ugrave: "Ù",
Uacute: "Ú",
Ucirc: "Û",
Uuml: "Ü",
Yacute: "Ý",
THORN: "Þ",
szlig: "ß",
agrave: "à",
aacute: "á",
acirc: "â",
atilde: "ã",
auml: "ä",
aring: "å",
aelig: "æ",
ccedil: "ç",
egrave: "è",
eacute: "é",
ecirc: "ê",
euml: "ë",
igrave: "ì",
iacute: "í",
icirc: "î",
iuml: "ï",
eth: "ð",
ntilde: "ñ",
ograve: "ò",
oacute: "ó",
ocirc: "ô",
otilde: "õ",
ouml: "ö",
divide: "÷",
oslash: "ø",
ugrave: "ù",
uacute: "ú",
ucirc: "û",
uuml: "ü",
yacute: "ý",
thorn: "þ",
yuml: "ÿ",
OElig: "Œ",
oelig: "œ",
Scaron: "Š",
scaron: "š",
Yuml: "Ÿ",
fnof: "ƒ",
circ: "ˆ",
tilde: "˜",
Alpha: "Α",
Beta: "Β",
Gamma: "Γ",
Delta: "Δ",
Epsilon: "Ε",
Zeta: "Ζ",
Eta: "Η",
Theta: "Θ",
Iota: "Ι",
Kappa: "Κ",
Lambda: "Λ",
Mu: "Μ",
Nu: "Ν",
Xi: "Ξ",
Omicron: "Ο",
Pi: "Π",
Rho: "Ρ",
Sigma: "Σ",
Tau: "Τ",
Upsilon: "Υ",
Phi: "Φ",
Chi: "Χ",
Psi: "Ψ",
Omega: "Ω",
alpha: "α",
beta: "β",
gamma: "γ",
delta: "δ",
epsilon: "ε",
zeta: "ζ",
eta: "η",
theta: "θ",
iota: "ι",
kappa: "κ",
lambda: "λ",
mu: "μ",
nu: "ν",
xi: "ξ",
omicron: "ο",
pi: "π",
rho: "ρ",
sigmaf: "ς",
sigma: "σ",
tau: "τ",
upsilon: "υ",
phi: "φ",
chi: "χ",
psi: "ψ",
omega: "ω",
thetasym: "ϑ",
upsih: "ϒ",
piv: "ϖ",
ensp: "",
emsp: "",
thinsp: "",
zwnj: "",
zwj: "",
lrm: "",
rlm: "",
ndash: "",
mdash: "—",
lsquo: "",
rsquo: "",
sbquo: "",
ldquo: "“",
rdquo: "”",
bdquo: "„",
dagger: "†",
Dagger: "‡",
bull: "•",
hellip: "…",
permil: "‰",
prime: "",
Prime: "″",
lsaquo: "",
rsaquo: "",
oline: "‾",
frasl: "",
euro: "€",
image: "",
weierp: "℘",
real: "",
trade: "™",
alefsym: "ℵ",
larr: "←",
uarr: "↑",
rarr: "→",
darr: "↓",
harr: "↔",
crarr: "↵",
lArr: "⇐",
uArr: "⇑",
rArr: "⇒",
dArr: "⇓",
hArr: "⇔",
forall: "∀",
part: "∂",
exist: "∃",
empty: "∅",
nabla: "∇",
isin: "∈",
notin: "∉",
ni: "∋",
prod: "∏",
sum: "∑",
minus: "",
lowast: "",
radic: "√",
prop: "∝",
infin: "∞",
ang: "∠",
and: "∧",
or: "",
cap: "∩",
cup: "",
int: "∫",
there4: "∴",
sim: "",
cong: "≅",
asymp: "≈",
ne: "≠",
equiv: "≡",
le: "≤",
ge: "≥",
sub: "⊂",
sup: "⊃",
nsub: "⊄",
sube: "⊆",
supe: "⊇",
oplus: "⊕",
otimes: "⊗",
perp: "⊥",
sdot: "⋅",
lceil: "⌈",
rceil: "⌉",
lfloor: "⌊",
rfloor: "⌋",
lang: "〈",
rang: "〉",
loz: "◊",
spades: "♠",
clubs: "♣",
hearts: "♥",
diams: "♦"
};
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

@ -0,0 +1,783 @@
// A recursive descent parser operates by defining functions for all
// syntactic elements, and recursively calling those, each function
// advancing the input stream and returning an AST node. Precedence
// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
// instead of `(!x)[1]` is handled by the fact that the parser
// function that parses unary prefix operators is called first, and
// in turn calls the function that parses `[]` subscripts — that
// way, it'll receive the node for `x[1]` already parsed, and wraps
// *that* in the unary operator node.
//
// Acorn uses an [operator precedence parser][opp] to handle binary
// operator precedence, because it is much more compact than using
// the technique outlined above, which uses different, nesting
// functions to specify precedence, for all of the ten binary
// precedence levels that JavaScript defines.
//
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
"use strict";
var tt = require("./tokentype").types;
var Parser = require("./state").Parser;
var reservedWords = require("./identifier").reservedWords;
var has = require("./util").has;
var pp = Parser.prototype;
// Check if property name clashes with already added.
// Object/class getters and setters are not allowed to clash —
// either with each other or with an init property — and in
// strict mode, init properties are also not allowed to be repeated.
pp.checkPropClash = function (prop, propHash) {
if (this.options.ecmaVersion >= 6) return;
var key = prop.key,
name = undefined;
switch (key.type) {
case "Identifier":
name = key.name;break;
case "Literal":
name = String(key.value);break;
default:
return;
}
var kind = prop.kind || "init",
other = undefined;
if (has(propHash, name)) {
other = propHash[name];
var isGetSet = kind !== "init";
if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(key.start, "Redefinition of property");
} else {
other = propHash[name] = {
init: false,
get: false,
set: false
};
}
other[kind] = true;
};
// ### Expression parsing
// These nest, from the most general expression type at the top to
// 'atomic', nondivisible expression types at the bottom. Most of
// the functions will simply let the function(s) below them parse,
// and, *if* the syntactic construct they handle is present, wrap
// the AST node that the inner parser gave them in another node.
// Parse a full expression. The optional arguments are used to
// forbid the `in` operator (in for loops initalization expressions)
// and provide reference for storing '=' operator inside shorthand
// property assignment in contexts where both object expression
// and object pattern might appear (so it's possible to raise
// delayed syntax error at correct position).
pp.parseExpression = function (noIn, refShorthandDefaultPos) {
var start = this.markPosition();
var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
if (this.type === tt.comma) {
var node = this.startNodeAt(start);
node.expressions = [expr];
while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
return this.finishNode(node, "SequenceExpression");
}
return expr;
};
// Parse an assignment expression. This includes applications of
// operators like `+=`.
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
if (this.type == tt._yield && this.inGenerator) return this.parseYield();
var failOnShorthandAssign = undefined;
if (!refShorthandDefaultPos) {
refShorthandDefaultPos = { start: 0 };
failOnShorthandAssign = true;
} else {
failOnShorthandAssign = false;
}
var start = this.markPosition();
if (this.type == tt.parenL || this.type == tt.name) this.potentialArrowAt = this.start;
var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
if (afterLeftParse) left = afterLeftParse.call(this, left, start);
if (this.type.isAssign) {
var node = this.startNodeAt(start);
node.operator = this.value;
node.left = this.type === tt.eq ? this.toAssignable(left) : left;
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
this.checkLVal(left);
if (left.parenthesizedExpression) {
var errorMsg = undefined;
if (left.type === "ObjectPattern") {
errorMsg = "`({a}) = 0` use `({a} = 0)`";
} else if (left.type === "ArrayPattern") {
errorMsg = "`([a]) = 0` use `([a] = 0)`";
}
if (errorMsg) {
this.raise(left.start, "You're trying to assign to a parenthesized expression, eg. instead of " + errorMsg);
}
}
this.next();
node.right = this.parseMaybeAssign(noIn);
return this.finishNode(node, "AssignmentExpression");
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start);
}
return left;
};
// Parse a ternary conditional (`?:`) operator.
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
var start = this.markPosition();
var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
if (this.eat(tt.question)) {
var node = this.startNodeAt(start);
node.test = expr;
node.consequent = this.parseMaybeAssign();
this.expect(tt.colon);
node.alternate = this.parseMaybeAssign(noIn);
return this.finishNode(node, "ConditionalExpression");
}
return expr;
};
// Start the precedence parser.
pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
var start = this.markPosition();
var expr = this.parseMaybeUnary(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
return this.parseExprOp(expr, start, -1, noIn);
};
// Parse binary operators with the operator precedence parsing
// algorithm. `left` is the left-hand side of the operator.
// `minPrec` provides context that allows the function to stop and
// defer further parser to one of its callers when it encounters an
// operator that has a lower precedence than the set it is parsing.
pp.parseExprOp = function (left, leftStart, minPrec, noIn) {
var prec = this.type.binop;
if (prec != null && (!noIn || this.type !== tt._in)) {
if (prec > minPrec) {
var node = this.startNodeAt(leftStart);
node.left = left;
node.operator = this.value;
var op = this.type;
this.next();
var start = this.markPosition();
node.right = this.parseExprOp(this.parseMaybeUnary(), start, op.rightAssociative ? prec - 1 : prec, noIn);
this.finishNode(node, op === tt.logicalOR || op === tt.logicalAND ? "LogicalExpression" : "BinaryExpression");
return this.parseExprOp(node, leftStart, minPrec, noIn);
}
}
return left;
};
// Parse unary operators, both prefix and postfix.
pp.parseMaybeUnary = function (refShorthandDefaultPos) {
if (this.type.prefix) {
var node = this.startNode(),
update = this.type === tt.incDec;
node.operator = this.value;
node.prefix = true;
this.next();
node.argument = this.parseMaybeUnary();
if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
}
var start = this.markPosition();
var expr = this.parseExprSubscripts(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
while (this.type.postfix && !this.canInsertSemicolon()) {
var node = this.startNodeAt(start);
node.operator = this.value;
node.prefix = false;
node.argument = expr;
this.checkLVal(expr);
this.next();
expr = this.finishNode(node, "UpdateExpression");
}
return expr;
};
// Parse call, dot, and `[]`-subscript expressions.
pp.parseExprSubscripts = function (refShorthandDefaultPos) {
var start = this.markPosition();
var expr = this.parseExprAtom(refShorthandDefaultPos);
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
return this.parseSubscripts(expr, start);
};
pp.parseSubscripts = function (base, start, noCalls) {
if (this.eat(tt.dot)) {
var node = this.startNodeAt(start);
node.object = base;
node.property = this.parseIdent(true);
node.computed = false;
return this.parseSubscripts(this.finishNode(node, "MemberExpression"), start, noCalls);
} else if (this.eat(tt.bracketL)) {
var node = this.startNodeAt(start);
node.object = base;
node.property = this.parseExpression();
node.computed = true;
this.expect(tt.bracketR);
return this.parseSubscripts(this.finishNode(node, "MemberExpression"), start, noCalls);
} else if (!noCalls && this.eat(tt.parenL)) {
var node = this.startNodeAt(start);
node.callee = base;
node.arguments = this.parseExprList(tt.parenR, this.options.features["es7.trailingFunctionCommas"]);
return this.parseSubscripts(this.finishNode(node, "CallExpression"), start, noCalls);
} else if (this.type === tt.backQuote) {
var node = this.startNodeAt(start);
node.tag = base;
node.quasi = this.parseTemplate();
return this.parseSubscripts(this.finishNode(node, "TaggedTemplateExpression"), start, noCalls);
}return base;
};
// Parse an atomic expression — either a single token that is an
// expression, an expression started by a keyword like `function` or
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
// or `{}`.
pp.parseExprAtom = function (refShorthandDefaultPos) {
var node = undefined,
canBeArrow = this.potentialArrowAt == this.start;
switch (this.type) {
case tt._this:
case tt._super:
var type = this.type === tt._this ? "ThisExpression" : "Super";
node = this.startNode();
this.next();
return this.finishNode(node, type);
case tt._yield:
if (this.inGenerator) this.unexpected();
case tt._do:
if (this.options.features["es7.doExpressions"]) {
var _node = this.startNode();
this.next();
_node.body = this.parseBlock();
return this.finishNode(_node, "DoExpression");
}
case tt.name:
var start = this.markPosition();
node = this.startNode();
var id = this.parseIdent(this.type !== tt.name);
//
if (this.options.features["es7.asyncFunctions"]) {
// async functions!
if (id.name === "async") {
// arrow functions
if (this.type === tt.parenL) {
var expr = this.parseParenAndDistinguishExpression(start, true, true);
if (expr && expr.type === "ArrowFunctionExpression") {
return expr;
} else {
node.callee = id;
if (!expr) {
node.arguments = [];
} else if (expr.type === "SequenceExpression") {
node.arguments = expr.expressions;
} else {
node.arguments = [expr];
}
return this.parseSubscripts(this.finishNode(node, "CallExpression"), start);
}
} else if (this.type === tt.name) {
id = this.parseIdent();
this.expect(tt.arrow);
return this.parseArrowExpression(node, [id], true);
}
// normal functions
if (this.type === tt._function && !this.canInsertSemicolon()) {
this.next();
return this.parseFunction(node, false, false, true);
}
} else if (id.name === "await") {
if (this.inAsync) return this.parseAwait(node);
}
}
//
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) return this.parseArrowExpression(this.startNodeAt(start), [id]);
return id;
case tt.regexp:
var value = this.value;
node = this.parseLiteral(value.value);
node.regex = { pattern: value.pattern, flags: value.flags };
return node;
case tt.num:case tt.string:
return this.parseLiteral(this.value);
case tt._null:case tt._true:case tt._false:
node = this.startNode();
node.value = this.type === tt._null ? null : this.type === tt._true;
node.raw = this.type.keyword;
this.next();
return this.finishNode(node, "Literal");
case tt.parenL:
return this.parseParenAndDistinguishExpression(null, null, canBeArrow);
case tt.bracketL:
node = this.startNode();
this.next();
// check whether this is array comprehension or regular array
if ((this.options.ecmaVersion >= 7 || this.options.features["es7.comprehensions"]) && this.type === tt._for) {
return this.parseComprehension(node, false);
}
node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos);
return this.finishNode(node, "ArrayExpression");
case tt.braceL:
return this.parseObj(false, refShorthandDefaultPos);
case tt._function:
node = this.startNode();
this.next();
return this.parseFunction(node, false);
case tt.at:
this.parseDecorators();
case tt._class:
node = this.startNode();
this.takeDecorators(node);
return this.parseClass(node, false);
case tt._new:
return this.parseNew();
case tt.backQuote:
return this.parseTemplate();
default:
this.unexpected();
}
};
pp.parseLiteral = function (value) {
var node = this.startNode();
node.value = value;
node.raw = this.input.slice(this.start, this.end);
this.next();
return this.finishNode(node, "Literal");
};
pp.parseParenExpression = function () {
this.expect(tt.parenL);
var val = this.parseExpression();
this.expect(tt.parenR);
return val;
};
pp.parseParenAndDistinguishExpression = function (start, isAsync, canBeArrow) {
start = start || this.markPosition();
var val = undefined;
if (this.options.ecmaVersion >= 6) {
this.next();
if ((this.options.features["es7.comprehensions"] || this.options.ecmaVersion >= 7) && this.type === tt._for) {
return this.parseComprehension(this.startNodeAt(start), true);
}
var innerStart = this.markPosition(),
exprList = [],
first = true;
var refShorthandDefaultPos = { start: 0 },
spreadStart = undefined,
innerParenStart = undefined;
while (this.type !== tt.parenR) {
first ? first = false : this.expect(tt.comma);
if (this.type === tt.ellipsis) {
var spreadNodeStart = this.markPosition();
spreadStart = this.start;
exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStart));
break;
} else {
if (this.type === tt.parenL && !innerParenStart) {
innerParenStart = this.start;
}
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
}
}
var innerEnd = this.markPosition();
this.expect(tt.parenR);
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
if (innerParenStart) this.unexpected(innerParenStart);
return this.parseParenArrowList(start, exprList, isAsync);
}
if (!exprList.length) {
if (isAsync) {
return;
} else {
this.unexpected(this.lastTokStart);
}
}
if (spreadStart) this.unexpected(spreadStart);
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
if (exprList.length > 1) {
val = this.startNodeAt(innerStart);
val.expressions = exprList;
this.finishNodeAt(val, "SequenceExpression", innerEnd);
} else {
val = exprList[0];
}
} else {
val = this.parseParenExpression();
}
if (this.options.preserveParens) {
var par = this.startNodeAt(start);
par.expression = val;
return this.finishNode(par, "ParenthesizedExpression");
} else {
val.parenthesizedExpression = true;
return val;
}
};
pp.parseParenArrowList = function (start, exprList, isAsync) {
return this.parseArrowExpression(this.startNodeAt(start), exprList, isAsync);
};
pp.parseParenItem = function (node, start) {
return node;
};
// New's precedence is slightly tricky. It must allow its argument
// to be a `[]` or dot subscript expression, but not a call — at
// least, not without wrapping it in parentheses. Thus, it uses the
var empty = [];
pp.parseNew = function () {
var node = this.startNode();
var meta = this.parseIdent(true);
if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
node.meta = meta;
node.property = this.parseIdent(true);
if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
return this.finishNode(node, "MetaProperty");
}
var start = this.markPosition();
node.callee = this.parseSubscripts(this.parseExprAtom(), start, true);
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false);else node.arguments = empty;
return this.finishNode(node, "NewExpression");
};
// Parse template expression.
pp.parseTemplateElement = function () {
var elem = this.startNode();
elem.value = {
raw: this.input.slice(this.start, this.end),
cooked: this.value
};
this.next();
elem.tail = this.type === tt.backQuote;
return this.finishNode(elem, "TemplateElement");
};
pp.parseTemplate = function () {
var node = this.startNode();
this.next();
node.expressions = [];
var curElt = this.parseTemplateElement();
node.quasis = [curElt];
while (!curElt.tail) {
this.expect(tt.dollarBraceL);
node.expressions.push(this.parseExpression());
this.expect(tt.braceR);
node.quasis.push(curElt = this.parseTemplateElement());
}
this.next();
return this.finishNode(node, "TemplateLiteral");
};
// Parse an object literal or binding pattern.
pp.parseObj = function (isPattern, refShorthandDefaultPos) {
var node = this.startNode(),
first = true,
propHash = {};
node.properties = [];
var decorators = [];
this.next();
while (!this.eat(tt.braceR)) {
if (!first) {
this.expect(tt.comma);
if (this.afterTrailingComma(tt.braceR)) break;
} else first = false;
while (this.type === tt.at) {
decorators.push(this.parseDecorator());
}
var prop = this.startNode(),
isGenerator = false,
isAsync = false,
start = undefined;
if (decorators.length) {
prop.decorators = decorators;
decorators = [];
}
if (this.options.features["es7.objectRestSpread"] && this.type === tt.ellipsis) {
prop = this.parseSpread();
prop.type = "SpreadProperty";
node.properties.push(prop);
continue;
}
if (this.options.ecmaVersion >= 6) {
prop.method = false;
prop.shorthand = false;
if (isPattern || refShorthandDefaultPos) start = this.markPosition();
if (!isPattern) isGenerator = this.eat(tt.star);
}
if (this.options.features["es7.asyncFunctions"] && this.isContextual("async")) {
if (isGenerator || isPattern) this.unexpected();
var asyncId = this.parseIdent();
if (this.type === tt.colon || this.type === tt.parenL) {
prop.key = asyncId;
} else {
isAsync = true;
this.parsePropertyName(prop);
}
} else {
this.parsePropertyName(prop);
}
this.parseObjPropValue(prop, start, isGenerator, isAsync, isPattern, refShorthandDefaultPos);
this.checkPropClash(prop, propHash);
node.properties.push(this.finishNode(prop, "Property"));
}
if (decorators.length) {
this.raise(this.start, "You have trailing decorators with no property");
}
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
};
pp.parseObjPropValue = function (prop, start, isGenerator, isAsync, isPattern, refShorthandDefaultPos) {
if (this.eat(tt.colon)) {
prop.value = isPattern ? this.parseMaybeDefault() : this.parseMaybeAssign(false, refShorthandDefaultPos);
prop.kind = "init";
} else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
if (isPattern) this.unexpected();
prop.kind = "init";
prop.method = true;
prop.value = this.parseMethod(isGenerator, isAsync);
} else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != tt.comma && this.type != tt.braceR)) {
if (isGenerator || isAsync || isPattern) this.unexpected();
prop.kind = prop.key.name;
this.parsePropertyName(prop);
prop.value = this.parseMethod(false);
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
prop.kind = "init";
if (isPattern) {
if (this.isKeyword(prop.key.name) || this.strict && (reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
prop.value = this.parseMaybeDefault(start, prop.key);
} else if (this.type === tt.eq && refShorthandDefaultPos) {
if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
prop.value = this.parseMaybeDefault(start, prop.key);
} else {
prop.value = prop.key;
}
prop.shorthand = true;
} else this.unexpected();
};
pp.parsePropertyName = function (prop) {
if (this.options.ecmaVersion >= 6) {
if (this.eat(tt.bracketL)) {
prop.computed = true;
prop.key = this.parseMaybeAssign();
this.expect(tt.bracketR);
return;
} else {
prop.computed = false;
}
}
prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true);
};
// Initialize empty function node.
pp.initFunction = function (node, isAsync) {
node.id = null;
if (this.options.ecmaVersion >= 6) {
node.generator = false;
node.expression = false;
}
if (this.options.features["es7.asyncFunctions"]) {
node.async = !!isAsync;
}
};
// Parse object or class method.
pp.parseMethod = function (isGenerator, isAsync) {
var node = this.startNode();
this.initFunction(node, isAsync);
this.expect(tt.parenL);
node.params = this.parseBindingList(tt.parenR, false, false);
if (this.options.ecmaVersion >= 6) {
node.generator = isGenerator;
}
this.parseFunctionBody(node);
return this.finishNode(node, "FunctionExpression");
};
// Parse arrow function expression with given parameters.
pp.parseArrowExpression = function (node, params, isAsync) {
this.initFunction(node, isAsync);
node.params = this.toAssignableList(params, true);
this.parseFunctionBody(node, true);
return this.finishNode(node, "ArrowFunctionExpression");
};
// Parse function body and check parameters.
pp.parseFunctionBody = function (node, allowExpression) {
var isExpression = allowExpression && this.type !== tt.braceL;
var oldInAsync = this.inAsync;
this.inAsync = node.async;
if (isExpression) {
node.body = this.parseMaybeAssign();
node.expression = true;
} else {
// Start a new scope with regard to labels and the `inFunction`
// flag (restore them to their old value afterwards).
var oldInFunc = this.inFunction,
oldInGen = this.inGenerator,
oldLabels = this.labels;
this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
node.body = this.parseBlock(true);
node.expression = false;
this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
}
this.inAsync = oldInAsync;
// If this is a strict mode function, verify that argument names
// are not repeated, and it does not try to bind the words `eval`
// or `arguments`.
if (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
var nameHash = {},
oldStrict = this.strict;
this.strict = true;
if (node.id) this.checkLVal(node.id, true);
for (var i = 0; i < node.params.length; i++) {
this.checkLVal(node.params[i], true, nameHash);
}this.strict = oldStrict;
}
};
// Parses a comma-separated list of expressions, and returns them as
// an array. `close` is the token type that ends the list, and
// `allowEmpty` can be turned on to allow subsequent commas with
// nothing in between them to be parsed as `null` (which is needed
// for array literals).
pp.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
var elts = [],
first = true;
while (!this.eat(close)) {
if (!first) {
this.expect(tt.comma);
if (allowTrailingComma && this.afterTrailingComma(close)) break;
} else first = false;
if (allowEmpty && this.type === tt.comma) {
elts.push(null);
} else {
if (this.type === tt.ellipsis) elts.push(this.parseSpread(refShorthandDefaultPos));else elts.push(this.parseMaybeAssign(false, refShorthandDefaultPos));
}
}
return elts;
};
// Parse the next token as an identifier. If `liberal` is true (used
// when parsing properties), it will also convert keywords into
// identifiers.
pp.parseIdent = function (liberal) {
var node = this.startNode();
if (liberal && this.options.allowReserved == "never") liberal = false;
if (this.type === tt.name) {
if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
node.name = this.value;
} else if (liberal && this.type.keyword) {
node.name = this.type.keyword;
} else {
this.unexpected();
}
this.next();
return this.finishNode(node, "Identifier");
};
// Parses await expression inside async function.
pp.parseAwait = function (node) {
if (this.eat(tt.semi) || this.canInsertSemicolon()) {
this.unexpected();
}
node.all = this.eat(tt.star);
node.argument = this.parseMaybeUnary();
return this.finishNode(node, "AwaitExpression");
};
// Parses yield expression inside generator.
pp.parseYield = function () {
var node = this.startNode();
this.next();
if (this.type == tt.semi || this.canInsertSemicolon() || this.type != tt.star && !this.type.startsExpr) {
node.delegate = false;
node.argument = null;
} else {
node.delegate = this.eat(tt.star);
node.argument = this.parseMaybeAssign();
}
return this.finishNode(node, "YieldExpression");
};
// Parses array and generator comprehensions.
pp.parseComprehension = function (node, isGenerator) {
node.blocks = [];
while (this.type === tt._for) {
var block = this.startNode();
this.next();
this.expect(tt.parenL);
block.left = this.parseBindingAtom();
this.checkLVal(block.left, true);
this.expectContextual("of");
block.right = this.parseExpression();
this.expect(tt.parenR);
node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
}
node.filter = this.eat(tt._if) ? this.parseParenExpression() : null;
node.body = this.parseExpression();
this.expect(isGenerator ? tt.parenR : tt.bracketR);
node.generator = isGenerator;
return this.finishNode(node, "ComprehensionExpression");
};

View File

@ -0,0 +1,106 @@
// Test whether a given character code starts an identifier.
"use strict";
exports.isIdentifierStart = isIdentifierStart;
// Test whether a given character is part of an identifier.
exports.isIdentifierChar = isIdentifierChar;
exports.__esModule = true;
// This is a trick taken from Esprima. It turns out that, on
// non-Chrome browsers, to check whether a string is in a set, a
// predicate containing a big ugly `switch` statement is faster than
// a regular expression, and on Chrome the two are about on par.
// This function uses `eval` (non-lexical) to produce such a
// predicate from a space-separated string of words.
//
// It starts by sorting the words by length.
function makePredicate(words) {
words = words.split(" ");
return function (str) {
return words.indexOf(str) >= 0;
};
}
// Reserved word lists for various dialects of the language
var reservedWords = {
3: makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"),
5: makePredicate("class enum extends super const export import"),
6: makePredicate("enum await"),
strict: makePredicate("implements interface let package private protected public static yield"),
strictBind: makePredicate("eval arguments")
};
exports.reservedWords = reservedWords;
// And the keywords
var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
var keywords = {
5: makePredicate(ecma5AndLessKeywords),
6: makePredicate(ecma5AndLessKeywords + " let const class extends export import yield super")
};
exports.keywords = keywords;
// ## Character categories
// Big ugly regular expressions that match characters in the
// whitespace, identifier, and identifier-start categories. These
// are only applied when a character is found to actually have a
// code point above 128.
// Generated by `tools/generate-identifier-regex.js`.
var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA--zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
var nonASCIIidentifierChars = "‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍--_";
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
// These are a run-length and offset encoded representation of the
// >0xffff code points that are a valid part of identifiers. The
// offset starts at 0x10000, and each pair of numbers represents an
// offset to the next range, and then a size of the range. They were
// generated by tools/generate-identifier-regex.js
var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 4149, 196, 1340, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42710, 42, 4148, 12, 221, 16355, 541];
var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 9, 135, 4, 60, 6, 26, 9, 1016, 45, 17, 3, 19723, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 4305, 6, 792618, 239];
// This has a complexity linear to the value of the code. The
// assumption is that looking up astral identifier characters is
// rare.
function isInAstralSet(code, set) {
var pos = 65536;
for (var i = 0; i < set.length; i += 2) {
pos += set[i];
if (pos > code) return false;
pos += set[i + 1];
if (pos >= code) return true;
}
}
function isIdentifierStart(code, astral) {
if (code < 65) return code === 36;
if (code < 91) return true;
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 65535) return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes);
}
function isIdentifierChar(code, astral) {
if (code < 48) return code === 36;
if (code < 58) return true;
if (code < 65) return false;
if (code < 91) return true;
if (code < 97) return code === 95;
if (code < 123) return true;
if (code <= 65535) return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
if (astral === false) return false;
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
}

View File

@ -0,0 +1,124 @@
// The main exported interface (under `self.acorn` when in the
// browser) is a `parse` function that takes a code string and
// returns an abstract syntax tree as specified by [Mozilla parser
// API][api].
//
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
"use strict";
exports.parse = parse;
// This function tries to parse a single expression at a given
// offset in a string. Useful for parsing mixed-language formats
// that embed JavaScript expressions.
exports.parseExpressionAt = parseExpressionAt;
// Acorn is organized as a tokenizer and a recursive-descent parser.
// The `tokenize` export provides an interface to the tokenizer.
// Because the tokenizer is optimized for being efficiently used by
// the Acorn parser itself, this interface is somewhat crude and not
// very modular.
exports.tokenizer = tokenizer;
exports.__esModule = true;
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
//
// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
// various contributors and released under an MIT license.
//
// Git repositories for Acorn are available at
//
// http://marijnhaverbeke.nl/git/acorn
// https://github.com/marijnh/acorn.git
//
// Please use the [github bug tracker][ghbt] to report issues.
//
// [ghbt]: https://github.com/marijnh/acorn/issues
//
// This file defines the main parser interface. The library also comes
// with a [error-tolerant parser][dammit] and an
// [abstract syntax tree walker][walk], defined in other files.
//
// [dammit]: acorn_loose.js
// [walk]: util/walk.js
var _state = require("./state");
var Parser = _state.Parser;
var _options = require("./options");
var getOptions = _options.getOptions;
require("./parseutil");
require("./statement");
require("./lval");
require("./expression");
require("./lookahead");
exports.Parser = _state.Parser;
exports.plugins = _state.plugins;
exports.defaultOptions = _options.defaultOptions;
var _location = require("./location");
exports.SourceLocation = _location.SourceLocation;
exports.getLineInfo = _location.getLineInfo;
exports.Node = require("./node").Node;
var _tokentype = require("./tokentype");
exports.TokenType = _tokentype.TokenType;
exports.tokTypes = _tokentype.types;
var _tokencontext = require("./tokencontext");
exports.TokContext = _tokencontext.TokContext;
exports.tokContexts = _tokencontext.types;
var _identifier = require("./identifier");
exports.isIdentifierChar = _identifier.isIdentifierChar;
exports.isIdentifierStart = _identifier.isIdentifierStart;
exports.Token = require("./tokenize").Token;
var _whitespace = require("./whitespace");
exports.isNewLine = _whitespace.isNewLine;
exports.lineBreak = _whitespace.lineBreak;
exports.lineBreakG = _whitespace.lineBreakG;
require("../plugins/flow");
require("../plugins/jsx");
var version = "1.0.0";exports.version = version;
function parse(input, options) {
var p = parser(options, input);
var startPos = p.options.locations ? [p.pos, p.curPosition()] : p.pos;
p.nextToken();
return p.parseTopLevel(p.options.program || p.startNodeAt(startPos));
}
function parseExpressionAt(input, pos, options) {
var p = parser(options, input, pos);
p.nextToken();
return p.parseExpression();
}
function tokenizer(input, options) {
return parser(options, input);
}
function parser(options, input) {
return new Parser(getOptions(options), String(input));
}

View File

@ -0,0 +1,79 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
// The `getLineInfo` function is mostly useful when the
// `locations` option is off (for performance reasons) and you
// want to find the line/column position for a given character
// offset. `input` should be the code string that the offset refers
// into.
exports.getLineInfo = getLineInfo;
exports.__esModule = true;
var Parser = require("./state").Parser;
var lineBreakG = require("./whitespace").lineBreakG;
// These are used when `options.locations` is on, for the
// `startLoc` and `endLoc` properties.
var Position = exports.Position = (function () {
function Position(line, col) {
_classCallCheck(this, Position);
this.line = line;
this.column = col;
}
Position.prototype.offset = function offset(n) {
return new Position(this.line, this.column + n);
};
return Position;
})();
var SourceLocation = exports.SourceLocation = function SourceLocation(p, start, end) {
_classCallCheck(this, SourceLocation);
this.start = start;
this.end = end;
if (p.sourceFile !== null) this.source = p.sourceFile;
};
function getLineInfo(input, offset) {
for (var line = 1, cur = 0;;) {
lineBreakG.lastIndex = cur;
var match = lineBreakG.exec(input);
if (match && match.index < offset) {
++line;
cur = match.index + match[0].length;
} else {
return new Position(line, offset - cur);
}
}
}
var pp = Parser.prototype;
// This function is used to raise exceptions on parse errors. It
// takes an offset integer (into the current `input`) to indicate
// the location of the error, attaches the position to the end
// of the error message, and then raises a `SyntaxError` with that
// message.
pp.raise = function (pos, message) {
var loc = getLineInfo(this.input, pos);
message += " (" + loc.line + ":" + loc.column + ")";
var err = new SyntaxError(message);
err.pos = pos;err.loc = loc;err.raisedAt = this.pos;
throw err;
};
pp.curPosition = function () {
return new Position(this.curLine, this.pos - this.lineStart);
};
pp.markPosition = function () {
return this.options.locations ? [this.start, this.startLoc] : this.start;
};

View File

@ -0,0 +1,26 @@
"use strict";
var Parser = require("./state").Parser;
var pp = Parser.prototype;
var STATE_KEYS = ["lastTokStartLoc", "lastTokEndLoc", "lastTokStart", "lastTokEnd", "lineStart", "startLoc", "endLoc", "start", "pos", "end", "type", "value"];
pp.getState = function () {
var state = {};
for (var i = 0; i < STATE_KEYS.length; i++) {
var key = STATE_KEYS[i];
state[key] = this[key];
}
return state;
};
pp.lookahead = function () {
var old = this.getState();
this.isLookahead = true;
this.next();
this.isLookahead = false;
var curr = this.getState();
for (var key in old) this[key] = old[key];
return curr;
};

View File

@ -0,0 +1,201 @@
"use strict";
var tt = require("./tokentype").types;
var Parser = require("./state").Parser;
var reservedWords = require("./identifier").reservedWords;
var has = require("./util").has;
var pp = Parser.prototype;
// Convert existing expression atom to assignable pattern
// if possible.
pp.toAssignable = function (node, isBinding) {
if (this.options.ecmaVersion >= 6 && node) {
switch (node.type) {
case "Identifier":
case "ObjectPattern":
case "ArrayPattern":
case "AssignmentPattern":
break;
case "ObjectExpression":
node.type = "ObjectPattern";
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
this.toAssignable(prop.value, isBinding);
}
break;
case "ArrayExpression":
node.type = "ArrayPattern";
this.toAssignableList(node.elements, isBinding);
break;
case "AssignmentExpression":
if (node.operator === "=") {
node.type = "AssignmentPattern";
} else {
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
}
break;
case "MemberExpression":
if (!isBinding) break;
default:
this.raise(node.start, "Assigning to rvalue");
}
}
return node;
};
// Convert list of expression atoms to binding list.
pp.toAssignableList = function (exprList, isBinding) {
var end = exprList.length;
if (end) {
var last = exprList[end - 1];
if (last && last.type == "RestElement") {
--end;
} else if (last && last.type == "SpreadElement") {
last.type = "RestElement";
var arg = last.argument;
this.toAssignable(arg, isBinding);
if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
--end;
}
}
for (var i = 0; i < end; i++) {
var elt = exprList[i];
if (elt) this.toAssignable(elt, isBinding);
}
return exprList;
};
// Parses spread element.
pp.parseSpread = function (refShorthandDefaultPos) {
var node = this.startNode();
this.next();
node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
return this.finishNode(node, "SpreadElement");
};
pp.parseRest = function () {
var node = this.startNode();
this.next();
node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected();
return this.finishNode(node, "RestElement");
};
// Parses lvalue (assignable) atom.
pp.parseBindingAtom = function () {
if (this.options.ecmaVersion < 6) return this.parseIdent();
switch (this.type) {
case tt.name:
return this.parseIdent();
case tt.bracketL:
var node = this.startNode();
this.next();
node.elements = this.parseBindingList(tt.bracketR, true, true);
return this.finishNode(node, "ArrayPattern");
case tt.braceL:
return this.parseObj(true);
default:
this.unexpected();
}
};
pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
var elts = [],
first = true;
while (!this.eat(close)) {
if (first) first = false;else this.expect(tt.comma);
if (allowEmpty && this.type === tt.comma) {
elts.push(null);
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
break;
} else if (this.type === tt.ellipsis) {
elts.push(this.parseAssignableListItemTypes(this.parseRest()));
this.expect(close);
break;
} else {
var left = this.parseMaybeDefault();
this.parseAssignableListItemTypes(left);
elts.push(this.parseMaybeDefault(null, left));
}
}
return elts;
};
pp.parseAssignableListItemTypes = function (param) {
return param;
};
// Parses assignment pattern around given atom if possible.
pp.parseMaybeDefault = function (startPos, left) {
startPos = startPos || this.markPosition();
left = left || this.parseBindingAtom();
if (!this.eat(tt.eq)) return left;
var node = this.startNodeAt(startPos);
node.operator = "=";
node.left = left;
node.right = this.parseMaybeAssign();
return this.finishNode(node, "AssignmentPattern");
};
// Verify that a node is an lval — something that can be assigned
// to.
pp.checkLVal = function (expr, isBinding, checkClashes) {
switch (expr.type) {
case "Identifier":
if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
if (checkClashes) {
if (has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
checkClashes[expr.name] = true;
}
break;
case "MemberExpression":
if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
break;
case "ObjectPattern":
for (var i = 0; i < expr.properties.length; i++) {
var prop = expr.properties[i];
if (prop.type === "Property") prop = prop.value;
this.checkLVal(prop, isBinding, checkClashes);
}
break;
case "ArrayPattern":
for (var i = 0; i < expr.elements.length; i++) {
var elem = expr.elements[i];
if (elem) this.checkLVal(elem, isBinding, checkClashes);
}
break;
case "AssignmentPattern":
this.checkLVal(expr.left, isBinding, checkClashes);
break;
case "SpreadProperty":
case "RestElement":
this.checkLVal(expr.argument, isBinding, checkClashes);
break;
default:
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
}
};

View File

@ -0,0 +1,61 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
exports.__esModule = true;
var Parser = require("./state").Parser;
var SourceLocation = require("./location").SourceLocation;
// Start an AST node, attaching a start offset.
var pp = Parser.prototype;
var Node = exports.Node = function Node() {
_classCallCheck(this, Node);
};
pp.startNode = function () {
var node = new Node();
node.start = this.start;
if (this.options.locations) node.loc = new SourceLocation(this, this.startLoc);
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
if (this.options.ranges) node.range = [this.start, 0];
return node;
};
pp.startNodeAt = function (pos) {
var node = new Node(),
start = pos;
if (this.options.locations) {
node.loc = new SourceLocation(this, start[1]);
start = pos[0];
}
node.start = start;
if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
if (this.options.ranges) node.range = [start, 0];
return node;
};
// Finish an AST node, adding `type` and `end` properties.
pp.finishNode = function (node, type) {
node.type = type;
node.end = this.lastTokEnd;
if (this.options.locations) node.loc.end = this.lastTokEndLoc;
if (this.options.ranges) node.range[1] = this.lastTokEnd;
return node;
};
// Finish node at given position
pp.finishNodeAt = function (node, type, pos) {
if (this.options.locations) {
node.loc.end = pos[1];pos = pos[0];
}
node.type = type;
node.end = pos;
if (this.options.ranges) node.range[1] = pos;
return node;
};

View File

@ -0,0 +1,132 @@
// Interpret and default an options object
"use strict";
exports.getOptions = getOptions;
exports.__esModule = true;
var _util = require("./util");
var has = _util.has;
var isArray = _util.isArray;
var SourceLocation = require("./location").SourceLocation;
// A second optional argument can be given to further configure
// the parser process. These options are recognized:
var defaultOptions = {
// `ecmaVersion` indicates the ECMAScript version to parse. Must
// be either 3, or 5, or 6. This influences support for strict
// mode, the set of reserved words, support for getters and
// setters and other features.
ecmaVersion: 5,
// Source type ("script" or "module") for different semantics
sourceType: "script",
// `onInsertedSemicolon` can be a callback that will be called
// when a semicolon is automatically inserted. It will be passed
// th position of the comma as an offset, and if `locations` is
// enabled, it is given the location as a `{line, column}` object
// as second argument.
onInsertedSemicolon: null,
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
// trailing commas.
onTrailingComma: null,
// By default, reserved words are not enforced. Disable
// `allowReserved` to enforce them. When this option has the
// value "never", reserved words and keywords can also not be
// used as property names.
allowReserved: true,
// When enabled, a return at the top level is not considered an
// error.
allowReturnOutsideFunction: false,
// When enabled, import/export statements are not constrained to
// appearing at the top of the program.
allowImportExportEverywhere: false,
// When enabled, hashbang directive in the beginning of file
// is allowed and treated as a line comment.
allowHashBang: false,
// When `locations` is on, `loc` properties holding objects with
// `start` and `end` properties in `{line, column}` form (with
// line being 1-based and column 0-based) will be attached to the
// nodes.
locations: false,
// A function can be passed as `onToken` option, which will
// cause Acorn to call that function with object in the same
// format as tokenize() returns. Note that you are not
// allowed to call the parser from the callback—that will
// corrupt its internal state.
onToken: null,
// A function can be passed as `onComment` option, which will
// cause Acorn to call that function with `(block, text, start,
// end)` parameters whenever a comment is skipped. `block` is a
// boolean indicating whether this is a block (`/* */`) comment,
// `text` is the content of the comment, and `start` and `end` are
// character offsets that denote the start and end of the comment.
// When the `locations` option is on, two more parameters are
// passed, the full `{line, column}` locations of the start and
// end of the comments. Note that you are not allowed to call the
// parser from the callback—that will corrupt its internal state.
onComment: null,
// Nodes have their start and end characters offsets recorded in
// `start` and `end` properties (directly on the node, rather than
// the `loc` object, which holds line/column data. To also add a
// [semi-standardized][range] `range` property holding a `[start,
// end]` array with the same numbers, set the `ranges` option to
// `true`.
//
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
ranges: false,
// It is possible to parse multiple files into a single AST by
// passing the tree produced by parsing the first file as
// `program` option in subsequent parses. This will add the
// toplevel forms of the parsed file to the `Program` (top) node
// of an existing parse tree.
program: null,
// When `locations` is on, you can pass this to record the source
// file in every node's `loc` object.
sourceFile: null,
// This value, if given, is stored in every node, whether
// `locations` is on or off.
directSourceFile: null,
// When enabled, parenthesized expressions are represented by
// (non-standard) ParenthesizedExpression nodes
preserveParens: false,
plugins: {},
// Babel-specific options
features: {},
strictMode: null
};exports.defaultOptions = defaultOptions;
function getOptions(opts) {
var options = {};
for (var opt in defaultOptions) {
options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt];
}if (isArray(options.onToken)) {
(function () {
var tokens = options.onToken;
options.onToken = function (token) {
return tokens.push(token);
};
})();
}
if (isArray(options.onComment)) options.onComment = pushComment(options, options.onComment);
return options;
}
function pushComment(options, array) {
return function (block, text, start, end, startLoc, endLoc) {
var comment = {
type: block ? "Block" : "Line",
value: text,
start: start,
end: end
};
if (options.locations) comment.loc = new SourceLocation(this, startLoc, endLoc);
if (options.ranges) comment.range = [start, end];
array.push(comment);
};
}

View File

@ -0,0 +1,88 @@
"use strict";
var tt = require("./tokentype").types;
var Parser = require("./state").Parser;
var lineBreak = require("./whitespace").lineBreak;
var pp = Parser.prototype;
// ## Parser utilities
// Test whether a statement node is the string literal `"use strict"`.
pp.isUseStrict = function (stmt) {
return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
};
// Predicate that tests whether the next token is of the given
// type, and if yes, consumes it as a side effect.
pp.eat = function (type) {
if (this.type === type) {
this.next();
return true;
} else {
return false;
}
};
// Tests whether parsed token is a contextual keyword.
pp.isContextual = function (name) {
return this.type === tt.name && this.value === name;
};
// Consumes contextual keyword if possible.
pp.eatContextual = function (name) {
return this.value === name && this.eat(tt.name);
};
// Asserts that following token is given contextual keyword.
pp.expectContextual = function (name) {
if (!this.eatContextual(name)) this.unexpected();
};
// Test whether a semicolon can be inserted at the current position.
pp.canInsertSemicolon = function () {
return this.type === tt.eof || this.type === tt.braceR || lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
};
pp.insertSemicolon = function () {
if (this.canInsertSemicolon()) {
if (this.options.onInsertedSemicolon) this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc);
return true;
}
};
// Consume a semicolon, or, failing that, see if we are allowed to
// pretend that there is a semicolon at this position.
pp.semicolon = function () {
if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected();
};
pp.afterTrailingComma = function (tokType) {
if (this.type == tokType) {
if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
this.next();
return true;
}
};
// Expect a token of a given type. If found, consume it, otherwise,
// raise an unexpected token error.
pp.expect = function (type) {
this.eat(type) || this.unexpected();
};
// Raise an unexpected token error.
pp.unexpected = function (pos) {
this.raise(pos != null ? pos : this.start, "Unexpected token");
};

View File

@ -0,0 +1,90 @@
"use strict";
exports.Parser = Parser;
exports.__esModule = true;
var _identifier = require("./identifier");
var reservedWords = _identifier.reservedWords;
var keywords = _identifier.keywords;
var _tokentype = require("./tokentype");
var tt = _tokentype.types;
var lineBreak = _tokentype.lineBreak;
function Parser(options, input, startPos) {
this.options = options;
this.loadPlugins(this.options.plugins);
this.sourceFile = this.options.sourceFile || null;
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
this.isReservedWord = reservedWords[this.options.ecmaVersion];
this.input = input;
// Set up token state
// The current position of the tokenizer in the input.
if (startPos) {
this.pos = startPos;
this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
} else {
this.pos = this.lineStart = 0;
this.curLine = 1;
}
// Properties of the current token:
// Its type
this.type = tt.eof;
// For tokens that include more information than their type, the value
this.value = null;
// Its start and end offset
this.start = this.end = this.pos;
// And, if locations are used, the {line, column} object
// corresponding to those offsets
this.startLoc = this.endLoc = null;
// Position information for the previous token
this.lastTokEndLoc = this.lastTokStartLoc = null;
this.lastTokStart = this.lastTokEnd = this.pos;
// The context stack is used to superficially track syntactic
// context to predict whether a regular expression is allowed in a
// given position.
this.context = this.initialContext();
this.exprAllowed = true;
// Figure out if it's a module code.
this.inModule = this.options.sourceType === "module";
this.strict = this.options.strictMode === false ? false : this.inModule;
// Used to signify the start of a potential arrow function
this.potentialArrowAt = -1;
// Flags to track whether we are in a function, a generator.
this.inFunction = this.inGenerator = false;
// Labels in scope.
this.labels = [];
this.decorators = [];
// If enabled, skip leading hashbang line.
if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
}
Parser.prototype.extend = function (name, f) {
this[name] = f(this[name]);
};
// Registered plugins
var plugins = {};
exports.plugins = plugins;
Parser.prototype.loadPlugins = function (plugins) {
for (var _name in plugins) {
var plugin = exports.plugins[_name];
if (!plugin) throw new Error("Plugin '" + _name + "' not found");
plugin(this, plugins[_name]);
}
};

View File

@ -0,0 +1,752 @@
"use strict";
var tt = require("./tokentype").types;
var Parser = require("./state").Parser;
var lineBreak = require("./whitespace").lineBreak;
var pp = Parser.prototype;
// ### Statement parsing
// Parse a program. Initializes the parser, reads any number of
// statements, and wraps them in a Program node. Optionally takes a
// `program` argument. If present, the statements will be appended
// to its body instead of creating a new node.
pp.parseTopLevel = function (node) {
var first = true;
if (!node.body) node.body = [];
while (this.type !== tt.eof) {
var stmt = this.parseStatement(true, true);
node.body.push(stmt);
if (first && this.isUseStrict(stmt)) this.setStrict(true);
first = false;
}
this.next();
if (this.options.ecmaVersion >= 6) {
node.sourceType = this.options.sourceType;
}
return this.finishNode(node, "Program");
};
var loopLabel = { kind: "loop" },
switchLabel = { kind: "switch" };
// Parse a single statement.
//
// If expecting a statement and finding a slash operator, parse a
// regular expression literal. This is to handle cases like
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
// does not help.
pp.parseStatement = function (declaration, topLevel) {
if (this.type === tt.at) {
this.parseDecorators(true);
}
var starttype = this.type,
node = this.startNode();
// Most types of statements are recognized by the keyword they
// start with. Many are trivial to parse, some require a bit of
// complexity.
switch (starttype) {
case tt._break:case tt._continue:
return this.parseBreakContinueStatement(node, starttype.keyword);
case tt._debugger:
return this.parseDebuggerStatement(node);
case tt._do:
return this.parseDoStatement(node);
case tt._for:
return this.parseForStatement(node);
case tt._function:
if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
return this.parseFunctionStatement(node);
case tt._class:
if (!declaration) this.unexpected();
this.takeDecorators(node);
return this.parseClass(node, true);
case tt._if:
return this.parseIfStatement(node);
case tt._return:
return this.parseReturnStatement(node);
case tt._switch:
return this.parseSwitchStatement(node);
case tt._throw:
return this.parseThrowStatement(node);
case tt._try:
return this.parseTryStatement(node);
case tt._let:case tt._const:
if (!declaration) this.unexpected(); // NOTE: falls through to _var
case tt._var:
return this.parseVarStatement(node, starttype);
case tt._while:
return this.parseWhileStatement(node);
case tt._with:
return this.parseWithStatement(node);
case tt.braceL:
return this.parseBlock();
case tt.semi:
return this.parseEmptyStatement(node);
case tt._export:
case tt._import:
if (!this.options.allowImportExportEverywhere) {
if (!topLevel) this.raise(this.start, "'import' and 'export' may only appear at the top level");
if (!this.inModule) this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'");
}
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node);
case tt.name:
if (this.options.features["es7.asyncFunctions"] && this.value === "async" && this.lookahead().type === tt._function) {
this.next();
this.expect(tt._function);
return this.parseFunction(node, true, false, true);
}
// If the statement does not start with a statement keyword or a
// brace, it's an ExpressionStatement or LabeledStatement. We
// simply start parsing an expression, and afterwards, if the
// next token is a colon and the expression was a simple
// Identifier node, we switch to interpreting it as a label.
default:
var maybeName = this.value,
expr = this.parseExpression();
if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
}
};
pp.takeDecorators = function (node) {
if (this.decorators.length) {
node.decorators = this.decorators;
this.decorators = [];
}
};
pp.parseDecorators = function (allowExport) {
while (this.type === tt.at) {
this.decorators.push(this.parseDecorator());
}
if (allowExport && this.type === tt._export) {
return;
}
if (this.type !== tt._class) {
this.raise(this.start, "Leading decorators must be attached to a class declaration");
}
};
pp.parseDecorator = function (allowExport) {
if (!this.options.features["es7.decorators"]) {
this.unexpected();
}
var node = this.startNode();
this.next();
node.expression = this.parseMaybeAssign();
return this.finishNode(node, "Decorator");
};
pp.parseBreakContinueStatement = function (node, keyword) {
var isBreak = keyword == "break";
this.next();
if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== tt.name) this.unexpected();else {
node.label = this.parseIdent();
this.semicolon();
}
// Verify that there is an actual destination to break or
// continue to.
for (var i = 0; i < this.labels.length; ++i) {
var lab = this.labels[i];
if (node.label == null || lab.name === node.label.name) {
if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
if (node.label && isBreak) break;
}
}
if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword);
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
};
pp.parseDebuggerStatement = function (node) {
this.next();
this.semicolon();
return this.finishNode(node, "DebuggerStatement");
};
pp.parseDoStatement = function (node) {
var start = this.markPosition();
this.next();
this.labels.push(loopLabel);
node.body = this.parseStatement(false);
this.labels.pop();
if (this.options.features["es7.doExpressions"] && this.type !== tt._while) {
var container = this.startNodeAt(start);
container.expression = this.finishNode(node, "DoExpression");
this.semicolon();
return this.finishNode(container, "ExpressionStatement");
}
this.expect(tt._while);
node.test = this.parseParenExpression();
if (this.options.ecmaVersion >= 6) this.eat(tt.semi);else this.semicolon();
return this.finishNode(node, "DoWhileStatement");
};
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
// loop is non-trivial. Basically, we have to parse the init `var`
// statement or expression, disallowing the `in` operator (see
// the second parameter to `parseExpression`), and then check
// whether the next token is `in` or `of`. When there is no init
// part (semicolon immediately after the opening parenthesis), it
// is a regular `for` loop.
pp.parseForStatement = function (node) {
this.next();
this.labels.push(loopLabel);
this.expect(tt.parenL);
if (this.type === tt.semi) return this.parseFor(node, null);
if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
var _init = this.startNode(),
varKind = this.type;
this.next();
this.parseVar(_init, true, varKind);
this.finishNode(_init, "VariableDeclaration");
if ((this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== tt._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
return this.parseFor(node, _init);
}
var refShorthandDefaultPos = { start: 0 };
var init = this.parseExpression(true, refShorthandDefaultPos);
if (this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
this.toAssignable(init);
this.checkLVal(init);
return this.parseForIn(node, init);
} else if (refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start);
}
return this.parseFor(node, init);
};
pp.parseFunctionStatement = function (node) {
this.next();
return this.parseFunction(node, true);
};
pp.parseIfStatement = function (node) {
this.next();
node.test = this.parseParenExpression();
node.consequent = this.parseStatement(false);
node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
return this.finishNode(node, "IfStatement");
};
pp.parseReturnStatement = function (node) {
if (!this.inFunction && !this.options.allowReturnOutsideFunction) this.raise(this.start, "'return' outside of function");
this.next();
// In `return` (and `break`/`continue`), the keywords with
// optional arguments, we eagerly look for a semicolon or the
// possibility to insert one.
if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null;else {
node.argument = this.parseExpression();this.semicolon();
}
return this.finishNode(node, "ReturnStatement");
};
pp.parseSwitchStatement = function (node) {
this.next();
node.discriminant = this.parseParenExpression();
node.cases = [];
this.expect(tt.braceL);
this.labels.push(switchLabel);
// Statements under must be grouped (by label) in SwitchCase
// nodes. `cur` is used to keep the node that we are currently
// adding statements to.
for (var cur, sawDefault; this.type != tt.braceR;) {
if (this.type === tt._case || this.type === tt._default) {
var isCase = this.type === tt._case;
if (cur) this.finishNode(cur, "SwitchCase");
node.cases.push(cur = this.startNode());
cur.consequent = [];
this.next();
if (isCase) {
cur.test = this.parseExpression();
} else {
if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
sawDefault = true;
cur.test = null;
}
this.expect(tt.colon);
} else {
if (!cur) this.unexpected();
cur.consequent.push(this.parseStatement(true));
}
}
if (cur) this.finishNode(cur, "SwitchCase");
this.next(); // Closing brace
this.labels.pop();
return this.finishNode(node, "SwitchStatement");
};
pp.parseThrowStatement = function (node) {
this.next();
if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) this.raise(this.lastTokEnd, "Illegal newline after throw");
node.argument = this.parseExpression();
this.semicolon();
return this.finishNode(node, "ThrowStatement");
};
// Reused empty array added for node fields that are always empty.
var empty = [];
pp.parseTryStatement = function (node) {
this.next();
node.block = this.parseBlock();
node.handler = null;
if (this.type === tt._catch) {
var clause = this.startNode();
this.next();
this.expect(tt.parenL);
clause.param = this.parseBindingAtom();
this.checkLVal(clause.param, true);
this.expect(tt.parenR);
clause.guard = null;
clause.body = this.parseBlock();
node.handler = this.finishNode(clause, "CatchClause");
}
node.guardedHandlers = empty;
node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
return this.finishNode(node, "TryStatement");
};
pp.parseVarStatement = function (node, kind) {
this.next();
this.parseVar(node, false, kind);
this.semicolon();
return this.finishNode(node, "VariableDeclaration");
};
pp.parseWhileStatement = function (node) {
this.next();
node.test = this.parseParenExpression();
this.labels.push(loopLabel);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, "WhileStatement");
};
pp.parseWithStatement = function (node) {
if (this.strict) this.raise(this.start, "'with' in strict mode");
this.next();
node.object = this.parseParenExpression();
node.body = this.parseStatement(false);
return this.finishNode(node, "WithStatement");
};
pp.parseEmptyStatement = function (node) {
this.next();
return this.finishNode(node, "EmptyStatement");
};
pp.parseLabeledStatement = function (node, maybeName, expr) {
for (var i = 0; i < this.labels.length; ++i) {
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
}var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null;
this.labels.push({ name: maybeName, kind: kind });
node.body = this.parseStatement(true);
this.labels.pop();
node.label = expr;
return this.finishNode(node, "LabeledStatement");
};
pp.parseExpressionStatement = function (node, expr) {
node.expression = expr;
this.semicolon();
return this.finishNode(node, "ExpressionStatement");
};
// Parse a semicolon-enclosed block of statements, handling `"use
// strict"` declarations when `allowStrict` is true (used for
// function bodies).
pp.parseBlock = function (allowStrict) {
var node = this.startNode(),
first = true,
oldStrict = undefined;
node.body = [];
this.expect(tt.braceL);
while (!this.eat(tt.braceR)) {
var stmt = this.parseStatement(true);
node.body.push(stmt);
if (first && allowStrict && this.isUseStrict(stmt)) {
oldStrict = this.strict;
this.setStrict(this.strict = true);
}
first = false;
}
if (oldStrict === false) this.setStrict(false);
return this.finishNode(node, "BlockStatement");
};
// Parse a regular `for` loop. The disambiguation code in
// `parseStatement` will already have parsed the init statement or
// expression.
pp.parseFor = function (node, init) {
node.init = init;
this.expect(tt.semi);
node.test = this.type === tt.semi ? null : this.parseExpression();
this.expect(tt.semi);
node.update = this.type === tt.parenR ? null : this.parseExpression();
this.expect(tt.parenR);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, "ForStatement");
};
// Parse a `for`/`in` and `for`/`of` loop, which are almost
// same from parser's perspective.
pp.parseForIn = function (node, init) {
var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement";
this.next();
node.left = init;
node.right = this.parseExpression();
this.expect(tt.parenR);
node.body = this.parseStatement(false);
this.labels.pop();
return this.finishNode(node, type);
};
// Parse a list of variable declarations.
pp.parseVar = function (node, isFor, kind) {
node.declarations = [];
node.kind = kind.keyword;
for (;;) {
var decl = this.startNode();
this.parseVarHead(decl);
if (this.eat(tt.eq)) {
decl.init = this.parseMaybeAssign(isFor);
} else if (kind === tt._const && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
this.unexpected();
} else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
} else {
decl.init = null;
}
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
if (!this.eat(tt.comma)) break;
}
return node;
};
pp.parseVarHead = function (decl) {
decl.id = this.parseBindingAtom();
this.checkLVal(decl.id, true);
};
// Parse a function declaration or literal (depending on the
// `isStatement` parameter).
pp.parseFunction = function (node, isStatement, allowExpressionBody, isAsync) {
this.initFunction(node, isAsync);
if (this.options.ecmaVersion >= 6) node.generator = this.eat(tt.star);
if (isStatement || this.type === tt.name) node.id = this.parseIdent();
this.parseFunctionParams(node);
this.parseFunctionBody(node, allowExpressionBody);
return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
};
pp.parseFunctionParams = function (node) {
this.expect(tt.parenL);
node.params = this.parseBindingList(tt.parenR, false, this.options.features["es7.trailingFunctionCommas"]);
};
// Parse a class declaration or literal (depending on the
// `isStatement` parameter).
pp.parseClass = function (node, isStatement) {
this.next();
this.parseClassId(node, isStatement);
this.parseClassSuper(node);
var classBody = this.startNode();
classBody.body = [];
this.expect(tt.braceL);
var decorators = [];
while (!this.eat(tt.braceR)) {
if (this.eat(tt.semi)) continue;
if (this.type === tt.at) {
decorators.push(this.parseDecorator());
continue;
}
var method = this.startNode();
if (decorators.length) {
method.decorators = decorators;
decorators = [];
}
var isGenerator = this.eat(tt.star),
isAsync = false;
this.parsePropertyName(method);
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" && method.key.name === "static") {
if (isGenerator) this.unexpected();
method["static"] = true;
isGenerator = this.eat(tt.star);
this.parsePropertyName(method);
} else {
method["static"] = false;
}
if (!isGenerator && method.key.type === "Identifier" && !method.computed && this.isClassProperty()) {
classBody.body.push(this.parseClassProperty(method));
continue;
}
if (this.options.features["es7.asyncFunctions"] && this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" && method.key.name === "async") {
isAsync = true;
this.parsePropertyName(method);
}
method.kind = "method";
if (!method.computed && !isGenerator) {
if (method.key.type === "Identifier") {
if (this.type !== tt.parenL && (method.key.name === "get" || method.key.name === "set")) {
method.kind = method.key.name;
this.parsePropertyName(method);
} else if (!method["static"] && method.key.name === "constructor") {
method.kind = "constructor";
}
} else if (!method["static"] && method.key.type === "Literal" && method.key.value === "constructor") {
method.kind = "constructor";
}
}
if (method.kind === "constructor" && method.decorators) {
this.raise(method.start, "You can't attach decorators to a class constructor");
}
this.parseClassMethod(classBody, method, isGenerator, isAsync);
}
if (decorators.length) {
this.raise(this.start, "You have trailing decorators with no method");
}
node.body = this.finishNode(classBody, "ClassBody");
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
};
pp.isClassProperty = function () {
return this.type === tt.eq || (this.type === tt.semi || this.canInsertSemicolon());
};
pp.parseClassProperty = function (node) {
if (this.type === tt.eq) {
if (!this.options.features["es7.classProperties"]) this.unexpected();
this.next();
node.value = this.parseMaybeAssign();
} else {
node.value = null;
}
this.semicolon();
return this.finishNode(node, "ClassProperty");
};
pp.parseClassMethod = function (classBody, method, isGenerator, isAsync) {
method.value = this.parseMethod(isGenerator, isAsync);
classBody.body.push(this.finishNode(method, "MethodDefinition"));
};
pp.parseClassId = function (node, isStatement) {
node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
};
pp.parseClassSuper = function (node) {
node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
};
// Parses module export declaration.
pp.parseExport = function (node) {
this.next();
// export * from '...'
if (this.type === tt.star) {
var specifier = this.startNode();
this.next();
if (this.options.features["es7.exportExtensions"] && this.eatContextual("as")) {
specifier.exported = this.parseIdent();
node.specifiers = [this.finishNode(specifier, "ExportNamespaceSpecifier")];
this.parseExportSpecifiersMaybe(node);
this.parseExportFrom(node);
} else {
this.parseExportFrom(node);
return this.finishNode(node, "ExportAllDeclaration");
}
} else if (this.isExportDefaultSpecifier()) {
var specifier = this.startNode();
specifier.exported = this.parseIdent(true);
node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
if (this.type === tt.comma && this.lookahead().type === tt.star) {
this.expect(tt.comma);
var _specifier = this.startNode();
this.expect(tt.star);
this.expectContextual("as");
_specifier.exported = this.parseIdent();
node.specifiers.push(this.finishNode(_specifier, "ExportNamespaceSpecifier"));
} else {
this.parseExportSpecifiersMaybe(node);
}
this.parseExportFrom(node);
} else if (this.eat(tt._default)) {
// export default ...
var expr = this.parseMaybeAssign();
var needsSemi = true;
if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
needsSemi = false;
if (expr.id) {
expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
}
}
node.declaration = expr;
if (needsSemi) this.semicolon();
this.checkExport(node);
return this.finishNode(node, "ExportDefaultDeclaration");
} else if (this.type.keyword || this.shouldParseExportDeclaration()) {
node.declaration = this.parseStatement(true);
node.specifiers = [];
node.source = null;
} else {
// export { x, y as z } [from '...']
node.declaration = null;
node.specifiers = this.parseExportSpecifiers();
if (this.eatContextual("from")) {
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
} else {
node.source = null;
}
this.semicolon();
}
this.checkExport(node);
return this.finishNode(node, "ExportNamedDeclaration");
};
pp.isExportDefaultSpecifier = function () {
if (this.type === tt.name) {
return this.value !== "type" && this.value !== "async";
}
if (this.type !== tt._default) {
return false;
}
var lookahead = this.lookahead();
return lookahead.type === tt.comma || lookahead.type === tt.name && lookahead.value === "from";
};
pp.parseExportSpecifiersMaybe = function (node) {
if (this.eat(tt.comma)) {
node.specifiers = node.specifiers.concat(this.parseExportSpecifiers());
}
};
pp.parseExportFrom = function (node) {
this.expectContextual("from");
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
this.semicolon();
this.checkExport(node);
};
pp.shouldParseExportDeclaration = function () {
return this.options.features["es7.asyncFunctions"] && this.isContextual("async");
};
pp.checkExport = function (node) {
if (this.decorators.length) {
var isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression");
if (!node.declaration || !isClass) {
this.raise(node.start, "You can only use decorators on an export when exporting a class");
}
this.takeDecorators(node.declaration);
}
};
// Parses a comma-separated list of module exports.
pp.parseExportSpecifiers = function () {
var nodes = [],
first = true;
// export { x, y as z } [from '...']
this.expect(tt.braceL);
while (!this.eat(tt.braceR)) {
if (!first) {
this.expect(tt.comma);
if (this.afterTrailingComma(tt.braceR)) break;
} else first = false;
var node = this.startNode();
node.local = this.parseIdent(this.type === tt._default);
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
nodes.push(this.finishNode(node, "ExportSpecifier"));
}
return nodes;
};
// Parses import declaration.
pp.parseImport = function (node) {
this.next();
// import '...'
if (this.type === tt.string) {
node.specifiers = empty;
node.source = this.parseExprAtom();
} else {
node.specifiers = [];
this.parseImportSpecifiers(node);
this.expectContextual("from");
node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
}
this.semicolon();
return this.finishNode(node, "ImportDeclaration");
};
// Parses a comma-separated list of module imports.
pp.parseImportSpecifiers = function (node) {
var first = true;
if (this.type === tt.name) {
// import defaultObj, { x, y as z } from '...'
var start = this.markPosition();
node.specifiers.push(this.parseImportSpecifierDefault(this.parseIdent(), start));
if (!this.eat(tt.comma)) return;
}
if (this.type === tt.star) {
var specifier = this.startNode();
this.next();
this.expectContextual("as");
specifier.local = this.parseIdent();
this.checkLVal(specifier.local, true);
node.specifiers.push(this.finishNode(specifier, "ImportNamespaceSpecifier"));
return;
}
this.expect(tt.braceL);
while (!this.eat(tt.braceR)) {
if (!first) {
this.expect(tt.comma);
if (this.afterTrailingComma(tt.braceR)) break;
} else first = false;
var specifier = this.startNode();
specifier.imported = this.parseIdent(true);
specifier.local = this.eatContextual("as") ? this.parseIdent() : specifier.imported;
this.checkLVal(specifier.local, true);
node.specifiers.push(this.finishNode(specifier, "ImportSpecifier"));
}
};
pp.parseImportSpecifierDefault = function (id, start) {
var node = this.startNodeAt(start);
node.local = id;
this.checkLVal(node.local, true);
return this.finishNode(node, "ImportDefaultSpecifier");
};

View File

@ -0,0 +1,105 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
exports.__esModule = true;
// The algorithm used to determine whether a regexp can appear at a
// given point in the program is loosely based on sweet.js' approach.
// See https://github.com/mozilla/sweet.js/wiki/design
var Parser = require("./state").Parser;
var tt = require("./tokentype").types;
var lineBreak = require("./whitespace").lineBreak;
var TokContext = exports.TokContext = function TokContext(token, isExpr, preserveSpace, override) {
_classCallCheck(this, TokContext);
this.token = token;
this.isExpr = isExpr;
this.preserveSpace = preserveSpace;
this.override = override;
};
var types = {
b_stat: new TokContext("{", false),
b_expr: new TokContext("{", true),
b_tmpl: new TokContext("${", true),
p_stat: new TokContext("(", false),
p_expr: new TokContext("(", true),
q_tmpl: new TokContext("`", true, true, function (p) {
return p.readTmplToken();
}),
f_expr: new TokContext("function", true)
};
exports.types = types;
var pp = Parser.prototype;
pp.initialContext = function () {
return [types.b_stat];
};
pp.braceIsBlock = function (prevType) {
var parent = undefined;
if (prevType === tt.colon && (parent = this.curContext()).token == "{") return !parent.isExpr;
if (prevType === tt._return) return lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof) return true;
if (prevType == tt.braceL) return this.curContext() === types.b_stat;
return !this.exprAllowed;
};
pp.updateContext = function (prevType) {
var update = undefined,
type = this.type;
if (type.keyword && prevType == tt.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
};
// Token-specific context update code
tt.parenR.updateContext = tt.braceR.updateContext = function () {
if (this.context.length == 1) {
this.exprAllowed = true;
return;
}
var out = this.context.pop();
if (out === types.b_stat && this.curContext() === types.f_expr) {
this.context.pop();
this.exprAllowed = false;
} else if (out === types.b_tmpl) {
this.exprAllowed = true;
} else {
this.exprAllowed = !out.isExpr;
}
};
tt.braceL.updateContext = function (prevType) {
this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
this.exprAllowed = true;
};
tt.dollarBraceL.updateContext = function () {
this.context.push(types.b_tmpl);
this.exprAllowed = true;
};
tt.parenL.updateContext = function (prevType) {
var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
this.context.push(statementParens ? types.p_stat : types.p_expr);
this.exprAllowed = true;
};
tt.incDec.updateContext = function () {};
tt._function.updateContext = function () {
if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
this.exprAllowed = false;
};
tt.backQuote.updateContext = function () {
if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
this.exprAllowed = false;
};
// tokExprAllowed stays unchanged

View File

@ -0,0 +1,755 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
exports.__esModule = true;
var _identifier = require("./identifier");
var isIdentifierStart = _identifier.isIdentifierStart;
var isIdentifierChar = _identifier.isIdentifierChar;
var _tokentype = require("./tokentype");
var tt = _tokentype.types;
var keywordTypes = _tokentype.keywords;
var Parser = require("./state").Parser;
var SourceLocation = require("./location").SourceLocation;
var _whitespace = require("./whitespace");
var lineBreak = _whitespace.lineBreak;
var lineBreakG = _whitespace.lineBreakG;
var isNewLine = _whitespace.isNewLine;
var nonASCIIwhitespace = _whitespace.nonASCIIwhitespace;
// Object type used to represent tokens. Note that normally, tokens
// simply exist as properties on the parser object. This is only
// used for the onToken callback and the external tokenizer.
var Token = exports.Token = function Token(p) {
_classCallCheck(this, Token);
this.type = p.type;
this.value = p.value;
this.start = p.start;
this.end = p.end;
if (p.options.locations) this.loc = new SourceLocation(p, p.startLoc, p.endLoc);
if (p.options.ranges) this.range = [p.start, p.end];
};
// ## Tokenizer
var pp = Parser.prototype;
// Move to the next token
pp.next = function () {
if (this.options.onToken && !this.isLookahead) this.options.onToken(new Token(this));
this.lastTokEnd = this.end;
this.lastTokStart = this.start;
this.lastTokEndLoc = this.endLoc;
this.lastTokStartLoc = this.startLoc;
this.nextToken();
};
pp.getToken = function () {
this.next();
return new Token(this);
};
// If we're in an ES6 environment, make parsers iterable
if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
var self = this;
return { next: function next() {
var token = self.getToken();
return {
done: token.type === tt.eof,
value: token
};
} };
};
// Toggle strict mode. Re-reads the next number or string to please
// pedantic tests (`"use strict"; 010;` should fail).
pp.setStrict = function (strict) {
this.strict = strict;
if (this.type !== tt.num && this.type !== tt.string) return;
this.pos = this.start;
if (this.options.locations) {
while (this.pos < this.lineStart) {
this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
--this.curLine;
}
}
this.nextToken();
};
pp.curContext = function () {
return this.context[this.context.length - 1];
};
// Read a single token, updating the parser object's token-related
// properties.
pp.nextToken = function () {
var curContext = this.curContext();
if (!curContext || !curContext.preserveSpace) this.skipSpace();
this.start = this.pos;
if (this.options.locations) this.startLoc = this.curPosition();
if (this.pos >= this.input.length) return this.finishToken(tt.eof);
if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
};
pp.readToken = function (code) {
// Identifier or keyword. '\uXXXX' sequences are allowed in
// identifiers, so '\' also dispatches to that.
if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord();
return this.getTokenFromCode(code);
};
pp.fullCharCodeAtPos = function () {
var code = this.input.charCodeAt(this.pos);
if (code <= 55295 || code >= 57344) return code;
var next = this.input.charCodeAt(this.pos + 1);
return (code << 10) + next - 56613888;
};
pp.skipBlockComment = function () {
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
var start = this.pos,
end = this.input.indexOf("*/", this.pos += 2);
if (end === -1) this.raise(this.pos - 2, "Unterminated comment");
this.pos = end + 2;
if (this.options.locations) {
lineBreakG.lastIndex = start;
var match = undefined;
while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
++this.curLine;
this.lineStart = match.index + match[0].length;
}
}
if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.options.locations && this.curPosition());
};
pp.skipLineComment = function (startSkip) {
var start = this.pos;
var startLoc = this.options.onComment && this.options.locations && this.curPosition();
var ch = this.input.charCodeAt(this.pos += startSkip);
while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
++this.pos;
ch = this.input.charCodeAt(this.pos);
}
if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.options.locations && this.curPosition());
};
// Called at the start of the parse and after every token. Skips
// whitespace and comments, and.
pp.skipSpace = function () {
while (this.pos < this.input.length) {
var ch = this.input.charCodeAt(this.pos);
if (ch === 32) {
// ' '
++this.pos;
} else if (ch === 13) {
++this.pos;
var next = this.input.charCodeAt(this.pos);
if (next === 10) {
++this.pos;
}
if (this.options.locations) {
++this.curLine;
this.lineStart = this.pos;
}
} else if (ch === 10 || ch === 8232 || ch === 8233) {
++this.pos;
if (this.options.locations) {
++this.curLine;
this.lineStart = this.pos;
}
} else if (ch > 8 && ch < 14) {
++this.pos;
} else if (ch === 47) {
// '/'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 42) {
// '*'
this.skipBlockComment();
} else if (next === 47) {
// '/'
this.skipLineComment(2);
} else break;
} else if (ch === 160) {
// '\xa0'
++this.pos;
} else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
++this.pos;
} else {
break;
}
}
};
// Called at the end of every token. Sets `end`, `val`, and
// maintains `context` and `exprAllowed`, and skips the space after
// the token, so that the next one's `start` will point at the
// right position.
pp.finishToken = function (type, val) {
this.end = this.pos;
if (this.options.locations) this.endLoc = this.curPosition();
var prevType = this.type;
this.type = type;
this.value = val;
this.updateContext(prevType);
};
// ### Token reading
// This is the function that is called to fetch the next token. It
// is somewhat obscure, because it works in character codes rather
// than characters, and because operator parsing has been inlined
// into it.
//
// All in the name of speed.
//
pp.readToken_dot = function () {
var next = this.input.charCodeAt(this.pos + 1);
if (next >= 48 && next <= 57) return this.readNumber(true);
var next2 = this.input.charCodeAt(this.pos + 2);
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) {
// 46 = dot '.'
this.pos += 3;
return this.finishToken(tt.ellipsis);
} else {
++this.pos;
return this.finishToken(tt.dot);
}
};
pp.readToken_slash = function () {
// '/'
var next = this.input.charCodeAt(this.pos + 1);
if (this.exprAllowed) {
++this.pos;return this.readRegexp();
}
if (next === 61) return this.finishOp(tt.assign, 2);
return this.finishOp(tt.slash, 1);
};
pp.readToken_mult_modulo = function (code) {
// '%*'
var type = code === 42 ? tt.star : tt.modulo;
var width = 1;
var next = this.input.charCodeAt(this.pos + 1);
if (next === 42) {
// '*'
width++;
next = this.input.charCodeAt(this.pos + 2);
type = tt.exponent;
}
if (next === 61) {
width++;
type = tt.assign;
}
return this.finishOp(type, width);
};
pp.readToken_pipe_amp = function (code) {
// '|&'
var next = this.input.charCodeAt(this.pos + 1);
if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
if (next === 61) return this.finishOp(tt.assign, 2);
return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
};
pp.readToken_caret = function () {
// '^'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 61) return this.finishOp(tt.assign, 2);
return this.finishOp(tt.bitwiseXOR, 1);
};
pp.readToken_plus_min = function (code) {
// '+-'
var next = this.input.charCodeAt(this.pos + 1);
if (next === code) {
if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
// A `-->` line comment
this.skipLineComment(3);
this.skipSpace();
return this.nextToken();
}
return this.finishOp(tt.incDec, 2);
}
if (next === 61) return this.finishOp(tt.assign, 2);
return this.finishOp(tt.plusMin, 1);
};
pp.readToken_lt_gt = function (code) {
// '<>'
var next = this.input.charCodeAt(this.pos + 1);
var size = 1;
if (next === code) {
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1);
return this.finishOp(tt.bitShift, size);
}
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
if (this.inModule) unexpected();
// `<!--`, an XML-style comment that should be interpreted as a line comment
this.skipLineComment(4);
this.skipSpace();
return this.nextToken();
}
if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
return this.finishOp(tt.relational, size);
};
pp.readToken_eq_excl = function (code) {
// '=!'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 61) return this.finishOp(tt.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2);
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) {
// '=>'
this.pos += 2;
return this.finishToken(tt.arrow);
}
return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
};
pp.getTokenFromCode = function (code) {
switch (code) {
// The interpretation of a dot depends on whether it is followed
// by a digit or another two dots.
case 46:
// '.'
return this.readToken_dot();
// Punctuation tokens.
case 40:
++this.pos;return this.finishToken(tt.parenL);
case 41:
++this.pos;return this.finishToken(tt.parenR);
case 59:
++this.pos;return this.finishToken(tt.semi);
case 44:
++this.pos;return this.finishToken(tt.comma);
case 91:
++this.pos;return this.finishToken(tt.bracketL);
case 93:
++this.pos;return this.finishToken(tt.bracketR);
case 123:
++this.pos;return this.finishToken(tt.braceL);
case 125:
++this.pos;return this.finishToken(tt.braceR);
case 58:
++this.pos;return this.finishToken(tt.colon);
case 63:
++this.pos;return this.finishToken(tt.question);
case 64:
++this.pos;return this.finishToken(tt.at);
case 96:
// '`'
if (this.options.ecmaVersion < 6) break;
++this.pos;
return this.finishToken(tt.backQuote);
case 48:
// '0'
var next = this.input.charCodeAt(this.pos + 1);
if (next === 120 || next === 88) return this.readRadixNumber(16); // '0x', '0X' - hex number
if (this.options.ecmaVersion >= 6) {
if (next === 111 || next === 79) return this.readRadixNumber(8); // '0o', '0O' - octal number
if (next === 98 || next === 66) return this.readRadixNumber(2); // '0b', '0B' - binary number
}
// Anything else beginning with a digit is an integer, octal
// number, or float.
case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
// 1-9
return this.readNumber(false);
// Quotes produce strings.
case 34:case 39:
// '"', "'"
return this.readString(code);
// Operators are parsed inline in tiny state machines. '=' (61) is
// often referred to. `finishOp` simply skips the amount of
// characters it is given as second argument, and returns a token
// of the type given by its first argument.
case 47:
// '/'
return this.readToken_slash();
case 37:case 42:
// '%*'
return this.readToken_mult_modulo(code);
case 124:case 38:
// '|&'
return this.readToken_pipe_amp(code);
case 94:
// '^'
return this.readToken_caret();
case 43:case 45:
// '+-'
return this.readToken_plus_min(code);
case 60:case 62:
// '<>'
return this.readToken_lt_gt(code);
case 61:case 33:
// '=!'
return this.readToken_eq_excl(code);
case 126:
// '~'
return this.finishOp(tt.prefix, 1);
}
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
};
pp.finishOp = function (type, size) {
var str = this.input.slice(this.pos, this.pos + size);
this.pos += size;
return this.finishToken(type, str);
};
var regexpUnicodeSupport = false;
try {
new RegExp("￿", "u");regexpUnicodeSupport = true;
} catch (e) {}
// Parse a regular expression. Some context-awareness is necessary,
// since a '/' inside a '[]' set does not end the expression.
pp.readRegexp = function () {
var escaped = undefined,
inClass = undefined,
start = this.pos;
for (;;) {
if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
var ch = this.input.charAt(this.pos);
if (lineBreak.test(ch)) this.raise(start, "Unterminated regular expression");
if (!escaped) {
if (ch === "[") inClass = true;else if (ch === "]" && inClass) inClass = false;else if (ch === "/" && !inClass) break;
escaped = ch === "\\";
} else escaped = false;
++this.pos;
}
var content = this.input.slice(start, this.pos);
++this.pos;
// Need to use `readWord1` because '\uXXXX' sequences are allowed
// here (don't ask).
var mods = this.readWord1();
var tmp = content;
if (mods) {
var validFlags = /^[gmsiy]*$/;
if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
// Replace each astral symbol and every Unicode escape sequence that
// possibly represents an astral symbol or a paired surrogate with a
// single ASCII symbol to avoid throwing on regular expressions that
// are only valid in combination with the `/u` flag.
// Note: replacing with the ASCII symbol `x` might cause false
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
// be replaced by `[x-b]` which throws an error.
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
}
}
// Detect invalid regular expressions.
try {
new RegExp(tmp);
} catch (e) {
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message);
this.raise(e);
}
// Get a regular expression object for this pattern-flag pair, or `null` in
// case the current environment doesn't support the flags it uses.
var value = undefined;
try {
value = new RegExp(content, mods);
} catch (err) {
value = null;
}
return this.finishToken(tt.regexp, { pattern: content, flags: mods, value: value });
};
// Read an integer in the given radix. Return null if zero digits
// were read, the integer value otherwise. When `len` is given, this
// will return `null` unless the integer has exactly `len` digits.
pp.readInt = function (radix, len) {
var start = this.pos,
total = 0;
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
var code = this.input.charCodeAt(this.pos),
val = undefined;
if (code >= 97) val = code - 97 + 10; // a
else if (code >= 65) val = code - 65 + 10; // A
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
else val = Infinity;
if (val >= radix) break;
++this.pos;
total = total * radix + val;
}
if (this.pos === start || len != null && this.pos - start !== len) return null;
return total;
};
pp.readRadixNumber = function (radix) {
this.pos += 2; // 0x
var val = this.readInt(radix);
if (val == null) this.raise(this.start + 2, "Expected number in radix " + radix);
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
return this.finishToken(tt.num, val);
};
// Read an integer, octal integer, or floating-point number.
pp.readNumber = function (startsWithDot) {
var start = this.pos,
isFloat = false,
octal = this.input.charCodeAt(this.pos) === 48;
if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
if (this.input.charCodeAt(this.pos) === 46) {
++this.pos;
this.readInt(10);
isFloat = true;
}
var next = this.input.charCodeAt(this.pos);
if (next === 69 || next === 101) {
// 'eE'
next = this.input.charCodeAt(++this.pos);
if (next === 43 || next === 45) ++this.pos; // '+-'
if (this.readInt(10) === null) this.raise(start, "Invalid number");
isFloat = true;
}
if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
var str = this.input.slice(start, this.pos),
val = undefined;
if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
return this.finishToken(tt.num, val);
};
// Read a string value, interpreting backslash-escapes.
pp.readCodePoint = function () {
var ch = this.input.charCodeAt(this.pos),
code = undefined;
if (ch === 123) {
if (this.options.ecmaVersion < 6) this.unexpected();
++this.pos;
code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
++this.pos;
if (code > 1114111) this.unexpected();
} else {
code = this.readHexChar(4);
}
return code;
};
function codePointToString(code) {
// UTF-16 Decoding
if (code <= 65535) return String.fromCharCode(code);
return String.fromCharCode((code - 65536 >> 10) + 55296, (code - 65536 & 1023) + 56320);
}
pp.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 === 92) {
// '\'
out += this.input.slice(chunkStart, this.pos);
out += this.readEscapedChar();
chunkStart = this.pos;
} else {
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
++this.pos;
}
}
out += this.input.slice(chunkStart, this.pos++);
return this.finishToken(tt.string, out);
};
// Reads template string tokens.
pp.readTmplToken = function () {
var out = "",
chunkStart = this.pos;
for (;;) {
if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
var ch = this.input.charCodeAt(this.pos);
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
// '`', '${'
if (this.pos === this.start && this.type === tt.template) {
if (ch === 36) {
this.pos += 2;
return this.finishToken(tt.dollarBraceL);
} else {
++this.pos;
return this.finishToken(tt.backQuote);
}
}
out += this.input.slice(chunkStart, this.pos);
return this.finishToken(tt.template, out);
}
if (ch === 92) {
// '\'
out += this.input.slice(chunkStart, this.pos);
out += this.readEscapedChar();
chunkStart = this.pos;
} else if (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;
}
}
};
// Used to read escaped characters
pp.readEscapedChar = function () {
var ch = this.input.charCodeAt(++this.pos);
var octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3));
if (octal) octal = octal[0];
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
if (octal === "0") octal = null;
++this.pos;
if (octal) {
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode");
this.pos += octal.length - 1;
return String.fromCharCode(parseInt(octal, 8));
} else {
switch (ch) {
case 110:
return "\n"; // 'n' -> '\n'
case 114:
return "\r"; // 'r' -> '\r'
case 120:
return String.fromCharCode(this.readHexChar(2)); // 'x'
case 117:
return codePointToString(this.readCodePoint()); // 'u'
case 116:
return "\t"; // 't' -> '\t'
case 98:
return "\b"; // 'b' -> '\b'
case 118:
return "\u000b"; // 'v' -> '\u000b'
case 102:
return "\f"; // 'f' -> '\f'
case 48:
return "\u0000"; // 0 -> '\0'
case 13:
if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
case 10:
// ' \n'
if (this.options.locations) {
this.lineStart = this.pos;++this.curLine;
}
return "";
default:
return String.fromCharCode(ch);
}
}
};
// Used to read character escape sequences ('\x', '\u', '\U').
pp.readHexChar = function (len) {
var n = this.readInt(16, len);
if (n === null) this.raise(this.start, "Bad character escape sequence");
return n;
};
// Used to signal to callers of `readWord1` whether the word
// contained any escape sequences. This is needed because words with
// escape sequences must not be interpreted as keywords.
var containsEsc;
// Read an identifier, and return it as a string. Sets `containsEsc`
// to whether the word contained a '\u' escape.
//
// Incrementally adds only escaped chars, adding other chunks as-is
// as a micro-optimization.
pp.readWord1 = function () {
containsEsc = false;
var word = "",
first = true,
chunkStart = this.pos;
var astral = this.options.ecmaVersion >= 6;
while (this.pos < this.input.length) {
var ch = this.fullCharCodeAtPos();
if (isIdentifierChar(ch, astral)) {
this.pos += ch <= 65535 ? 1 : 2;
} else if (ch === 92) {
// "\"
containsEsc = true;
word += this.input.slice(chunkStart, this.pos);
var escStart = this.pos;
if (this.input.charCodeAt(++this.pos) != 117) // "u"
this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
++this.pos;
var esc = this.readCodePoint();
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
word += codePointToString(esc);
chunkStart = this.pos;
} else {
break;
}
first = false;
}
return word + this.input.slice(chunkStart, this.pos);
};
// Read an identifier or keyword token. Will check for reserved
// words when necessary.
pp.readWord = function () {
var word = this.readWord1();
var type = tt.name;
if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = keywordTypes[word];
return this.finishToken(type, word);
};

View File

@ -0,0 +1,157 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
exports.__esModule = true;
// ## Token types
// The assignment of fine-grained, information-carrying type objects
// allows the tokenizer to store the information it has about a
// token in a way that is very cheap for the parser to look up.
// All token type variables start with an underscore, to make them
// easy to recognize.
// The `beforeExpr` property is used to disambiguate between regular
// expressions and divisions. It is set on all token types that can
// be followed by an expression (thus, a slash after them would be a
// regular expression).
//
// `isLoop` marks a keyword as starting a loop, which is important
// to know when parsing a label, in order to allow or disallow
// continue jumps to that label.
var TokenType = exports.TokenType = function TokenType(label) {
var conf = arguments[1] === undefined ? {} : arguments[1];
_classCallCheck(this, TokenType);
this.label = label;
this.keyword = conf.keyword;
this.beforeExpr = !!conf.beforeExpr;
this.startsExpr = !!conf.startsExpr;
this.rightAssociative = !!conf.rightAssociative;
this.isLoop = !!conf.isLoop;
this.isAssign = !!conf.isAssign;
this.prefix = !!conf.prefix;
this.postfix = !!conf.postfix;
this.binop = conf.binop || null;
this.updateContext = null;
};
function binop(name, prec) {
return new TokenType(name, { beforeExpr: true, binop: prec });
}
var beforeExpr = { beforeExpr: true },
startsExpr = { startsExpr: true };
var types = {
num: new TokenType("num", startsExpr),
regexp: new TokenType("regexp", startsExpr),
string: new TokenType("string", startsExpr),
name: new TokenType("name", startsExpr),
eof: new TokenType("eof"),
// Punctuation token types.
bracketL: new TokenType("[", { beforeExpr: true, startsExpr: true }),
bracketR: new TokenType("]"),
braceL: new TokenType("{", { beforeExpr: true, startsExpr: true }),
braceR: new TokenType("}"),
parenL: new TokenType("(", { beforeExpr: true, startsExpr: true }),
parenR: new TokenType(")"),
comma: new TokenType(",", beforeExpr),
semi: new TokenType(";", beforeExpr),
colon: new TokenType(":", beforeExpr),
dot: new TokenType("."),
question: new TokenType("?", beforeExpr),
arrow: new TokenType("=>", beforeExpr),
template: new TokenType("template"),
ellipsis: new TokenType("...", beforeExpr),
backQuote: new TokenType("`", startsExpr),
dollarBraceL: new TokenType("${", { beforeExpr: true, startsExpr: true }),
at: new TokenType("@"),
// Operators. These carry several kinds of properties to help the
// parser use them properly (the presence of these properties is
// what categorizes them as operators).
//
// `binop`, when present, specifies that this operator is a binary
// operator, and will refer to its precedence.
//
// `prefix` and `postfix` mark the operator as a prefix or postfix
// unary operator.
//
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
// binary operators with a very low precedence, that should result
// in AssignmentExpression nodes.
eq: new TokenType("=", { beforeExpr: true, isAssign: true }),
assign: new TokenType("_=", { beforeExpr: true, isAssign: true }),
incDec: new TokenType("++/--", { prefix: true, postfix: true, startsExpr: true }),
prefix: new TokenType("prefix", { beforeExpr: true, prefix: true, startsExpr: true }),
logicalOR: binop("||", 1),
logicalAND: binop("&&", 2),
bitwiseOR: binop("|", 3),
bitwiseXOR: binop("^", 4),
bitwiseAND: binop("&", 5),
equality: binop("==/!=", 6),
relational: binop("</>", 7),
bitShift: binop("<</>>", 8),
plusMin: new TokenType("+/-", { beforeExpr: true, binop: 9, prefix: true, startsExpr: true }),
modulo: binop("%", 10),
star: binop("*", 10),
slash: binop("/", 10),
exponent: new TokenType("**", { beforeExpr: true, binop: 11, rightAssociative: true })
};
exports.types = types;
// Map keyword names to token types.
var keywords = {};
exports.keywords = keywords;
// Succinct definitions of keyword token types
function kw(name) {
var options = arguments[1] === undefined ? {} : arguments[1];
options.keyword = name;
keywords[name] = types["_" + name] = new TokenType(name, options);
}
kw("break");
kw("case", beforeExpr);
kw("catch");
kw("continue");
kw("debugger");
kw("default");
kw("do", { isLoop: true });
kw("else", beforeExpr);
kw("finally");
kw("for", { isLoop: true });
kw("function", startsExpr);
kw("if");
kw("return", beforeExpr);
kw("switch");
kw("throw", beforeExpr);
kw("try");
kw("var");
kw("let");
kw("const");
kw("while", { isLoop: true });
kw("with");
kw("new", { beforeExpr: true, startsExpr: true });
kw("this", startsExpr);
kw("super", startsExpr);
kw("class");
kw("extends", beforeExpr);
kw("export");
kw("import");
kw("yield", { beforeExpr: true, startsExpr: true });
kw("null", startsExpr);
kw("true", startsExpr);
kw("false", startsExpr);
kw("in", { beforeExpr: true, binop: 7 });
kw("instanceof", { beforeExpr: true, binop: 7 });
kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });

View File

@ -0,0 +1,16 @@
"use strict";
exports.isArray = isArray;
// Checks if an object has a property.
exports.has = has;
exports.__esModule = true;
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
}
function has(obj, propName) {
return Object.prototype.hasOwnProperty.call(obj, propName);
}

View File

@ -0,0 +1,19 @@
"use strict";
exports.isNewLine = isNewLine;
exports.__esModule = true;
// Matches a whole line break (where CRLF is considered a single
// line break). Used to count lines.
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
exports.lineBreak = lineBreak;
var lineBreakG = new RegExp(lineBreak.source, "g");
exports.lineBreakG = lineBreakG;
function isNewLine(code) {
return code === 10 || code === 13 || code === 8232 || code == 8233;
}
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
exports.nonASCIIwhitespace = nonASCIIwhitespace;

View File

@ -0,0 +1,98 @@
"use strict";
var transform = module.exports = require("../transformation");
transform.options = require("../transformation/file/options");
transform.version = require("../../../package").version;
transform.transform = transform;
transform.run = function (code) {
var opts = arguments[1] === undefined ? {} : arguments[1];
opts.sourceMaps = "inline";
return new Function(transform(code, opts).code)();
};
transform.load = function (url, callback, _x, hold) {
var opts = arguments[2] === undefined ? {} : arguments[2];
var _opts = opts;
if (!_opts.filename) _opts.filename = url;
var xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
xhr.open("GET", url, true);
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
var status = xhr.status;
if (status === 0 || status === 200) {
var param = [xhr.responseText, opts];
if (!hold) transform.run.apply(transform, param);
if (callback) callback(param);
} else {
throw new Error("Could not load " + url);
}
};
xhr.send(null);
};
var runScripts = function runScripts() {
var scripts = [];
var types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
var index = 0;
var exec = (function (_exec) {
var _execWrapper = function exec() {
return _exec.apply(this, arguments);
};
_execWrapper.toString = function () {
return _exec.toString();
};
return _execWrapper;
})(function () {
var param = scripts[index];
if (param instanceof Array) {
transform.run.apply(transform, param);
index++;
exec();
}
});
var run = function run(script, i) {
var opts = {};
if (script.src) {
transform.load(script.src, function (param) {
scripts[i] = param;
exec();
}, opts, true);
} else {
opts.filename = "embedded";
scripts[i] = [script.innerHTML, opts];
}
};
var _scripts = global.document.getElementsByTagName("script");
for (var i = 0; i < _scripts.length; ++i) {
var _script = _scripts[i];
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
}
for (i in scripts) {
run(scripts[i], i);
}
exec();
};
if (global.addEventListener) {
global.addEventListener("DOMContentLoaded", runScripts, false);
} else if (global.attachEvent) {
global.attachEvent("onload", runScripts);
}

View File

@ -0,0 +1,96 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.register = register;
exports.polyfill = polyfill;
exports.transformFile = transformFile;
exports.transformFileSync = transformFileSync;
exports.parse = parse;
exports.__esModule = true;
var isFunction = _interopRequire(require("lodash/lang/isFunction"));
var transform = _interopRequire(require("../transformation"));
var acorn = _interopRequireWildcard(require("../../acorn"));
var _util = require("../util");
var util = _interopRequireWildcard(_util);
var fs = _interopRequire(require("fs"));
exports.util = util;
exports.acorn = acorn;
exports.transform = transform;
exports.canCompile = _util.canCompile;
exports.options = _interopRequire(require("../transformation/file/options"));
exports.Transformer = _interopRequire(require("../transformation/transformer"));
exports.traverse = _interopRequire(require("../traversal"));
exports.buildExternalHelpers = _interopRequire(require("../tools/build-external-helpers"));
exports.version = require("../../../package").version;
var t = _interopRequireWildcard(require("../types"));
exports.types = t;
function register(opts) {
var callback = require("./register/node");
if (opts != null) callback(opts);
return callback;
}
function polyfill() {
require("../polyfill");
}
function transformFile(filename, opts, callback) {
if (isFunction(opts)) {
callback = opts;
opts = {};
}
opts.filename = filename;
fs.readFile(filename, function (err, code) {
if (err) return callback(err);
var result;
try {
result = transform(code, opts);
} catch (err) {
return callback(err);
}
callback(null, result);
});
}
function transformFileSync(filename) {
var opts = arguments[1] === undefined ? {} : arguments[1];
opts.filename = filename;
return transform(fs.readFileSync(filename), opts);
}
function parse(code) {
var opts = arguments[1] === undefined ? {} : arguments[1];
opts.sourceType = "module";
opts.ecmaVersion = Infinity;
opts.plugins = {
flow: true,
jsx: true
};
opts.features = {};
for (var key in transform.transformers) {
opts.features[key] = true;
}
return acorn.parse(code, opts);
}

View File

@ -0,0 +1,7 @@
// required to safely use babel/register within a browserify codebase
"use strict";
module.exports = function () {};
require("../../polyfill");

View File

@ -0,0 +1,42 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.save = save;
exports.load = load;
exports.get = get;
exports.__esModule = true;
var path = _interopRequire(require("path"));
var os = _interopRequire(require("os"));
var fs = _interopRequire(require("fs"));
var userHome = _interopRequire(require("user-home"));
var FILENAME = process.env.BABEL_CACHE_PATH || path.join(userHome || os.tmpdir(), ".babel.json");
var data = {};
function save() {
fs.writeFileSync(FILENAME, JSON.stringify(data, null, " "));
}
function load() {
if (process.env.BABEL_DISABLE_CACHE) return;
process.on("exit", save);
process.nextTick(save);
if (!fs.existsSync(FILENAME)) return;
try {
data = JSON.parse(fs.readFileSync(FILENAME));
} catch (err) {
return;
}
}
function get() {
return data;
}

View File

@ -0,0 +1,175 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
require("../../polyfill");
var sourceMapSupport = _interopRequire(require("source-map-support"));
var registerCache = _interopRequireWildcard(require("./cache"));
var resolveRc = _interopRequire(require("../../tools/resolve-rc"));
var extend = _interopRequire(require("lodash/object/extend"));
var babel = _interopRequireWildcard(require("../node"));
var each = _interopRequire(require("lodash/collection/each"));
var util = _interopRequireWildcard(require("../../util"));
var fs = _interopRequire(require("fs"));
sourceMapSupport.install({
handleUncaughtExceptions: false,
retrieveSourceMap: function retrieveSourceMap(source) {
var map = maps && maps[source];
if (map) {
return {
url: null,
map: map
};
} else {
return null;
}
}
});
//
registerCache.load();
var cache = registerCache.get();
//
var transformOpts = {};
var ignoreRegex = /node_modules/;
var onlyRegex;
var oldHandlers = {};
var maps = {};
var mtime = function mtime(filename) {
return +fs.statSync(filename).mtime;
};
var compile = function compile(filename) {
var result;
var opts = extend({}, transformOpts);
// this will be done when the file is transformed anyway but we need all
// the options so we can generate the cache key
resolveRc(filename, opts);
var cacheKey = "" + filename + ":" + JSON.stringify(opts) + ":" + babel.version;
if (cache) {
var cached = cache[cacheKey];
if (cached && cached.mtime === mtime(filename)) {
result = cached;
}
}
if (!result) {
result = babel.transformFileSync(filename, extend(opts, {
sourceMap: "both",
ast: false
}));
}
if (cache) {
result.mtime = mtime(filename);
cache[cacheKey] = result;
}
maps[filename] = result.map;
return result.code;
};
var shouldIgnore = function shouldIgnore(filename) {
return ignoreRegex && ignoreRegex.test(filename) || onlyRegex && !onlyRegex.test(filename);
};
var istanbulMonkey = {};
if (process.env.running_under_istanbul) {
// jshint ignore:line
// 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;
fs.readFileSync = function (filename) {
if (istanbulMonkey[filename]) {
delete istanbulMonkey[filename];
var code = compile(filename);
istanbulMonkey[filename] = true;
return code;
} else {
return _readFileSync.apply(this, arguments);
}
};
}
var istanbulLoader = function istanbulLoader(m, filename, old) {
istanbulMonkey[filename] = true;
old(m, filename);
};
var normalLoader = function normalLoader(m, filename) {
m._compile(compile(filename), filename);
};
var registerExtension = function registerExtension(ext) {
var old = oldHandlers[ext] || oldHandlers[".js"];
var loader = normalLoader;
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
require.extensions[ext] = function (m, filename) {
if (shouldIgnore(filename)) {
old(m, filename);
} else {
loader(m, filename, old);
}
};
};
var hookExtensions = function hookExtensions(_exts) {
each(oldHandlers, function (old, ext) {
if (old === undefined) {
delete require.extensions[ext];
} else {
require.extensions[ext] = old;
}
});
oldHandlers = {};
each(_exts, function (ext) {
oldHandlers[ext] = require.extensions[ext];
registerExtension(ext);
});
};
hookExtensions(util.canCompile.EXTENSIONS);
module.exports = function () {
var opts = arguments[0] === undefined ? {} : arguments[0];
if (opts.only != null) onlyRegex = util.regexify(opts.only);
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
if (opts.cache === false) cache = null;
delete opts.extensions;
delete opts.ignore;
delete opts.cache;
delete opts.only;
extend(transformOpts, opts);
};

View File

@ -0,0 +1,188 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var repeating = _interopRequire(require("repeating"));
var trimRight = _interopRequire(require("trim-right"));
var isBoolean = _interopRequire(require("lodash/lang/isBoolean"));
var includes = _interopRequire(require("lodash/collection/includes"));
var isNumber = _interopRequire(require("lodash/lang/isNumber"));
var Buffer = (function () {
function Buffer(position, format) {
_classCallCheck(this, Buffer);
this.position = position;
this._indent = format.indent.base;
this.format = format;
this.buf = "";
}
Buffer.prototype.get = function get() {
return trimRight(this.buf);
};
Buffer.prototype.getIndent = function getIndent() {
if (this.format.compact || this.format.concise) {
return "";
} else {
return repeating(this.format.indent.style, this._indent);
}
};
Buffer.prototype.indentSize = function indentSize() {
return this.getIndent().length;
};
Buffer.prototype.indent = function indent() {
this._indent++;
};
Buffer.prototype.dedent = function dedent() {
this._indent--;
};
Buffer.prototype.semicolon = function semicolon() {
this.push(";");
};
Buffer.prototype.ensureSemicolon = function ensureSemicolon() {
if (!this.isLast(";")) this.semicolon();
};
Buffer.prototype.rightBrace = function rightBrace() {
this.newline(true);
this.push("}");
};
Buffer.prototype.keyword = function keyword(name) {
this.push(name);
this.space();
};
Buffer.prototype.space = function space() {
if (this.format.compact) return;
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
this.push(" ");
}
};
Buffer.prototype.removeLast = function removeLast(cha) {
if (this.format.compact) return;
if (!this.isLast(cha)) return;
this.buf = this.buf.substr(0, this.buf.length - 1);
this.position.unshift(cha);
};
Buffer.prototype.newline = function newline(i, removeLast) {
if (this.format.compact) return;
if (this.format.concise) {
this.space();
return;
}
if (!removeLast) removeLast = false;
if (isNumber(i)) {
i = Math.min(2, i);
if (this.endsWith("{\n") || this.endsWith(":\n")) i--;
if (i <= 0) return;
while (i > 0) {
this._newline(removeLast);
i--;
}
return;
}
if (isBoolean(i)) {
removeLast = i;
}
this._newline(removeLast);
};
Buffer.prototype._newline = function _newline(removeLast) {
// never allow more than two lines
if (this.endsWith("\n\n")) return;
// remove the last newline
if (removeLast && this.isLast("\n")) this.removeLast("\n");
this.removeLast(" ");
this._removeSpacesAfterLastNewline();
this._push("\n");
};
/**
* If buffer ends with a newline and some spaces after it, trim those spaces.
*/
Buffer.prototype._removeSpacesAfterLastNewline = function _removeSpacesAfterLastNewline() {
var lastNewlineIndex = this.buf.lastIndexOf("\n");
if (lastNewlineIndex === -1) return;
var index = this.buf.length - 1;
while (index > lastNewlineIndex) {
if (this.buf[index] !== " ") {
break;
}
index--;
}
if (index === lastNewlineIndex) {
this.buf = this.buf.substring(0, index + 1);
}
};
Buffer.prototype.push = function push(str, noIndent) {
if (!this.format.compact && this._indent && !noIndent && str !== "\n") {
// we have an indent level and we aren't pushing a newline
var indent = this.getIndent();
// replace all newlines with newlines with the indentation
str = str.replace(/\n/g, "\n" + indent);
// we've got a newline before us so prepend on the indentation
if (this.isLast("\n")) this._push(indent);
}
this._push(str);
};
Buffer.prototype._push = function _push(str) {
this.position.push(str);
this.buf += str;
};
Buffer.prototype.endsWith = function endsWith(str) {
return this.buf.slice(-str.length) === str;
};
Buffer.prototype.isLast = function isLast(cha) {
if (this.format.compact) return false;
var buf = this.buf;
var last = buf[buf.length - 1];
if (Array.isArray(cha)) {
return includes(cha, last);
} else {
return cha === last;
}
};
return Buffer;
})();
module.exports = Buffer;

View File

@ -0,0 +1,26 @@
"use strict";
exports.File = File;
exports.Program = Program;
exports.BlockStatement = BlockStatement;
exports.__esModule = true;
function File(node, print) {
print(node.program);
}
function Program(node, print) {
print.sequence(node.body);
}
function BlockStatement(node, print) {
if (node.body.length === 0) {
this.push("{}");
} else {
this.push("{");
this.newline();
print.sequence(node.body, { indent: true });
this.removeLast("\n");
this.rightBrace();
}
}

View File

@ -0,0 +1,75 @@
"use strict";
exports.ClassDeclaration = ClassDeclaration;
exports.ClassBody = ClassBody;
exports.ClassProperty = ClassProperty;
exports.MethodDefinition = MethodDefinition;
exports.__esModule = true;
function ClassDeclaration(node, print) {
print.list(node.decorators);
this.push("class");
if (node.id) {
this.space();
print(node.id);
}
print(node.typeParameters);
if (node.superClass) {
this.push(" extends ");
print(node.superClass);
print(node.superTypeParameters);
}
if (node["implements"]) {
this.push(" implements ");
print.join(node["implements"], { separator: ", " });
}
this.space();
print(node.body);
}
exports.ClassExpression = ClassDeclaration;
function ClassBody(node, print) {
if (node.body.length === 0) {
this.push("{}");
} else {
this.push("{");
this.newline();
this.indent();
print.sequence(node.body);
this.dedent();
this.rightBrace();
}
}
function ClassProperty(node, print) {
print.list(node.decorators);
if (node["static"]) this.push("static ");
print(node.key);
print(node.typeAnnotation);
if (node.value) {
this.space();
this.push("=");
this.space();
print(node.value);
}
this.semicolon();
}
function MethodDefinition(node, print) {
print.list(node.decorators);
if (node["static"]) {
this.push("static ");
}
this._method(node, print);
}

View File

@ -0,0 +1,33 @@
"use strict";
exports.ComprehensionBlock = ComprehensionBlock;
exports.ComprehensionExpression = ComprehensionExpression;
exports.__esModule = true;
function ComprehensionBlock(node, print) {
this.keyword("for");
this.push("(");
print(node.left);
this.push(" of ");
print(node.right);
this.push(")");
}
function ComprehensionExpression(node, print) {
this.push(node.generator ? "(" : "[");
print.join(node.blocks, { separator: " " });
this.space();
if (node.filter) {
this.keyword("if");
this.push("(");
print(node.filter);
this.push(")");
this.space();
}
print(node.body);
this.push(node.generator ? ")" : "]");
}

View File

@ -0,0 +1,202 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.UnaryExpression = UnaryExpression;
exports.DoExpression = DoExpression;
exports.UpdateExpression = UpdateExpression;
exports.ConditionalExpression = ConditionalExpression;
exports.NewExpression = NewExpression;
exports.SequenceExpression = SequenceExpression;
exports.ThisExpression = ThisExpression;
exports.Super = Super;
exports.Decorator = Decorator;
exports.CallExpression = CallExpression;
exports.EmptyStatement = EmptyStatement;
exports.ExpressionStatement = ExpressionStatement;
exports.AssignmentExpression = AssignmentExpression;
exports.MemberExpression = MemberExpression;
exports.MetaProperty = MetaProperty;
exports.__esModule = true;
var isInteger = _interopRequire(require("is-integer"));
var isNumber = _interopRequire(require("lodash/lang/isNumber"));
var t = _interopRequireWildcard(require("../../types"));
function UnaryExpression(node, print) {
var hasSpace = /[a-z]$/.test(node.operator);
var arg = node.argument;
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
hasSpace = true;
}
if (t.isUnaryExpression(arg) && arg.operator === "!") {
hasSpace = false;
}
this.push(node.operator);
if (hasSpace) this.push(" ");
print(node.argument);
}
function DoExpression(node, print) {
this.push("do");
this.space();
print(node.body);
}
function UpdateExpression(node, print) {
if (node.prefix) {
this.push(node.operator);
print(node.argument);
} else {
print(node.argument);
this.push(node.operator);
}
}
function ConditionalExpression(node, print) {
print(node.test);
this.space();
this.push("?");
this.space();
print(node.consequent);
this.space();
this.push(":");
this.space();
print(node.alternate);
}
function NewExpression(node, print) {
this.push("new ");
print(node.callee);
this.push("(");
print.list(node.arguments);
this.push(")");
}
function SequenceExpression(node, print) {
print.list(node.expressions);
}
function ThisExpression() {
this.push("this");
}
function Super() {
this.push("super");
}
function Decorator(node, print) {
this.push("@");
print(node.expression);
}
function CallExpression(node, print) {
print(node.callee);
this.push("(");
var separator = ",";
if (node._prettyCall) {
separator += "\n";
this.newline();
this.indent();
} else {
separator += " ";
}
print.list(node.arguments, { separator: separator });
if (node._prettyCall) {
this.newline();
this.dedent();
}
this.push(")");
}
var buildYieldAwait = function buildYieldAwait(keyword) {
return function (node, print) {
this.push(keyword);
if (node.delegate || node.all) {
this.push("*");
}
if (node.argument) {
this.space();
print(node.argument);
}
};
};
var YieldExpression = buildYieldAwait("yield");
exports.YieldExpression = YieldExpression;
var AwaitExpression = buildYieldAwait("await");
exports.AwaitExpression = AwaitExpression;
function EmptyStatement() {
this.semicolon();
}
function ExpressionStatement(node, print) {
print(node.expression);
this.semicolon();
}
function AssignmentExpression(node, print) {
// todo: add cases where the spaces can be dropped when in compact mode
print(node.left);
this.push(" ");
this.push(node.operator);
this.push(" ");
print(node.right);
}
exports.BinaryExpression = AssignmentExpression;
exports.LogicalExpression = AssignmentExpression;
exports.AssignmentPattern = AssignmentExpression;
var SCIENTIFIC_NOTATION = /e/i;
function MemberExpression(node, print) {
var obj = node.object;
print(obj);
if (!node.computed && t.isMemberExpression(node.property)) {
throw new TypeError("Got a MemberExpression for MemberExpression property");
}
var computed = node.computed;
if (t.isLiteral(node.property) && isNumber(node.property.value)) {
computed = true;
}
if (computed) {
this.push("[");
print(node.property);
this.push("]");
} else {
// 5..toFixed(2);
if (t.isLiteral(obj) && isInteger(obj.value) && !SCIENTIFIC_NOTATION.test(obj.value.toString())) {
this.push(".");
}
this.push(".");
print(node.property);
}
}
function MetaProperty(node, print) {
print(node.meta);
this.push(".");
print(node.property);
}

View File

@ -0,0 +1,271 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
exports.AnyTypeAnnotation = AnyTypeAnnotation;
exports.ArrayTypeAnnotation = ArrayTypeAnnotation;
exports.BooleanTypeAnnotation = BooleanTypeAnnotation;
exports.DeclareClass = DeclareClass;
exports.DeclareFunction = DeclareFunction;
exports.DeclareModule = DeclareModule;
exports.DeclareVariable = DeclareVariable;
exports.FunctionTypeAnnotation = FunctionTypeAnnotation;
exports.FunctionTypeParam = FunctionTypeParam;
exports.InterfaceExtends = InterfaceExtends;
exports._interfaceish = _interfaceish;
exports.InterfaceDeclaration = InterfaceDeclaration;
exports.IntersectionTypeAnnotation = IntersectionTypeAnnotation;
exports.NullableTypeAnnotation = NullableTypeAnnotation;
exports.NumberTypeAnnotation = NumberTypeAnnotation;
exports.StringLiteralTypeAnnotation = StringLiteralTypeAnnotation;
exports.StringTypeAnnotation = StringTypeAnnotation;
exports.TupleTypeAnnotation = TupleTypeAnnotation;
exports.TypeofTypeAnnotation = TypeofTypeAnnotation;
exports.TypeAlias = TypeAlias;
exports.TypeAnnotation = TypeAnnotation;
exports.TypeParameterInstantiation = TypeParameterInstantiation;
exports.ObjectTypeAnnotation = ObjectTypeAnnotation;
exports.ObjectTypeCallProperty = ObjectTypeCallProperty;
exports.ObjectTypeIndexer = ObjectTypeIndexer;
exports.ObjectTypeProperty = ObjectTypeProperty;
exports.QualifiedTypeIdentifier = QualifiedTypeIdentifier;
exports.UnionTypeAnnotation = UnionTypeAnnotation;
exports.TypeCastExpression = TypeCastExpression;
exports.VoidTypeAnnotation = VoidTypeAnnotation;
exports.__esModule = true;
var t = _interopRequireWildcard(require("../../types"));
function AnyTypeAnnotation() {
this.push("any");
}
function ArrayTypeAnnotation(node, print) {
print(node.elementType);
this.push("[");
this.push("]");
}
function BooleanTypeAnnotation(node) {
this.push("bool");
}
function DeclareClass(node, print) {
this.push("declare class ");
this._interfaceish(node, print);
}
function DeclareFunction(node, print) {
this.push("declare function ");
print(node.id);
print(node.id.typeAnnotation.typeAnnotation);
this.semicolon();
}
function DeclareModule(node, print) {
this.push("declare module ");
print(node.id);
this.space();
print(node.body);
}
function DeclareVariable(node, print) {
this.push("declare var ");
print(node.id);
print(node.id.typeAnnotation);
this.semicolon();
}
function FunctionTypeAnnotation(node, print, parent) {
print(node.typeParameters);
this.push("(");
print.list(node.params);
if (node.rest) {
if (node.params.length) {
this.push(",");
this.space();
}
this.push("...");
print(node.rest);
}
this.push(")");
// this node type is overloaded, not sure why but it makes it EXTREMELY annoying
if (parent.type === "ObjectTypeProperty" || parent.type === "ObjectTypeCallProperty" || parent.type === "DeclareFunction") {
this.push(":");
} else {
this.space();
this.push("=>");
}
this.space();
print(node.returnType);
}
function FunctionTypeParam(node, print) {
print(node.name);
if (node.optional) this.push("?");
this.push(":");
this.space();
print(node.typeAnnotation);
}
function InterfaceExtends(node, print) {
print(node.id);
print(node.typeParameters);
}
exports.ClassImplements = InterfaceExtends;
exports.GenericTypeAnnotation = InterfaceExtends;
function _interfaceish(node, print) {
print(node.id);
print(node.typeParameters);
if (node["extends"].length) {
this.push(" extends ");
print.join(node["extends"], { separator: ", " });
}
this.space();
print(node.body);
}
function InterfaceDeclaration(node, print) {
this.push("interface ");
this._interfaceish(node, print);
}
function IntersectionTypeAnnotation(node, print) {
print.join(node.types, { separator: " & " });
}
function NullableTypeAnnotation(node, print) {
this.push("?");
print(node.typeAnnotation);
}
function NumberTypeAnnotation() {
this.push("number");
}
function StringLiteralTypeAnnotation(node) {
this._stringLiteral(node.value);
}
function StringTypeAnnotation() {
this.push("string");
}
function TupleTypeAnnotation(node, print) {
this.push("[");
print.join(node.types, { separator: ", " });
this.push("]");
}
function TypeofTypeAnnotation(node, print) {
this.push("typeof ");
print(node.argument);
}
function TypeAlias(node, print) {
this.push("type ");
print(node.id);
print(node.typeParameters);
this.space();
this.push("=");
this.space();
print(node.right);
this.semicolon();
}
function TypeAnnotation(node, print) {
this.push(":");
this.space();
if (node.optional) this.push("?");
print(node.typeAnnotation);
}
function TypeParameterInstantiation(node, print) {
this.push("<");
print.join(node.params, { separator: ", " });
this.push(">");
}
exports.TypeParameterDeclaration = TypeParameterInstantiation;
function ObjectTypeAnnotation(node, print) {
var _this = this;
this.push("{");
var props = node.properties.concat(node.callProperties, node.indexers);
if (props.length) {
this.space();
print.list(props, {
separator: false,
indent: true,
iterator: function () {
if (props.length !== 1) {
_this.semicolon();
_this.space();
}
}
});
this.space();
}
this.push("}");
}
function ObjectTypeCallProperty(node, print) {
if (node["static"]) this.push("static ");
print(node.value);
}
function ObjectTypeIndexer(node, print) {
if (node["static"]) this.push("static ");
this.push("[");
print(node.id);
this.push(":");
this.space();
print(node.key);
this.push("]");
this.push(":");
this.space();
print(node.value);
}
function ObjectTypeProperty(node, print) {
if (node["static"]) this.push("static ");
print(node.key);
if (node.optional) this.push("?");
if (!t.isFunctionTypeAnnotation(node.value)) {
this.push(":");
this.space();
}
print(node.value);
}
function QualifiedTypeIdentifier(node, print) {
print(node.qualification);
this.push(".");
print(node.id);
}
function UnionTypeAnnotation(node, print) {
print.join(node.types, { separator: " | " });
}
function TypeCastExpression(node, print) {
this.push("(");
print(node.expression);
print(node.typeAnnotation);
this.push(")");
}
function VoidTypeAnnotation(node) {
this.push("void");
}

View File

@ -0,0 +1,95 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.JSXAttribute = JSXAttribute;
exports.JSXIdentifier = JSXIdentifier;
exports.JSXNamespacedName = JSXNamespacedName;
exports.JSXMemberExpression = JSXMemberExpression;
exports.JSXSpreadAttribute = JSXSpreadAttribute;
exports.JSXExpressionContainer = JSXExpressionContainer;
exports.JSXElement = JSXElement;
exports.JSXOpeningElement = JSXOpeningElement;
exports.JSXClosingElement = JSXClosingElement;
exports.JSXEmptyExpression = JSXEmptyExpression;
exports.__esModule = true;
var each = _interopRequire(require("lodash/collection/each"));
var t = _interopRequireWildcard(require("../../types"));
function JSXAttribute(node, print) {
print(node.name);
if (node.value) {
this.push("=");
print(node.value);
}
}
function JSXIdentifier(node) {
this.push(node.name);
}
function JSXNamespacedName(node, print) {
print(node.namespace);
this.push(":");
print(node.name);
}
function JSXMemberExpression(node, print) {
print(node.object);
this.push(".");
print(node.property);
}
function JSXSpreadAttribute(node, print) {
this.push("{...");
print(node.argument);
this.push("}");
}
function JSXExpressionContainer(node, print) {
this.push("{");
print(node.expression);
this.push("}");
}
function JSXElement(node, print) {
var _this = this;
var open = node.openingElement;
print(open);
if (open.selfClosing) return;
this.indent();
each(node.children, function (child) {
if (t.isLiteral(child)) {
_this.push(child.value);
} else {
print(child);
}
});
this.dedent();
print(node.closingElement);
}
function JSXOpeningElement(node, print) {
this.push("<");
print(node.name);
if (node.attributes.length > 0) {
this.push(" ");
print.join(node.attributes, { separator: " " });
}
this.push(node.selfClosing ? " />" : ">");
}
function JSXClosingElement(node, print) {
this.push("</");
print(node.name);
this.push(">");
}
function JSXEmptyExpression() {}

View File

@ -0,0 +1,102 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
exports._params = _params;
exports._method = _method;
exports.FunctionExpression = FunctionExpression;
exports.ArrowFunctionExpression = ArrowFunctionExpression;
exports.__esModule = true;
var t = _interopRequireWildcard(require("../../types"));
function _params(node, print) {
var _this = this;
print(node.typeParameters);
this.push("(");
print.list(node.params, {
iterator: function (node) {
if (node.optional) _this.push("?");
print(node.typeAnnotation);
}
});
this.push(")");
if (node.returnType) {
print(node.returnType);
}
}
function _method(node, print) {
var value = node.value;
var kind = node.kind;
var key = node.key;
if (kind === "method" || kind === "init") {
if (value.generator) {
this.push("*");
}
}
if (kind === "get" || kind === "set") {
this.push(kind + " ");
}
if (value.async) this.push("async ");
if (node.computed) {
this.push("[");
print(key);
this.push("]");
} else {
print(key);
}
this._params(value, print);
this.push(" ");
print(value.body);
}
function FunctionExpression(node, print) {
if (node.async) this.push("async ");
this.push("function");
if (node.generator) this.push("*");
if (node.id) {
this.push(" ");
print(node.id);
} else {
this.space();
}
this._params(node, print);
this.space();
print(node.body);
}
exports.FunctionDeclaration = FunctionExpression;
function ArrowFunctionExpression(node, print) {
if (node.async) this.push("async ");
if (node.params.length === 1 && t.isIdentifier(node.params[0])) {
print(node.params[0]);
} else {
this._params(node, print);
}
this.push(" => ");
var bodyNeedsParens = t.isObjectExpression(node.body);
if (bodyNeedsParens) {
this.push("(");
}
print(node.body);
if (bodyNeedsParens) {
this.push(")");
}
}

View File

@ -0,0 +1,145 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.ImportSpecifier = ImportSpecifier;
exports.ImportDefaultSpecifier = ImportDefaultSpecifier;
exports.ExportDefaultSpecifier = ExportDefaultSpecifier;
exports.ExportSpecifier = ExportSpecifier;
exports.ExportNamespaceSpecifier = ExportNamespaceSpecifier;
exports.ExportAllDeclaration = ExportAllDeclaration;
exports.ExportNamedDeclaration = ExportNamedDeclaration;
exports.ExportDefaultDeclaration = ExportDefaultDeclaration;
exports.ImportDeclaration = ImportDeclaration;
exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier;
exports.__esModule = true;
var each = _interopRequire(require("lodash/collection/each"));
var t = _interopRequireWildcard(require("../../types"));
function ImportSpecifier(node, print) {
print(node.imported);
if (node.local && node.local !== node.imported) {
this.push(" as ");
print(node.local);
}
}
function ImportDefaultSpecifier(node, print) {
print(node.local);
}
function ExportDefaultSpecifier(node, print) {
print(node.exported);
}
function ExportSpecifier(node, print) {
print(node.local);
if (node.exported && node.local !== node.exported) {
this.push(" as ");
print(node.exported);
}
}
function ExportNamespaceSpecifier(node, print) {
this.push("* as ");
print(node.exported);
}
function ExportAllDeclaration(node, print) {
this.push("export *");
if (node.exported) {
this.push(" as ");
print(node.exported);
}
this.push(" from ");
print(node.source);
this.semicolon();
}
function ExportNamedDeclaration(node, print) {
this.push("export ");
ExportDeclaration.call(this, node, print);
}
function ExportDefaultDeclaration(node, print) {
this.push("export default ");
ExportDeclaration.call(this, node, print);
}
function ExportDeclaration(node, print) {
var specifiers = node.specifiers;
if (node.declaration) {
var declar = node.declaration;
print(declar);
if (t.isStatement(declar) || t.isFunction(declar) || t.isClass(declar)) return;
} else {
var first = specifiers[0];
var hasSpecial = false;
if (t.isExportDefaultSpecifier(first) || t.isExportNamespaceSpecifier(first)) {
hasSpecial = true;
print(specifiers.shift());
if (specifiers.length) {
this.push(", ");
}
}
if (specifiers.length || !specifiers.length && !hasSpecial) {
this.push("{");
if (specifiers.length) {
this.space();
print.join(specifiers, { separator: ", " });
this.space();
}
this.push("}");
}
if (node.source) {
this.push(" from ");
print(node.source);
}
}
this.ensureSemicolon();
}
function ImportDeclaration(node, print) {
this.push("import ");
if (node.isType) {
this.push("type ");
}
var specfiers = node.specifiers;
if (specfiers && specfiers.length) {
var first = node.specifiers[0];
if (t.isImportDefaultSpecifier(first) || t.isImportNamespaceSpecifier(first)) {
print(node.specifiers.shift());
if (node.specifiers.length) {
this.push(", ");
}
}
if (node.specifiers.length) {
this.push("{");
this.space();
print.join(node.specifiers, { separator: ", " });
this.space();
this.push("}");
}
this.push(" from ");
}
print(node.source);
this.semicolon();
}
function ImportNamespaceSpecifier(node, print) {
this.push("* as ");
print(node.local);
}

View File

@ -0,0 +1,248 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.WithStatement = WithStatement;
exports.IfStatement = IfStatement;
exports.ForStatement = ForStatement;
exports.WhileStatement = WhileStatement;
exports.DoWhileStatement = DoWhileStatement;
exports.LabeledStatement = LabeledStatement;
exports.TryStatement = TryStatement;
exports.CatchClause = CatchClause;
exports.ThrowStatement = ThrowStatement;
exports.SwitchStatement = SwitchStatement;
exports.SwitchCase = SwitchCase;
exports.DebuggerStatement = DebuggerStatement;
exports.VariableDeclaration = VariableDeclaration;
exports.VariableDeclarator = VariableDeclarator;
exports.__esModule = true;
var repeating = _interopRequire(require("repeating"));
var t = _interopRequireWildcard(require("../../types"));
function WithStatement(node, print) {
this.keyword("with");
this.push("(");
print(node.object);
this.push(")");
print.block(node.body);
}
function IfStatement(node, print) {
this.keyword("if");
this.push("(");
print(node.test);
this.push(")");
this.space();
print.indentOnComments(node.consequent);
if (node.alternate) {
if (this.isLast("}")) this.space();
this.push("else ");
print.indentOnComments(node.alternate);
}
}
function ForStatement(node, print) {
this.keyword("for");
this.push("(");
print(node.init);
this.push(";");
if (node.test) {
this.push(" ");
print(node.test);
}
this.push(";");
if (node.update) {
this.push(" ");
print(node.update);
}
this.push(")");
print.block(node.body);
}
function WhileStatement(node, print) {
this.keyword("while");
this.push("(");
print(node.test);
this.push(")");
print.block(node.body);
}
var buildForXStatement = function buildForXStatement(op) {
return function (node, print) {
this.keyword("for");
this.push("(");
print(node.left);
this.push(" " + op + " ");
print(node.right);
this.push(")");
print.block(node.body);
};
};
var ForInStatement = buildForXStatement("in");
exports.ForInStatement = ForInStatement;
var ForOfStatement = buildForXStatement("of");
exports.ForOfStatement = ForOfStatement;
function DoWhileStatement(node, print) {
this.push("do ");
print(node.body);
this.space();
this.keyword("while");
this.push("(");
print(node.test);
this.push(");");
}
var buildLabelStatement = function buildLabelStatement(prefix, key) {
return function (node, print) {
this.push(prefix);
var label = node[key || "label"];
if (label) {
this.push(" ");
print(label);
}
this.semicolon();
};
};
var ContinueStatement = buildLabelStatement("continue");
exports.ContinueStatement = ContinueStatement;
var ReturnStatement = buildLabelStatement("return", "argument");
exports.ReturnStatement = ReturnStatement;
var BreakStatement = buildLabelStatement("break");
exports.BreakStatement = BreakStatement;
function LabeledStatement(node, print) {
print(node.label);
this.push(": ");
print(node.body);
}
function TryStatement(node, print) {
this.keyword("try");
print(node.block);
this.space();
// Esprima bug puts the catch clause in a `handlers` array.
// see https://code.google.com/p/esprima/issues/detail?id=433
// We run into this from regenerator generated ast.
if (node.handlers) {
print(node.handlers[0]);
} else {
print(node.handler);
}
if (node.finalizer) {
this.space();
this.push("finally ");
print(node.finalizer);
}
}
function CatchClause(node, print) {
this.keyword("catch");
this.push("(");
print(node.param);
this.push(") ");
print(node.body);
}
function ThrowStatement(node, print) {
this.push("throw ");
print(node.argument);
this.semicolon();
}
function SwitchStatement(node, print) {
this.keyword("switch");
this.push("(");
print(node.discriminant);
this.push(")");
this.space();
this.push("{");
print.sequence(node.cases, {
indent: true,
addNewlines: function addNewlines(leading, cas) {
if (!leading && node.cases[node.cases.length - 1] === cas) return -1;
}
});
this.push("}");
}
function SwitchCase(node, print) {
if (node.test) {
this.push("case ");
print(node.test);
this.push(":");
} else {
this.push("default:");
}
if (node.consequent.length) {
this.newline();
print.sequence(node.consequent, { indent: true });
}
}
function DebuggerStatement() {
this.push("debugger;");
}
function VariableDeclaration(node, print, parent) {
this.push(node.kind + " ");
var hasInits = false;
// don't add whitespace to loop heads
if (!t.isFor(parent)) {
for (var i = 0; i < node.declarations.length; i++) {
if (node.declarations[i].init) {
// has an init so let's split it up over multiple lines
hasInits = true;
}
}
}
var sep = ",";
if (!this.format.compact && hasInits) {
sep += "\n" + repeating(" ", node.kind.length + 1);
} else {
sep += " ";
}
print.list(node.declarations, { separator: sep });
if (t.isFor(parent)) {
if (parent.left === node || parent.init === node) return;
}
this.semicolon();
}
function VariableDeclarator(node, print) {
print(node.id);
print(node.id.typeAnnotation);
if (node.init) {
this.space();
this.push("=");
this.space();
print(node.init);
}
}

View File

@ -0,0 +1,40 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.TaggedTemplateExpression = TaggedTemplateExpression;
exports.TemplateElement = TemplateElement;
exports.TemplateLiteral = TemplateLiteral;
exports.__esModule = true;
var each = _interopRequire(require("lodash/collection/each"));
function TaggedTemplateExpression(node, print) {
print(node.tag);
print(node.quasi);
}
function TemplateElement(node) {
this._push(node.value.raw);
}
function TemplateLiteral(node, print) {
var _this = this;
this.push("`");
var quasis = node.quasis;
var len = quasis.length;
each(quasis, function (quasi, i) {
print(quasi);
if (i + 1 < len) {
_this.push("${ ");
print(node.expressions[i]);
_this.push(" }");
}
});
this._push("`");
}

View File

@ -0,0 +1,126 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.Identifier = Identifier;
exports.RestElement = RestElement;
exports.ObjectExpression = ObjectExpression;
exports.Property = Property;
exports.ArrayExpression = ArrayExpression;
exports.Literal = Literal;
exports._stringLiteral = _stringLiteral;
exports.__esModule = true;
var each = _interopRequire(require("lodash/collection/each"));
function Identifier(node) {
this.push(node.name);
}
function RestElement(node, print) {
this.push("...");
print(node.argument);
}
exports.SpreadElement = RestElement;
exports.SpreadProperty = RestElement;
function ObjectExpression(node, print) {
var props = node.properties;
if (props.length) {
this.push("{");
this.space();
print.list(props, { indent: true });
this.space();
this.push("}");
} else {
this.push("{}");
}
}
exports.ObjectPattern = ObjectExpression;
function Property(node, print) {
if (node.method || node.kind === "get" || node.kind === "set") {
this._method(node, print);
} else {
if (node.computed) {
this.push("[");
print(node.key);
this.push("]");
} else {
print(node.key);
if (node.shorthand) return;
}
this.push(":");
this.space();
print(node.value);
}
}
function ArrayExpression(node, print) {
var _this = this;
var elems = node.elements;
var len = elems.length;
this.push("[");
each(elems, function (elem, i) {
if (!elem) {
// If the array expression ends with a hole, that hole
// will be ignored by the interpreter, but if it ends with
// two (or more) holes, we need to write out two (or more)
// commas so that the resulting code is interpreted with
// both (all) of the holes.
_this.push(",");
} else {
if (i > 0) _this.push(" ");
print(elem);
if (i < len - 1) _this.push(",");
}
});
this.push("]");
}
exports.ArrayPattern = ArrayExpression;
function Literal(node) {
var val = node.value;
var type = typeof val;
if (type === "string") {
this._stringLiteral(val);
} else if (type === "number") {
this.push(val + "");
} else if (type === "boolean") {
this.push(val ? "true" : "false");
} else if (node.regex) {
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
} else if (val === null) {
this.push("null");
}
}
function _stringLiteral(val) {
val = JSON.stringify(val);
// escape illegal js but valid json unicode characters
val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) {
return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4);
});
if (this.format.quotes === "single") {
val = val.slice(1, -1);
val = val.replace(/\\"/g, "\"");
val = val.replace(/'/g, "\\'");
val = "'" + val + "'";
}
this.push(val);
}

View File

@ -0,0 +1,424 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var detectIndent = _interopRequire(require("detect-indent"));
var Whitespace = _interopRequire(require("./whitespace"));
var repeating = _interopRequire(require("repeating"));
var SourceMap = _interopRequire(require("./source-map"));
var Position = _interopRequire(require("./position"));
var messages = _interopRequireWildcard(require("../messages"));
var Buffer = _interopRequire(require("./buffer"));
var extend = _interopRequire(require("lodash/object/extend"));
var each = _interopRequire(require("lodash/collection/each"));
var n = _interopRequire(require("./node"));
var t = _interopRequireWildcard(require("../types"));
var CodeGenerator = (function () {
function CodeGenerator(ast, opts, code) {
_classCallCheck(this, CodeGenerator);
if (!opts) opts = {};
this.comments = ast.comments || [];
this.tokens = ast.tokens || [];
this.format = CodeGenerator.normalizeOptions(code, opts, this.tokens);
this.opts = opts;
this.ast = ast;
this.whitespace = new Whitespace(this.tokens, this.comments, this.format);
this.position = new Position();
this.map = new SourceMap(this.position, opts, code);
this.buffer = new Buffer(this.position, this.format);
}
CodeGenerator.normalizeOptions = function normalizeOptions(code, opts, tokens) {
var style = " ";
if (code) {
var indent = detectIndent(code).indent;
if (indent && indent !== " ") style = indent;
}
var format = {
comments: opts.comments == null || opts.comments,
compact: opts.compact,
quotes: CodeGenerator.findCommonStringDelimeter(code, tokens),
indent: {
adjustMultilineComment: true,
style: style,
base: 0
}
};
if (format.compact === "auto") {
format.compact = code.length > 100000; // 100KB
if (format.compact) {
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
}
}
return format;
};
CodeGenerator.findCommonStringDelimeter = function findCommonStringDelimeter(code, tokens) {
var occurences = {
single: 0,
double: 0
};
var checked = 0;
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (token.type.label !== "string") continue;
if (checked >= 3) continue;
var raw = code.slice(token.start, token.end);
if (raw[0] === "'") {
occurences.single++;
} else {
occurences.double++;
}
checked++;
}
if (occurences.single > occurences.double) {
return "single";
} else {
return "double";
}
};
CodeGenerator.generators = {
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
flow: require("./generators/flow"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
};
CodeGenerator.prototype.generate = function generate() {
var ast = this.ast;
this.print(ast);
var comments = [];
each(ast.comments, function (comment) {
if (!comment._displayed) comments.push(comment);
});
this._printComments(comments);
return {
map: this.map.get(),
code: this.buffer.get()
};
};
CodeGenerator.prototype.buildPrint = function buildPrint(parent) {
var _this = this;
var print = function (node, opts) {
return _this.print(node, parent, opts);
};
print.sequence = function (nodes) {
var opts = arguments[1] === undefined ? {} : arguments[1];
opts.statement = true;
return _this.printJoin(print, nodes, opts);
};
print.join = function (nodes, opts) {
return _this.printJoin(print, nodes, opts);
};
print.list = function (items) {
var opts = arguments[1] === undefined ? {} : arguments[1];
if (opts.separator == null) opts.separator = ", ";
print.join(items, opts);
};
print.block = function (node) {
return _this.printBlock(print, node);
};
print.indentOnComments = function (node) {
return _this.printAndIndentOnComments(print, node);
};
return print;
};
CodeGenerator.prototype.print = function print(node, parent) {
var _this = this;
var opts = arguments[2] === undefined ? {} : arguments[2];
if (!node) return;
if (parent && parent._compact) {
node._compact = true;
}
var oldConcise = this.format.concise;
if (node._compact) {
this.format.concise = true;
}
var newline = function (leading) {
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
}
var lines = 0;
if (node.start != null && !node._ignoreUserWhitespace) {
// user node
if (leading) {
lines = _this.whitespace.getNewlinesBefore(node);
} else {
lines = _this.whitespace.getNewlinesAfter(node);
}
} else {
// generated node
if (!leading) lines++; // always include at least a single line after
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
var needs = n.needsWhitespaceAfter;
if (leading) needs = n.needsWhitespaceBefore;
if (needs(node, parent)) lines++;
// generated nodes can't add starting file whitespace
if (!_this.buffer.buf) lines = 0;
}
_this.newline(lines);
};
if (this[node.type]) {
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
var needsParens = needsNoLineTermParens || n.needsParens(node, parent);
if (needsParens) this.push("(");
if (needsNoLineTermParens) this.indent();
this.printLeadingComments(node, parent);
newline(true);
if (opts.before) opts.before();
this.map.mark(node, "start");
this[node.type](node, this.buildPrint(node), parent);
if (needsNoLineTermParens) {
this.newline();
this.dedent();
}
if (needsParens) this.push(")");
this.map.mark(node, "end");
if (opts.after) opts.after();
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;
};
CodeGenerator.prototype.printJoin = function printJoin(print, nodes) {
var _this = this;
var opts = arguments[2] === undefined ? {} : arguments[2];
if (!nodes || !nodes.length) return;
var len = nodes.length;
if (opts.indent) this.indent();
each(nodes, function (node, i) {
print(node, {
statement: opts.statement,
addNewlines: opts.addNewlines,
after: function () {
if (opts.iterator) {
opts.iterator(node, i);
}
if (opts.separator && i < len - 1) {
_this.push(opts.separator);
}
}
});
});
if (opts.indent) this.dedent();
};
CodeGenerator.prototype.printAndIndentOnComments = function printAndIndentOnComments(print, node) {
var indent = !!node.leadingComments;
if (indent) this.indent();
print(node);
if (indent) this.dedent();
};
CodeGenerator.prototype.printBlock = function printBlock(print, node) {
if (t.isEmptyStatement(node)) {
this.semicolon();
} else {
this.push(" ");
print(node);
}
};
CodeGenerator.prototype.generateComment = function generateComment(comment) {
var val = comment.value;
if (comment.type === "Line") {
val = "//" + val;
} else {
val = "/*" + val + "*/";
}
return val;
};
CodeGenerator.prototype.printTrailingComments = function printTrailingComments(node, parent) {
this._printComments(this.getComments("trailingComments", node, parent));
};
CodeGenerator.prototype.printLeadingComments = function printLeadingComments(node, parent) {
this._printComments(this.getComments("leadingComments", node, parent));
};
CodeGenerator.prototype.getComments = function getComments(key, node, parent) {
var _this = this;
if (t.isExpressionStatement(parent)) {
return [];
}
var comments = [];
var nodes = [node];
if (t.isExpressionStatement(node)) {
nodes.push(node.argument);
}
each(nodes, function (node) {
comments = comments.concat(_this._getComments(key, node));
});
return comments;
};
CodeGenerator.prototype._getComments = function _getComments(key, node) {
return node && node[key] || [];
};
CodeGenerator.prototype._printComments = function _printComments(comments) {
var _this = this;
if (this.format.compact) return;
if (!this.format.comments) return;
if (!comments || !comments.length) return;
each(comments, function (comment) {
var skip = false;
// find the original comment in the ast and set it as displayed
each(_this.ast.comments, function (origComment) {
if (origComment.start === comment.start) {
// comment has already been output
if (origComment._displayed) skip = true;
origComment._displayed = true;
return false;
}
});
if (skip) return;
// whitespace before
_this.newline(_this.whitespace.getNewlinesBefore(comment));
var column = _this.position.column;
var val = _this.generateComment(comment);
if (column && !_this.isLast(["\n", " ", "[", "{"])) {
_this._push(" ");
column++;
}
//
if (comment.type === "Block" && _this.format.indent.adjustMultilineComment) {
var offset = comment.loc.start.column;
if (offset) {
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
}
var indent = Math.max(_this.indentSize(), column);
val = val.replace(/\n/g, "\n" + repeating(" ", indent));
}
if (column === 0) {
val = _this.getIndent() + val;
}
//
_this._push(val);
// whitespace after
_this.newline(_this.whitespace.getNewlinesAfter(comment));
});
};
return CodeGenerator;
})();
each(Buffer.prototype, function (fn, key) {
CodeGenerator.prototype[key] = function () {
return fn.apply(this.buffer, arguments);
};
});
each(CodeGenerator.generators, function (generator) {
extend(CodeGenerator.prototype, generator);
});
module.exports = function (ast, opts, code) {
var gen = new CodeGenerator(ast, opts, code);
return gen.generate();
};
module.exports.CodeGenerator = CodeGenerator;

View File

@ -0,0 +1,132 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var whitespace = _interopRequire(require("./whitespace"));
var parens = _interopRequireWildcard(require("./parentheses"));
var each = _interopRequire(require("lodash/collection/each"));
var some = _interopRequire(require("lodash/collection/some"));
var t = _interopRequireWildcard(require("../../types"));
var find = function find(obj, node, parent) {
if (!obj) return;
var result;
var types = Object.keys(obj);
for (var i = 0; i < types.length; i++) {
var type = types[i];
if (t.is(type, node)) {
var fn = obj[type];
result = fn(node, parent);
if (result != null) break;
}
}
return result;
};
var Node = (function () {
function Node(node, parent) {
_classCallCheck(this, Node);
this.parent = parent;
this.node = node;
}
Node.isUserWhitespacable = function isUserWhitespacable(node) {
return t.isUserWhitespacable(node);
};
Node.needsWhitespace = function needsWhitespace(node, parent, type) {
if (!node) return 0;
if (t.isExpressionStatement(node)) {
node = node.expression;
}
var linesInfo = find(whitespace.nodes, node, parent);
if (!linesInfo) {
var items = find(whitespace.list, node, parent);
if (items) {
for (var i = 0; i < items.length; i++) {
linesInfo = Node.needsWhitespace(items[i], node, type);
if (linesInfo) break;
}
}
}
return linesInfo && linesInfo[type] || 0;
};
Node.needsWhitespaceBefore = function needsWhitespaceBefore(node, parent) {
return Node.needsWhitespace(node, parent, "before");
};
Node.needsWhitespaceAfter = function needsWhitespaceAfter(node, parent) {
return Node.needsWhitespace(node, parent, "after");
};
Node.needsParens = function needsParens(node, parent) {
if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {
if (t.isCallExpression(node)) return true;
var hasCall = some(node, function (val) {
return t.isCallExpression(val);
});
if (hasCall) return true;
}
return find(parens, node, parent);
};
Node.needsParensNoLineTerminator = function needsParensNoLineTerminator(node, parent) {
if (!parent) return false;
// no comments
if (!node.leadingComments || !node.leadingComments.length) {
return false;
}
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
return true;
}
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) || t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
return true;
}
return false;
};
return Node;
})();
module.exports = Node;
each(Node, function (fn, key) {
Node.prototype[key] = function () {
// Avoid leaking arguments to prevent deoptimization
var args = new Array(arguments.length + 2);
args[0] = this.node;
args[1] = this.parent;
for (var i = 0; i < args.length; i++) {
args[i + 2] = arguments[i];
}
return Node[key].apply(null, args);
};
});

View File

@ -0,0 +1,176 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.NullableTypeAnnotation = NullableTypeAnnotation;
exports.UpdateExpression = UpdateExpression;
exports.ObjectExpression = ObjectExpression;
exports.Binary = Binary;
exports.BinaryExpression = BinaryExpression;
exports.SequenceExpression = SequenceExpression;
exports.YieldExpression = YieldExpression;
exports.ClassExpression = ClassExpression;
exports.UnaryLike = UnaryLike;
exports.FunctionExpression = FunctionExpression;
exports.ConditionalExpression = ConditionalExpression;
exports.__esModule = true;
var each = _interopRequire(require("lodash/collection/each"));
var t = _interopRequireWildcard(require("../../types"));
var PRECEDENCE = {};
each([["||"], ["&&"], ["|"], ["^"], ["&"], ["==", "===", "!=", "!=="], ["<", ">", "<=", ">=", "in", "instanceof"], [">>", "<<", ">>>"], ["+", "-"], ["*", "/", "%"], ["**"]], function (tier, i) {
each(tier, function (op) {
PRECEDENCE[op] = i;
});
});
function NullableTypeAnnotation(node, parent) {
return t.isArrayTypeAnnotation(parent);
}
exports.FunctionTypeAnnotation = NullableTypeAnnotation;
function UpdateExpression(node, parent) {
if (t.isMemberExpression(parent) && parent.object === node) {
// (foo++).test()
return true;
}
}
function ObjectExpression(node, parent) {
if (t.isExpressionStatement(parent)) {
// ({ foo: "bar" });
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
// ({ foo: "bar" }).foo
return true;
}
return false;
}
function Binary(node, parent) {
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
return true;
}
if (t.isUnaryLike(parent)) {
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
if (t.isBinary(parent)) {
var parentOp = parent.operator;
var parentPos = PRECEDENCE[parentOp];
var nodeOp = node.operator;
var nodePos = PRECEDENCE[nodeOp];
if (parentPos > nodePos) {
return true;
}
if (parentPos === nodePos && parent.right === node) {
return true;
}
}
}
function BinaryExpression(node, parent) {
if (node.operator === "in") {
// var i = (1 in []);
if (t.isVariableDeclarator(parent)) {
return true;
}
// for ((1 in []);;);
if (t.isFor(parent)) {
return true;
}
}
}
function SequenceExpression(node, parent) {
if (t.isForStatement(parent)) {
// Although parentheses wouldn't hurt around sequence
// expressions in the head of for loops, traditional style
// dictates that e.g. i++, j++ should not be wrapped with
// parentheses.
return false;
}
if (t.isExpressionStatement(parent) && parent.expression === node) {
return false;
}
// Otherwise err on the side of overparenthesization, adding
// explicit exceptions above if this proves overzealous.
return true;
}
function YieldExpression(node, parent) {
return t.isBinary(parent) || t.isUnaryLike(parent) || t.isCallExpression(parent) || t.isMemberExpression(parent) || t.isNewExpression(parent) || t.isConditionalExpression(parent) || t.isYieldExpression(parent);
}
function ClassExpression(node, parent) {
return t.isExpressionStatement(parent);
}
function UnaryLike(node, parent) {
return t.isMemberExpression(parent) && parent.object === node;
}
function FunctionExpression(node, parent) {
// function () {};
if (t.isExpressionStatement(parent)) {
return true;
}
// (function test() {}).name;
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
// (function () {})();
if (t.isCallExpression(parent) && parent.callee === node) {
return true;
}
}
function ConditionalExpression(node, parent) {
if (t.isUnaryLike(parent)) {
return true;
}
if (t.isBinary(parent)) {
return true;
}
if (t.isCallExpression(parent) || t.isNewExpression(parent)) {
if (parent.callee === node) {
return true;
}
}
if (t.isConditionalExpression(parent) && parent.test === node) {
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
return false;
}
exports.AssignmentExpression = ConditionalExpression;

View File

@ -0,0 +1,165 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var isBoolean = _interopRequire(require("lodash/lang/isBoolean"));
var each = _interopRequire(require("lodash/collection/each"));
var map = _interopRequire(require("lodash/collection/map"));
var t = _interopRequireWildcard(require("../../types"));
function crawl(node) {
var state = arguments[1] === undefined ? {} : arguments[1];
if (t.isMemberExpression(node)) {
crawl(node.object, state);
if (node.computed) crawl(node.property, state);
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
crawl(node.left, state);
crawl(node.right, state);
} else if (t.isCallExpression(node)) {
state.hasCall = true;
crawl(node.callee, state);
} else if (t.isFunction(node)) {
state.hasFunction = true;
} else if (t.isIdentifier(node)) {
var _state = state;
if (!_state.hasHelper) _state.hasHelper = isHelper(node.callee);
}
return state;
}
function isHelper(node) {
if (t.isMemberExpression(node)) {
return isHelper(node.object) || isHelper(node.property);
} else if (t.isIdentifier(node)) {
return node.name === "require" || node.name[0] === "_";
} else if (t.isCallExpression(node)) {
return isHelper(node.callee);
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
return t.isIdentifier(node.left) && isHelper(node.left) || isHelper(node.right);
} else {
return false;
}
}
function isType(node) {
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) || t.isIdentifier(node) || t.isMemberExpression(node);
}
exports.nodes = {
AssignmentExpression: function AssignmentExpression(node) {
var state = crawl(node.right);
if (state.hasCall && state.hasHelper || state.hasFunction) {
return {
before: state.hasFunction,
after: true
};
}
},
SwitchCase: function SwitchCase(node, parent) {
return {
before: node.consequent.length || parent.cases[0] === node
};
},
LogicalExpression: function LogicalExpression(node) {
if (t.isFunction(node.left) || t.isFunction(node.right)) {
return {
after: true
};
}
},
Literal: function Literal(node) {
if (node.value === "use strict") {
return {
after: true
};
}
},
CallExpression: function CallExpression(node) {
if (t.isFunction(node.callee) || isHelper(node)) {
return {
before: true,
after: true
};
}
},
VariableDeclaration: function VariableDeclaration(node) {
for (var i = 0; i < node.declarations.length; i++) {
var declar = node.declarations[i];
var enabled = isHelper(declar.id) && !isType(declar.init);
if (!enabled) {
var state = crawl(declar.init);
enabled = isHelper(declar.init) && state.hasCall || state.hasFunction;
}
if (enabled) {
return {
before: true,
after: true
};
}
}
},
IfStatement: function IfStatement(node) {
if (t.isBlockStatement(node.consequent)) {
return {
before: true,
after: true
};
}
}
};
exports.nodes.Property = exports.nodes.SpreadProperty = function (node, parent) {
if (parent.properties[0] === node) {
return {
before: true
};
}
};
exports.list = {
VariableDeclaration: function VariableDeclaration(node) {
return map(node.declarations, "init");
},
ArrayExpression: function ArrayExpression(node) {
return node.elements;
},
ObjectExpression: function ObjectExpression(node) {
return node.properties;
}
};
each({
Function: true,
Class: true,
Loop: true,
LabeledStatement: true,
SwitchStatement: true,
TryStatement: true
}, function (amounts, type) {
if (isBoolean(amounts)) {
amounts = { after: amounts, before: amounts };
}
each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
exports.nodes[type] = function () {
return amounts;
};
});
});

View File

@ -0,0 +1,37 @@
"use strict";
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var Position = (function () {
function Position() {
_classCallCheck(this, Position);
this.line = 1;
this.column = 0;
}
Position.prototype.push = function push(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
this.line++;
this.column = 0;
} else {
this.column++;
}
}
};
Position.prototype.unshift = function unshift(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
this.line--;
} else {
this.column--;
}
}
};
return Position;
})();
module.exports = Position;

View File

@ -0,0 +1,69 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var sourceMap = _interopRequire(require("source-map"));
var t = _interopRequireWildcard(require("../types"));
var SourceMap = (function () {
function SourceMap(position, opts, code) {
_classCallCheck(this, SourceMap);
this.position = position;
this.opts = opts;
if (opts.sourceMaps) {
this.map = new sourceMap.SourceMapGenerator({
file: opts.sourceMapName,
sourceRoot: opts.sourceRoot
});
this.map.setSourceContent(opts.sourceFileName, code);
} else {
this.map = null;
}
}
SourceMap.prototype.get = function get() {
var map = this.map;
if (map) {
return map.toJSON();
} else {
return map;
}
};
SourceMap.prototype.mark = function mark(node, type) {
var loc = node.loc;
if (!loc) return; // no location info
var map = this.map;
if (!map) return; // no source map
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes
var position = this.position;
var generated = {
line: position.line,
column: position.column
};
var original = loc[type];
map.addMapping({
source: this.opts.sourceFileName,
generated: generated,
original: original
});
};
return SourceMap;
})();
module.exports = SourceMap;

View File

@ -0,0 +1,125 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var sortBy = _interopRequire(require("lodash/collection/sortBy"));
/**
* Returns `i`th number from `base`, continuing from 0 when `max` is reached.
* Useful for shifting `for` loop by a fixed number but going over all items.
*
* @param {Number} i Current index in the loop
* @param {Number} base Start index for which to return 0
* @param {Number} max Array length
* @returns {Number} shiftedIndex
*/
function getLookupIndex(i, base, max) {
i += base;
if (i >= max) {
i -= max;
}
return i;
}
var Whitespace = (function () {
function Whitespace(tokens, comments) {
_classCallCheck(this, Whitespace);
this.tokens = sortBy(tokens.concat(comments), "start");
this.used = {};
// Profiling this code shows that while generator passes over it, indexes
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing.
// We use this implementation detail for an optimization: instead of always
// starting to look from `this.tokens[0]`, we will start `for` loops from the
// previous successful match. We will enumerate all tokens—but the common
// case will be much faster.
this._lastFoundIndex = 0;
}
Whitespace.prototype.getNewlinesBefore = function getNewlinesBefore(node) {
var startToken;
var endToken;
var tokens = this.tokens;
var token;
for (var j = 0; j < tokens.length; j++) {
// optimize for forward traversal by shifting for loop index
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
token = tokens[i];
// this is the token this node starts with
if (node.start === token.start) {
startToken = tokens[i - 1];
endToken = token;
this._lastFoundIndex = i;
break;
}
}
return this.getNewlinesBetween(startToken, endToken);
};
Whitespace.prototype.getNewlinesAfter = function getNewlinesAfter(node) {
var startToken;
var endToken;
var tokens = this.tokens;
var token;
for (var j = 0; j < tokens.length; j++) {
// optimize for forward traversal by shifting for loop index
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
token = tokens[i];
// this is the token this node ends with
if (node.end === token.end) {
startToken = token;
endToken = tokens[i + 1];
this._lastFoundIndex = i;
break;
}
}
if (endToken && endToken.type.label === "eof") {
return 1;
} else {
var lines = this.getNewlinesBetween(startToken, endToken);
if (node.type === "Line" && !lines) {
// line comment
return 1;
} else {
return lines;
}
}
};
Whitespace.prototype.getNewlinesBetween = function getNewlinesBetween(startToken, endToken) {
if (!endToken || !endToken.loc) return 0;
var start = startToken ? startToken.loc.end.line : 1;
var end = endToken.loc.start.line;
var lines = 0;
for (var line = start; line < end; line++) {
if (typeof this.used[line] === "undefined") {
this.used[line] = true;
lines++;
}
}
return lines;
};
return Whitespace;
})();
module.exports = Whitespace;

View File

@ -0,0 +1,104 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var lineNumbers = _interopRequire(require("line-numbers"));
var repeating = _interopRequire(require("repeating"));
var jsTokens = _interopRequire(require("js-tokens"));
var esutils = _interopRequire(require("esutils"));
var chalk = _interopRequire(require("chalk"));
var defs = {
string: chalk.red,
punctuator: chalk.bold,
curly: chalk.green,
parens: chalk.blue.bold,
square: chalk.yellow,
keyword: chalk.cyan,
number: chalk.magenta,
regex: chalk.magenta,
comment: chalk.grey,
invalid: chalk.inverse
};
var NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
function getTokenType(match) {
var token = jsTokens.matchToToken(match);
if (token.type === "name" && esutils.keyword.isReservedWordES6(token.value)) {
return "keyword";
}
if (token.type === "punctuator") {
switch (token.value) {
case "{":
case "}":
return "curly";
case "(":
case ")":
return "parens";
case "[":
case "]":
return "square";
}
}
return token.type;
}
function highlight(text) {
return text.replace(jsTokens, function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var type = getTokenType(args);
var colorize = defs[type];
if (colorize) {
return args[0].split(NEWLINE).map(function (str) {
return colorize(str);
}).join("\n");
} else {
return args[0];
}
});
}
module.exports = function (lines, lineNumber, colNumber) {
var opts = arguments[3] === undefined ? {} : arguments[3];
colNumber = Math.max(colNumber, 0);
if (opts.highlightCode && chalk.supportsColor) {
lines = highlight(lines);
}
lines = lines.split(NEWLINE);
var start = Math.max(lineNumber - 3, 0);
var end = Math.min(lines.length, lineNumber + 3);
if (!lineNumber && !colNumber) {
start = 0;
end = lines.length;
}
return lineNumbers(lines.slice(start, end), {
start: start + 1,
before: " ",
after: " | ",
transform: function transform(params) {
if (params.number !== lineNumber) {
return;
}
if (colNumber) {
params.line += "\n" + params.before + "" + repeating(" ", params.width) + "" + params.after + "" + repeating(" ", colNumber - 1) + "^";
}
params.before = params.before.replace(/^./, ">");
}
}).join("\n");
};

View File

@ -0,0 +1,13 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var t = _interopRequireWildcard(require("../types"));
module.exports = function (ast, comments, tokens) {
if (ast && ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);
} else {
throw new Error("Not a valid ast?");
}
};

View File

@ -0,0 +1,5 @@
"use strict";
module.exports = function () {
return Object.create(null);
};

View File

@ -0,0 +1,74 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var normalizeAst = _interopRequire(require("./normalize-ast"));
var estraverse = _interopRequire(require("estraverse"));
var codeFrame = _interopRequire(require("./code-frame"));
var acorn = _interopRequireWildcard(require("../../acorn"));
module.exports = function (opts, code, callback) {
try {
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
};
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) {}
}
}
throw err;
}
};
// `err.stack` may be a readonly property in some environments

View File

@ -0,0 +1,65 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
exports.get = get;
exports.parseArgs = parseArgs;
exports.__esModule = true;
var util = _interopRequireWildcard(require("util"));
var MESSAGES = {
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
classesIllegalBareSuper: "Illegal use of bare super",
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
classesIllegalConstructorKind: "Illegal kind for constructor method",
scopeDuplicateDeclaration: "Duplicate declaration $1",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
settersInvalidParamLength: "Setters must have exactly one parameter",
settersNoRest: "Setters aren't allowed to have a rest",
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
readOnly: "$1 is read-only",
modulesIllegalExportName: "Illegal export $1",
unknownForHead: "Unknown node type $1 in ForStatement",
didYouMean: "Did you mean $1?",
evalInStrictMode: "eval is not allowed in strict mode",
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
unsupportedOutputType: "Unsupported output type $1",
illegalMethodName: "Illegal method name $1"
};
exports.MESSAGES = MESSAGES;
function get(key) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var msg = MESSAGES[key];
if (!msg) throw new ReferenceError("Unknown message " + JSON.stringify(key));
args = parseArgs(args);
return msg.replace(/\$(\d+)/g, function (str, i) {
return args[--i];
});
}
function parseArgs(args) {
return args.map(function (val) {
if (val != null && val.inspect) {
return val.inspect();
} else {
try {
return JSON.stringify(val) || val + "";
} catch (e) {
return util.inspect(val);
}
}
});
}

View File

@ -0,0 +1,39 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var estraverse = _interopRequire(require("estraverse"));
var extend = _interopRequire(require("lodash/object/extend"));
var types = _interopRequire(require("ast-types"));
var t = _interopRequireWildcard(require("./types"));
// estraverse
extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
// regenerator/ast-types
var def = types.Type.def;
var or = types.Type.or;
//def("File")
// .bases("Node")
// .build("program")
// .field("program", def("Program"));
def("AssignmentPattern").bases("Pattern").build("left", "right").field("left", def("Pattern")).field("right", def("Expression"));
def("RestElement").bases("Pattern").build("argument").field("argument", def("expression"));
def("DoExpression").bases("Expression").build("body").field("body", [def("Statement")]);
def("ExportDefaultDeclaration").bases("Declaration").build("declaration").field("declaration", or(def("Declaration"), def("Expression"), null));
def("ExportNamedDeclaration").bases("Declaration").build("declaration").field("declaration", or(def("Declaration"), def("Expression"), null)).field("specifiers", [or(def("ExportSpecifier"))]).field("source", or(def("ModuleSpecifier"), null));
types.finalize();

View File

@ -0,0 +1,10 @@
"use strict";
if (global._babelPolyfill) {
throw new Error("only one instance of babel/polyfill is allowed");
}
global._babelPolyfill = true;
require("core-js/shim");
require("regenerator/runtime");

View File

@ -0,0 +1,88 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var generator = _interopRequire(require("../generation"));
var messages = _interopRequireWildcard(require("../messages"));
var util = _interopRequireWildcard(require("../util"));
var File = _interopRequire(require("../transformation/file"));
var each = _interopRequire(require("lodash/collection/each"));
var t = _interopRequireWildcard(require("../types"));
function buildGlobal(namespace, builder) {
var body = [];
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
var tree = t.program([t.expressionStatement(t.callExpression(container, [util.template("helper-self-global")]))]);
body.push(t.variableDeclaration("var", [t.variableDeclarator(namespace, t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([])))]));
builder(body);
return tree;
}
function buildUmd(namespace, builder) {
var body = [];
body.push(t.variableDeclaration("var", [t.variableDeclarator(namespace, t.identifier("global"))]));
builder(body);
var container = util.template("umd-commonjs-strict", {
FACTORY_PARAMETERS: t.identifier("global"),
BROWSER_ARGUMENTS: t.assignmentExpression("=", t.memberExpression(t.identifier("root"), namespace), t.objectExpression({})),
COMMON_ARGUMENTS: t.identifier("exports"),
AMD_ARGUMENTS: t.arrayExpression([t.literal("exports")]),
FACTORY_BODY: body,
UMD_ROOT: t.identifier("this")
});
return t.program([container]);
}
function buildVar(namespace, builder) {
var body = [];
body.push(t.variableDeclaration("var", [t.variableDeclarator(namespace, t.objectExpression({}))]));
builder(body);
return t.program(body);
}
function buildHelpers(body, namespace, whitelist) {
each(File.helpers, function (name) {
if (whitelist && whitelist.indexOf(name) === -1) return;
var key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement(t.assignmentExpression("=", t.memberExpression(namespace, key), util.template("helper-" + name))));
});
}
module.exports = function (whitelist) {
var outputType = arguments[1] === undefined ? "global" : arguments[1];
var namespace = t.identifier("babelHelpers");
var builder = function builder(body) {
return buildHelpers(body, namespace, whitelist);
};
var tree;
var build = ({
global: buildGlobal,
umd: buildUmd,
"var": buildVar
})[outputType];
if (build) {
tree = build(namespace, builder);
} else {
throw new Error(messages.get("unsupportedOutputType", outputType));
}
return generator(tree).code;
};

View File

@ -0,0 +1,65 @@
"use strict";
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var stripJsonComments = _interopRequire(require("strip-json-comments"));
var merge = _interopRequire(require("lodash/object/merge"));
var path = _interopRequire(require("path"));
var fs = _interopRequire(require("fs"));
var cache = {};
var jsons = {};
function exists(filename) {
if (!fs.existsSync) return false;
var cached = cache[filename];
if (cached != null) return cached;
return cache[filename] = fs.existsSync(filename);
}
module.exports = function (loc) {
var opts = arguments[1] === undefined ? {} : arguments[1];
var rel = ".babelrc";
function find(start, rel) {
var file = path.join(start, rel);
if (exists(file)) {
var content = fs.readFileSync(file, "utf8");
var json;
try {
var _jsons, _content;
json = (_jsons = jsons, _content = content, !_jsons[_content] && (_jsons[_content] = JSON.parse(stripJsonComments(content))), _jsons[_content]);
} catch (err) {
err.message = "" + file + ": " + err.message;
throw err;
}
if (json.breakConfig) return;
merge(opts, json, function (a, b) {
if (Array.isArray(a)) {
return a.concat(b);
}
});
}
var up = path.dirname(start);
if (up !== start) {
// root
find(up, rel);
}
}
if (opts.breakConfig !== true) {
find(loc, rel);
}
return opts;
};

View File

@ -0,0 +1,677 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var convertSourceMap = _interopRequire(require("convert-source-map"));
var optionParsers = _interopRequireWildcard(require("./option-parsers"));
var shebangRegex = _interopRequire(require("shebang-regex"));
var TraversalPath = _interopRequire(require("../../traversal/path"));
var isFunction = _interopRequire(require("lodash/lang/isFunction"));
var isAbsolute = _interopRequire(require("path-is-absolute"));
var resolveRc = _interopRequire(require("../../tools/resolve-rc"));
var sourceMap = _interopRequire(require("source-map"));
var transform = _interopRequire(require("./../index"));
var generate = _interopRequire(require("../../generation"));
var defaults = _interopRequire(require("lodash/object/defaults"));
var includes = _interopRequire(require("lodash/collection/includes"));
var traverse = _interopRequire(require("../../traversal"));
var assign = _interopRequire(require("lodash/object/assign"));
var Logger = _interopRequire(require("./logger"));
var parse = _interopRequire(require("../../helpers/parse"));
var Scope = _interopRequire(require("../../traversal/scope"));
var slash = _interopRequire(require("slash"));
var clone = _interopRequire(require("lodash/lang/clone"));
var util = _interopRequireWildcard(require("../../util"));
var path = _interopRequire(require("path"));
var each = _interopRequire(require("lodash/collection/each"));
var t = _interopRequireWildcard(require("../../types"));
var checkTransformerVisitor = {
enter: function enter(node, parent, scope, state) {
checkNode(state.stack, node, scope);
}
};
function checkNode(stack, node, scope) {
each(stack, function (pass) {
if (pass.shouldRun || pass.ran) return;
pass.checkNode(node, scope);
});
}
var File = (function () {
function File() {
var opts = arguments[0] === undefined ? {} : arguments[0];
_classCallCheck(this, File);
this.dynamicImportTypes = {};
this.dynamicImportIds = {};
this.dynamicImports = [];
this.usedHelpers = {};
this.dynamicData = {};
this.data = {};
this.uids = {};
this.lastStatements = [];
this.log = new Logger(this, opts.filename || "unknown");
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
}
File.helpers = ["inherits", "defaults", "create-class", "create-decorated-class", "create-decorated-object", "tagged-template-literal", "tagged-template-literal-loose", "interop-require", "to-array", "to-consumable-array", "sliced-to-array", "sliced-to-array-loose", "object-without-properties", "has-own", "slice", "bind", "define-property", "async-to-generator", "interop-require-wildcard", "typeof", "extends", "get", "set", "class-call-check", "object-destructuring-empty", "temporal-undefined", "temporal-assert-defined", "self-global", "default-props"];
File.soloHelpers = ["ludicrous-proxy-create", "ludicrous-proxy-directory"];
File.options = require("./options");
File.prototype.normalizeOptions = function normalizeOptions(opts) {
opts = assign({}, opts);
if (opts.filename) {
var rcFilename = opts.filename;
if (!isAbsolute(rcFilename)) rcFilename = path.join(process.cwd(), rcFilename);
opts = resolveRc(rcFilename, opts);
}
//
for (var key in opts) {
if (key[0] === "_") continue;
var option = File.options[key];
if (!option) this.log.error("Unknown option: " + key, ReferenceError);
}
for (var key in File.options) {
var option = File.options[key];
var val = opts[key];
if (!val && option.optional) continue;
if (val && option.deprecated) {
throw new Error("Deprecated option " + key + ": " + option.deprecated);
}
if (val == null) {
val = clone(option["default"]);
}
var optionParser = optionParsers[option.type];
if (optionParser) val = optionParser(key, val);
if (option.alias) {
var _opts = opts;
var _option$alias = option.alias;
if (!_opts[_option$alias]) _opts[_option$alias] = val;
} else {
opts[key] = val;
}
}
if (opts.inputSourceMap) {
opts.sourceMaps = true;
}
// normalize windows path separators to unix
opts.filename = slash(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = slash(opts.sourceRoot);
}
if (opts.moduleId) {
opts.moduleIds = true;
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.ignore = util.arrayify(opts.ignore, util.regexify);
opts.only = util.arrayify(opts.only, util.regexify);
defaults(opts, {
moduleRoot: opts.sourceRoot
});
defaults(opts, {
sourceRoot: opts.moduleRoot
});
defaults(opts, {
filenameRelative: opts.filename
});
defaults(opts, {
sourceFileName: opts.filenameRelative,
sourceMapName: opts.filenameRelative
});
//
if (opts.externalHelpers) {
this.set("helpersNamespace", t.identifier("babelHelpers"));
}
return opts;
};
File.prototype.isLoose = function isLoose(key) {
return includes(this.opts.loose, key);
};
File.prototype.buildTransformers = function buildTransformers() {
var file = this;
var transformers = this.transformers = {};
var secondaryStack = [];
var stack = [];
// build internal transformers
each(transform.transformers, function (transformer, key) {
var pass = transformers[key] = transformer.buildPass(file);
if (pass.canTransform()) {
stack.push(pass);
if (transformer.metadata.secondPass) {
secondaryStack.push(pass);
}
if (transformer.manipulateOptions) {
transformer.manipulateOptions(file.opts, file);
}
}
});
// init plugins!
var beforePlugins = [];
var afterPlugins = [];
for (var i = 0; i < file.opts.plugins.length; i++) {
this.addPlugin(file.opts.plugins[i], beforePlugins, afterPlugins);
}
stack = beforePlugins.concat(stack, afterPlugins);
// register
this.transformerStack = stack.concat(secondaryStack);
};
File.prototype.getModuleFormatter = function getModuleFormatter(type) {
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);
};
File.prototype.addPlugin = function addPlugin(name, before, after) {
var position = "before";
var plugin;
if (name) {
if (typeof name === "object" && name.transformer) {
plugin = name.transformer;
if (!position) position = name.position;
} else if (typeof name === "string") {
// this is a plugin in the form of "foobar" or "foobar:after"
// where the optional colon is the delimiter for plugin position in the transformer stack
var _ref = name.split(":");
var _ref2 = _slicedToArray(_ref, 2);
name = _ref2[0];
var _ref2$1 = _ref2[1];
position = _ref2$1 === undefined ? "before" : _ref2$1;
var loc = util.resolveRelative(name) || util.resolveRelative("babel-plugin-" + name);
if (loc) {
plugin = require(loc);
} else {
throw new ReferenceError("Unknown plugin " + JSON.stringify(name));
}
} else {
// not a string so we'll just assume that it's a direct Transformer instance, if not then
// the checks later on will complain
plugin = name;
}
} else {
throw new TypeError("Ilegal kind " + typeof name + " for plugin name " + JSON.stringify(name));
}
// validate position
if (position !== "before" && position !== "after") {
throw new TypeError("Plugin " + JSON.stringify(name) + " has an illegal position of " + JSON.stringify(position));
}
// validate transformer key
var key = plugin.key;
if (this.transformers[key]) {
throw new ReferenceError("The key for plugin " + JSON.stringify(name) + " of " + key + " collides with an existing plugin");
}
// validate Transformer instance
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
throw new TypeError("Plugin " + JSON.stringify(name) + " didn't export a default Transformer instance");
}
// build!
var pass = this.transformers[key] = plugin.buildPass(this);
if (pass.canTransform()) {
var stack = before;
if (position === "after") stack = after;
stack.push(pass);
}
};
File.prototype.parseInputSourceMap = function parseInputSourceMap(code) {
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;
};
File.prototype.parseShebang = function parseShebang(code) {
var shebangMatch = shebangRegex.exec(code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
// remove shebang
code = code.replace(shebangRegex, "");
}
return code;
};
File.prototype.set = function set(key, val) {
return this.data[key] = val;
};
File.prototype.setDynamic = function setDynamic(key, fn) {
this.dynamicData[key] = fn;
};
File.prototype.get = function get(key) {
var data = this.data[key];
if (data) {
return data;
} else {
var dynamic = this.dynamicData[key];
if (dynamic) {
return this.set(key, dynamic());
}
}
};
File.prototype.resolveModuleSource = (function (_resolveModuleSource) {
var _resolveModuleSourceWrapper = function resolveModuleSource(_x) {
return _resolveModuleSource.apply(this, arguments);
};
_resolveModuleSourceWrapper.toString = function () {
return _resolveModuleSource.toString();
};
return _resolveModuleSourceWrapper;
})(function (source) {
var resolveModuleSource = this.opts.resolveModuleSource;
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
return source;
});
File.prototype.addImport = function addImport(source, name, type) {
if (!name) name = source;
var id = this.dynamicImportIds[name];
if (!id) {
source = this.resolveModuleSource(source);
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
var specifiers = [t.importDefaultSpecifier(id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
declar._blockHoist = 3;
if (type) {
var _dynamicImportTypes, _type;
var modules = (_dynamicImportTypes = this.dynamicImportTypes, _type = type, !_dynamicImportTypes[_type] && (_dynamicImportTypes[_type] = []), _dynamicImportTypes[_type]);
modules.push(declar);
}
if (this.transformers["es6.modules"].canTransform()) {
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
this.moduleFormatter.hasLocalImports = true;
} else {
this.dynamicImports.push(declar);
}
}
return id;
};
File.prototype.isConsequenceExpressionStatement = function isConsequenceExpressionStatement(node) {
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0;
};
File.prototype.attachAuxiliaryComment = function attachAuxiliaryComment(node) {
var comment = this.opts.auxiliaryComment;
if (comment) {
var _node = node;
if (!_node.leadingComments) _node.leadingComments = [];
node.leadingComments.push({
type: "Line",
value: " " + comment
});
}
return node;
};
File.prototype.addHelper = function addHelper(name) {
var isSolo = includes(File.soloHelpers, name);
if (!isSolo && !includes(File.helpers, name)) {
throw new ReferenceError("Unknown helper " + name);
}
var program = this.ast.program;
var declar = program._declarations && program._declarations[name];
if (declar) return declar.id;
this.usedHelpers[name] = true;
if (!isSolo) {
var generator = this.get("helperGenerator");
var runtime = this.get("helpersNamespace");
if (generator) {
return generator(name);
} else if (runtime) {
var id = t.identifier(t.toIdentifier(name));
return t.memberExpression(runtime, id);
}
}
var ref = util.template("helper-" + name);
ref._compact = true;
var uid = this.scope.generateUidIdentifier(name);
this.scope.push({
key: name,
id: uid,
init: ref
});
return uid;
};
File.prototype.errorWithNode = function errorWithNode(node, msg) {
var Error = arguments[2] === undefined ? SyntaxError : arguments[2];
var loc = node.loc.start;
var err = new Error("Line " + loc.line + ": " + msg);
err.loc = loc;
return err;
};
File.prototype.addCode = function addCode(code) {
code = (code || "") + "";
code = this.parseInputSourceMap(code);
this.code = code;
return this.parseShebang(code);
};
File.prototype.shouldIgnore = function shouldIgnore() {
var opts = this.opts;
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
};
File.prototype.parse = (function (_parse) {
var _parseWrapper = function parse(_x2) {
return _parse.apply(this, arguments);
};
_parseWrapper.toString = function () {
return _parse.toString();
};
return _parseWrapper;
})(function (code) {
var _this = this;
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";
//
return parse(parseOpts, code, function (tree) {
_this.transform(tree);
return _this.generate();
});
});
File.prototype.setAst = function setAst(ast) {
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
this.scope = this.path.scope;
this.ast = ast;
this.path.traverse({
enter: function enter(node, parent, scope) {
if (this.isScope()) {
for (var key in scope.bindings) {
scope.bindings[key].setTypeAnnotation();
}
}
}
});
};
File.prototype.transform = function transform(ast) {
this.log.debug();
this.setAst(ast);
this.lastStatements = t.getLastStatements(ast.program);
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
modFormatter.init();
}
this.checkNode(ast);
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
this.call("post");
};
File.prototype.call = function call(key) {
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);
}
};
File.prototype.checkNode = (function (_checkNode) {
var _checkNodeWrapper = function checkNode(_x3, _x4) {
return _checkNode.apply(this, arguments);
};
_checkNodeWrapper.toString = function () {
return _checkNode.toString();
};
return _checkNodeWrapper;
})(function (node, scope) {
if (Array.isArray(node)) {
for (var i = 0; i < node.length; i++) {
this.checkNode(node[i], scope);
}
return;
}
var stack = this.transformerStack;
if (!scope) scope = this.scope;
checkNode(stack, node, scope);
scope.traverse(node, checkTransformerVisitor, {
stack: stack
});
});
File.prototype.mergeSourceMap = function mergeSourceMap(map) {
var opts = this.opts;
var inputMap = opts.inputSourceMap;
if (inputMap) {
map.sources[0] = inputMap.file;
var inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
var outputMapConsumer = new sourceMap.SourceMapConsumer(map);
var outputMapGenerator = sourceMap.SourceMapGenerator.fromSourceMap(outputMapConsumer);
outputMapGenerator.applySourceMap(inputMapConsumer);
var mergedMap = outputMapGenerator.toJSON();
mergedMap.sources = inputMap.sources;
mergedMap.file = inputMap.file;
return mergedMap;
}
return map;
};
File.prototype.generate = (function (_generate) {
var _generateWrapper = function generate() {
return _generate.apply(this, arguments);
};
_generateWrapper.toString = function () {
return _generate.toString();
};
return _generateWrapper;
})(function () {
var opts = this.opts;
var ast = this.ast;
var result = {
metadata: {},
code: "",
map: null,
ast: null
};
if (this.opts.metadataUsedHelpers) {
result.metadata.usedHelpers = Object.keys(this.usedHelpers);
}
if (opts.ast) result.ast = ast;
if (!opts.code) return result;
var _result = generate(ast, opts, this.code);
result.code = _result.code;
result.map = _result.map;
if (this.shebang) {
// add back shebang
result.code = "" + this.shebang + "\n" + result.code;
}
if (result.map) {
result.map = this.mergeSourceMap(result.map);
}
if (opts.sourceMaps === "inline" || opts.sourceMaps === "both") {
result.code += "\n" + convertSourceMap.fromObject(result.map).toComment();
}
if (opts.sourceMaps === "inline") {
result.map = null;
}
return result;
});
return File;
})();
module.exports = File;

View File

@ -0,0 +1,46 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var util = _interopRequireWildcard(require("../../util"));
var Logger = (function () {
function Logger(file, filename) {
_classCallCheck(this, Logger);
this.filename = filename;
this.file = file;
}
Logger.prototype._buildMessage = function _buildMessage(msg) {
var parts = "[BABEL] " + this.filename;
if (msg) parts += ": " + msg;
return parts;
};
Logger.prototype.error = function error(msg) {
var Constructor = arguments[1] === undefined ? Error : arguments[1];
throw new Constructor(this._buildMessage(msg));
};
Logger.prototype.deprecate = function deprecate(msg) {
if (!this.file.opts.suppressDeprecationMessages) {
console.error(this._buildMessage(msg));
}
};
Logger.prototype.debug = function debug(msg) {
util.debug(this._buildMessage(msg));
};
Logger.prototype.deopt = function deopt(node, msg) {
util.debug(this._buildMessage(msg));
};
return Logger;
})();
module.exports = Logger;

View File

@ -0,0 +1,42 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.transformerList = transformerList;
exports.number = number;
exports.boolean = boolean;
exports.booleanString = booleanString;
exports.list = list;
exports.__esModule = true;
var transform = _interopRequire(require("./../index"));
var util = _interopRequireWildcard(require("../../util"));
function transformerList(key, val) {
val = util.arrayify(val);
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
val = Object.keys(transform.transformers);
}
return transform._ensureTransformerNames(key, val);
}
function number(key, val) {
return +val;
}
function boolean(key, val) {
return !!val;
}
function booleanString(key, val) {
return util.booleanify(val);
}
function list(key, val) {
return util.list(val);
}

View File

@ -0,0 +1,211 @@
{
"filename": {
"type": "string",
"description": "filename to use when reading from stdin - this will be used in source-maps, errors etc",
"default": "unknown",
"shorthand": "f"
},
"filenameRelative": {
"hidden": true,
"type": "string"
},
"inputSourceMap": {
"hidden": true
},
"extra": {
"hidden": true,
"default": {}
},
"moduleId": {
"description": "specify a custom name for module ids",
"type": "string"
},
"nonStandard": {
"type": "boolean",
"default": true,
"description": "enable support for JSX and Flow"
},
"experimental": {
"deprecated": "use `--stage 0`/`{ stage: 0 }` instead"
},
"highlightCode": {
"description": "ANSI syntax highlight code frames",
"type": "boolean",
"default": true
},
"suppressDeprecationMessages": {
"type": "boolean",
"default": false,
"hidden": true
},
"resolveModuleSource": {
"hidden": true
},
"stage": {
"description": "ECMAScript proposal stage version to allow [0-4]",
"shorthand": "e",
"type": "number",
"default": 2
},
"blacklist": {
"type": "transformerList",
"description": "blacklist of transformers to NOT use",
"shorthand": "b"
},
"whitelist": {
"type": "transformerList",
"optional": true,
"description": "whitelist of transformers to ONLY use",
"shorthand": "l"
},
"optional": {
"type": "transformerList",
"description": "list of optional transformers to enable"
},
"modules": {
"type": "string",
"description": "module formatter type to use [common]",
"default": "common",
"shorthand": "m"
},
"moduleIds": {
"type": "boolean",
"default": false,
"shorthand": "M",
"description": "insert an explicit id for modules"
},
"loose": {
"type": "transformerList",
"description": "list of transformers to enable loose mode ON",
"shorthand": "L"
},
"jsxPragma": {
"type": "string",
"description": "custom pragma to use with JSX (same functionality as @jsx comments)",
"default": "React.createElement",
"shorthand": "P"
},
"plugins": {
"type": "list",
"description": ""
},
"ignore": {
"type": "list",
"description": "list of glob paths to **not** compile"
},
"only": {
"type": "list",
"description": "list of glob paths to **only** compile"
},
"code": {
"hidden": true,
"default": true,
"type": "boolean"
},
"ast": {
"hidden": true,
"default": true,
"type": "boolean"
},
"comments": {
"type": "boolean",
"default": true,
"description": "output comments in generated output"
},
"compact": {
"type": "booleanString",
"default": "auto",
"description": "do not include superfluous whitespace characters and line terminators [true|false|auto]"
},
"keepModuleIdExtensions": {
"type": "boolean",
"description": "keep extensions when generating module ids",
"default": false,
"shorthand": "k"
},
"auxiliaryComment": {
"type": "string",
"default": "",
"shorthand": "a",
"description": "attach a comment before all helper declarations and auxiliary code"
},
"externalHelpers": {
"type": "string",
"default": false,
"shorthand": "r",
"description": "uses a reference to `babelHelpers` instead of placing helpers at the top of your code."
},
"metadataUsedHelpers": {
"type": "boolean",
"default": false,
"hidden": true
},
"sourceMap": {
"alias": "sourceMaps",
"hidden": true
},
"sourceMaps": {
"type": "booleanString",
"description": "[true|false|inline]",
"default": false,
"shorthand": "s"
},
"sourceMapName": {
"type": "string",
"description": "set `file` on returned source map"
},
"sourceFileName": {
"type": "string",
"description": "set `sources[0]` on returned source map"
},
"sourceRoot": {
"type": "string",
"description": "the root from which all sources are relative"
},
"moduleRoot": {
"type": "string",
"description": "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions"
},
"breakConfig": {
"type": "boolean",
"default": false,
"hidden": true,
"description": "stop trying to load .babelrc files"
}
}

View File

@ -0,0 +1,48 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var explode = _interopRequire(require("./explode-assignable-expression"));
var t = _interopRequireWildcard(require("../../types"));
module.exports = function (exports, opts) {
var isAssignment = function isAssignment(node) {
return node.operator === opts.operator + "=";
};
var buildAssignment = function buildAssignment(left, right) {
return t.assignmentExpression("=", left, right);
};
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (file.isConsequenceExpressionStatement(node)) return;
var expr = node.expression;
if (!isAssignment(expr)) return;
var nodes = [];
var exploded = explode(expr.left, nodes, file, scope, true);
nodes.push(t.expressionStatement(buildAssignment(exploded.ref, opts.build(exploded.uid, expr.right))));
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!isAssignment(node)) return;
var nodes = [];
var exploded = explode(node.left, nodes, file, scope);
nodes.push(buildAssignment(exploded.ref, opts.build(exploded.uid, node.right)));
return nodes;
};
exports.BinaryExpression = function (node) {
if (node.operator !== opts.operator) return;
return opts.build(node.left, node.right);
};
};

View File

@ -0,0 +1,25 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
module.exports = build;
var t = _interopRequireWildcard(require("../../types"));
function build(node, buildBody) {
var self = node.blocks.shift();
if (!self) return;
var child = build(node, buildBody);
if (!child) {
// last item
child = buildBody();
// add a filter as this is our final stop
if (node.filter) {
child = t.ifStatement(node.filter, t.blockStatement([child]));
}
}
return t.forOfStatement(t.variableDeclaration("let", [t.variableDeclarator(self.left)]), self.right, t.blockStatement([child]));
}

View File

@ -0,0 +1,45 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var explode = _interopRequire(require("./explode-assignable-expression"));
var t = _interopRequireWildcard(require("../../types"));
module.exports = function (exports, opts) {
var buildAssignment = function buildAssignment(left, right) {
return t.assignmentExpression("=", left, right);
};
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (file.isConsequenceExpressionStatement(node)) return;
var expr = node.expression;
if (!opts.is(expr, file)) return;
var nodes = [];
var exploded = explode(expr.left, nodes, file, scope);
nodes.push(t.ifStatement(opts.build(exploded.uid, file), t.expressionStatement(buildAssignment(exploded.ref, expr.right))));
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!opts.is(node, file)) return;
var nodes = [];
var exploded = explode(node.left, nodes, file, scope);
nodes.push(t.logicalExpression("&&", opts.build(exploded.uid, file), buildAssignment(exploded.ref, node.right)));
// todo: duplicate expression node
nodes.push(exploded.ref);
return nodes;
};
};

View File

@ -0,0 +1,216 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
// https://github.com/RReverser/jsx-transpiler
// jsx
var isString = _interopRequire(require("lodash/lang/isString"));
var messages = _interopRequireWildcard(require("../../messages"));
var esutils = _interopRequire(require("esutils"));
var react = _interopRequireWildcard(require("./react"));
var t = _interopRequireWildcard(require("../../types"));
module.exports = function (exports, opts) {
exports.check = function (node) {
if (t.isJSX(node)) return true;
if (react.isCreateClass(node)) return true;
return false;
};
exports.JSXIdentifier = function (node, parent) {
if (node.name === "this" && t.isReferenced(node, parent)) {
return t.thisExpression();
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
node.type = "Identifier";
} else {
return t.literal(node.name);
}
};
exports.JSXNamespacedName = function (node, parent, scope, file) {
throw this.errorWithNode(messages.get("JSXNamespacedTags"));
};
exports.JSXMemberExpression = {
exit: function exit(node) {
node.computed = t.isLiteral(node.property);
node.type = "MemberExpression";
}
};
exports.JSXExpressionContainer = function (node) {
return node.expression;
};
exports.JSXAttribute = {
enter: function enter(node) {
var value = node.value;
if (t.isLiteral(value) && isString(value.value)) {
value.value = value.value.replace(/\n\s+/g, " ");
}
},
exit: function exit(node) {
var value = node.value || t.literal(true);
return t.inherits(t.property("init", node.name, value), node);
}
};
exports.JSXOpeningElement = {
exit: function exit(node, parent, scope, file) {
parent.children = react.buildChildren(parent);
var tagExpr = node.name;
var args = [];
var tagName;
if (t.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t.isLiteral(tagExpr)) {
tagName = tagExpr.value;
}
var state = {
tagExpr: tagExpr,
tagName: tagName,
args: args
};
if (opts.pre) {
opts.pre(state, file);
}
var attribs = node.attributes;
if (attribs.length) {
attribs = buildJSXOpeningElementAttributes(attribs, file);
} else {
attribs = t.literal(null);
}
args.push(attribs);
if (opts.post) {
opts.post(state, file);
}
return state.call || t.callExpression(state.callee, args);
}
};
/**
* The logic for this is quite terse. It's because we need to
* support spread elements. We loop over all attributes,
* breaking on spreads, we then push a new object containg
* all prior attributes to an array for later processing.
*/
var buildJSXOpeningElementAttributes = function buildJSXOpeningElementAttributes(attribs, file) {
var _props = [];
var objs = [];
var pushProps = function pushProps() {
if (!_props.length) return;
objs.push(t.objectExpression(_props));
_props = [];
};
while (attribs.length) {
var prop = attribs.shift();
if (t.isJSXSpreadAttribute(prop)) {
pushProps();
objs.push(prop.argument);
} else {
_props.push(prop);
}
}
pushProps();
if (objs.length === 1) {
// only one object
attribs = objs[0];
} else {
// looks like we have multiple objects
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
// spread it
attribs = t.callExpression(file.addHelper("extends"), objs);
}
return attribs;
};
exports.JSXElement = {
exit: function exit(node) {
var callExpr = node.openingElement;
callExpr.arguments = callExpr.arguments.concat(node.children);
if (callExpr.arguments.length >= 3) {
callExpr._prettyCall = true;
}
return t.inherits(callExpr, node);
}
};
// display names
var addDisplayName = function addDisplayName(id, call) {
var props = call.arguments[0].properties;
var safe = true;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
if (t.isIdentifier(prop.key, { name: "displayName" })) {
safe = false;
break;
}
}
if (safe) {
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
}
};
exports.ExportDefaultDeclaration = function (node, parent, scope, file) {
if (react.isCreateClass(node.declaration)) {
addDisplayName(file.opts.basename, node.declaration);
}
};
exports.AssignmentExpression = exports.Property = exports.VariableDeclarator = function (node) {
var left, right;
if (t.isAssignmentExpression(node)) {
left = node.left;
right = node.right;
} else if (t.isProperty(node)) {
left = node.key;
right = node.value;
} else if (t.isVariableDeclarator(node)) {
left = node.id;
right = node.init;
}
if (t.isMemberExpression(left)) {
left = left.property;
}
if (t.isIdentifier(left) && react.isCreateClass(right)) {
addDisplayName(left.name, right);
}
};
};

View File

@ -0,0 +1,41 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
var traverse = _interopRequire(require("../../traversal"));
var t = _interopRequireWildcard(require("../../types"));
var visitor = {
enter: function enter(node, parent, scope, state) {
if (this.isThisExpression() || this.isReferencedIdentifier({ name: "arguments" })) {
state.found = true;
this.stop();
}
if (this.isFunction()) {
this.skip();
}
}
};
module.exports = function (node, scope) {
var container = t.functionExpression(null, [], node.body, node.generator, node.async);
var callee = container;
var args = [];
var state = { found: false };
scope.traverse(node, visitor, state);
if (state.found) {
callee = t.memberExpression(container, t.identifier("apply"));
args = [t.thisExpression(), t.identifier("arguments")];
}
var call = t.callExpression(callee, args);
if (node.generator) call = t.yieldExpression(call, true);
return t.returnStatement(call);
};

View File

@ -0,0 +1,128 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.push = push;
exports.hasComputed = hasComputed;
exports.toComputedObjectFromClass = toComputedObjectFromClass;
exports.toClassObject = toClassObject;
exports.toDefineObject = toDefineObject;
exports.__esModule = true;
var cloneDeep = _interopRequire(require("lodash/lang/cloneDeep"));
var traverse = _interopRequire(require("../../traversal"));
var each = _interopRequire(require("lodash/collection/each"));
var has = _interopRequire(require("lodash/object/has"));
var t = _interopRequireWildcard(require("../../types"));
function push(mutatorMap, node, kind, file) {
var alias = t.toKeyAlias(node);
//
var map = {};
if (has(mutatorMap, alias)) map = mutatorMap[alias];
mutatorMap[alias] = map;
//
var _map = map;
if (!_map._inherits) _map._inherits = [];
map._inherits.push(node);
map._key = node.key;
if (node.computed) {
map._computed = true;
}
if (node.decorators) {
var _map2;
var decorators = (_map2 = map, !_map2.decorators && (_map2.decorators = t.arrayExpression([])), _map2.decorators);
decorators.elements = decorators.elements.concat(node.decorators.map(function (dec) {
return dec.expression;
}));
}
if (map.value || map.initializer) {
throw file.errorWithNode(node, "Key conflict with sibling node");
}
if (node.value) {
if (node.kind === "init") kind = "value";
if (node.kind === "get") kind = "get";
if (node.kind === "set") kind = "set";
t.inheritsComments(node.value, node);
map[kind] = node.value;
}
return map;
}
function hasComputed(mutatorMap) {
for (var key in mutatorMap) {
if (mutatorMap[key]._computed) {
return true;
}
}
return false;
}
function toComputedObjectFromClass(obj) {
var objExpr = t.arrayExpression([]);
for (var i = 0; i < obj.properties.length; i++) {
var prop = obj.properties[i];
var val = prop.value;
val.properties.unshift(t.property("init", t.identifier("key"), t.toComputedKey(prop)));
objExpr.elements.push(val);
}
return objExpr;
}
function toClassObject(mutatorMap) {
var objExpr = t.objectExpression([]);
each(mutatorMap, function (map) {
var mapNode = t.objectExpression([]);
var propNode = t.property("init", map._key, mapNode, map._computed);
each(map, function (node, key) {
if (key[0] === "_") return;
var inheritNode = node;
if (t.isMethodDefinition(node) || t.isClassProperty(node)) node = node.value;
var prop = t.property("init", t.identifier(key), node);
t.inheritsComments(prop, inheritNode);
t.removeComments(inheritNode);
mapNode.properties.push(prop);
});
objExpr.properties.push(propNode);
});
return objExpr;
}
function toDefineObject(mutatorMap) {
each(mutatorMap, function (map) {
if (map.value) map.writable = t.literal(true);
map.configurable = t.literal(true);
map.enumerable = t.literal(true);
});
return toClassObject(mutatorMap);
}

View File

@ -0,0 +1,71 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var t = _interopRequireWildcard(require("../../types"));
var getObjRef = function getObjRef(node, nodes, file, scope) {
var ref;
if (t.isIdentifier(node)) {
if (scope.hasBinding(node.name)) {
// this variable is declared in scope so we can be 100% sure
// that evaluating it multiple times wont trigger a getter
// or something else
return node;
} else {
// could possibly trigger a getter so we need to only evaluate
// it once
ref = node;
}
} else if (t.isMemberExpression(node)) {
ref = node.object;
if (t.isIdentifier(ref) && scope.hasGlobal(ref.name)) {
// the object reference that we need to save is locally declared
// so as per the previous comment we can be 100% sure evaluating
// it multiple times will be safe
return ref;
}
} else {
throw new Error("We can't explode this node type " + node.type);
}
var temp = scope.generateUidBasedOnNode(ref);
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, ref)]));
return temp;
};
var getPropRef = function getPropRef(node, nodes, file, scope) {
var prop = node.property;
var key = t.toComputedKey(node, prop);
if (t.isLiteral(key)) return key;
var temp = scope.generateUidBasedOnNode(prop);
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(temp, prop)]));
return temp;
};
module.exports = function (node, nodes, file, scope, allowedSingleIdent) {
var obj;
if (t.isIdentifier(node) && allowedSingleIdent) {
obj = node;
} else {
obj = getObjRef(node, nodes, file, scope);
}
var ref, uid;
if (t.isIdentifier(node)) {
ref = node;
uid = obj;
} else {
var prop = getPropRef(node, nodes, file, scope);
var computed = node.computed || t.isLiteral(prop);
uid = ref = t.memberExpression(obj, prop, computed);
}
return {
uid: uid,
ref: ref
};
};

View File

@ -0,0 +1,13 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var t = _interopRequireWildcard(require("../../types"));
module.exports = function (node) {
var lastNonDefault = 0;
for (var i = 0; i < node.params.length; i++) {
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
}
return lastNonDefault;
};

View File

@ -0,0 +1,31 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var t = _interopRequireWildcard(require("../../types"));
module.exports = function (decorators, scope) {
for (var i = 0; i < decorators.length; i++) {
var decorator = decorators[i];
var expression = decorator.expression;
if (!t.isMemberExpression(expression)) continue;
var temp = scope.generateMemoisedReference(expression.object);
var ref;
var nodes = [];
if (temp) {
ref = temp;
nodes.push(t.assignmentExpression("=", temp, expression.object));
} else {
ref = expression.object;
}
nodes.push(t.callExpression(t.memberExpression(t.memberExpression(ref, expression.property, expression.computed), t.identifier("bind")), [ref]));
decorator.expression = t.sequenceExpression(nodes);
}
return decorators;
};

View File

@ -0,0 +1,152 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.custom = custom;
exports.property = property;
exports.bare = bare;
exports.__esModule = true;
var getFunctionArity = _interopRequire(require("./get-function-arity"));
var util = _interopRequireWildcard(require("../../util"));
var t = _interopRequireWildcard(require("../../types"));
var visitor = {
enter: function enter(node, parent, scope, state) {
// check if this node is a referenced identifier that matches the same as our
// function id
if (!this.isReferencedIdentifier({ name: state.name })) return;
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.getBindingIdentifier(state.name);
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
this.stop();
}
};
var wrap = function wrap(state, method, id, scope) {
if (state.selfReference) {
var templateName = "property-method-assignment-wrapper";
if (method.generator) templateName += "-generator";
var template = util.template(templateName, {
FUNCTION: method,
FUNCTION_ID: id,
FUNCTION_KEY: scope.generateUidIdentifier(id.name)
});
template.callee._skipModulesRemap = true;
// shim in dummy params to retain function arity, if you try to read the
// source then you'll get the original since it's proxied so it's all good
var params = template.callee.body.body[0].params;
for (var i = 0, len = getFunctionArity(method); i < len; i++) {
params.push(scope.generateUidIdentifier("x"));
}
return template;
} else {
method.id = id;
return method;
}
};
var visit = function visit(node, name, scope) {
var state = {
selfAssignment: false,
selfReference: false,
outerDeclar: scope.getBindingIdentifier(name),
references: [],
name: name
};
// check to see if we have a local binding of the id we're setting inside of
// the function, this is important as there are caveats associated
var bindingInfo = scope.getOwnBindingInfo(name);
if (bindingInfo) {
if (bindingInfo.kind === "param") {
// safari will blow up in strict mode with code like:
//
// var t = function t(t) {};
//
// with the error:
//
// Cannot declare a parameter named 't' as it shadows the name of a
// strict mode function.
//
// this isn't to the spec and they've invented this behaviour which is
// **extremely** annoying so we avoid setting the name if it has a param
// with the same id
state.selfReference = true;
} else {}
} else {
scope.traverse(node, visitor, state);
}
return state;
};
function custom(node, id, scope) {
var state = visit(node, id.name, scope);
return wrap(state, node, id, scope);
}
function property(node, file, scope) {
var key = t.toComputedKey(node, node.key);
if (!t.isLiteral(key)) return node; // we can't set a function id with this
var name = t.toIdentifier(key.value);
if (name === "eval" || name === "arguments") name = "_" + name;
var id = t.identifier(name);
var method = node.value;
var state = visit(method, name, scope);
node.value = wrap(state, method, id, scope);
}
function bare(node, parent, scope) {
// has an `id` so we don't need to infer one
if (node.id) return node;
var id;
if (t.isProperty(parent) && parent.kind === "init" && (!parent.computed || t.isLiteral(parent.key))) {
// { foo() {} };
id = parent.key;
} else if (t.isVariableDeclarator(parent)) {
// var foo = function () {};
id = parent.id;
} else {
return node;
}
var name;
if (t.isLiteral(id)) {
name = id.value;
} else if (t.isIdentifier(id)) {
name = id.name;
} else {
return;
}
name = t.toIdentifier(name);
id = t.identifier(name);
var state = visit(node, name, scope);
return wrap(state, node, id, scope);
}
// otherwise it's defined somewhere in scope like:
//
// var t = function () {
// var t = 2;
// };
//
// so we can safely just set the id and move along as it shadows the
// bound function id

View File

@ -0,0 +1,110 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.isCreateClass = isCreateClass;
exports.isCompatTag = isCompatTag;
exports.buildChildren = buildChildren;
exports.__esModule = true;
var isString = _interopRequire(require("lodash/lang/isString"));
var t = _interopRequireWildcard(require("../../types"));
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
function isCreateClass(node) {
if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object
if (!isCreateClassCallExpression(node.callee)) return false;
// no call arguments
var args = node.arguments;
if (args.length !== 1) return false;
// first node arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return false;
return true;
}
var isReactComponent = t.buildMatchMemberExpression("React.Component");
exports.isReactComponent = isReactComponent;
function isCompatTag(tagName) {
return tagName && /^[a-z]|\-/.test(tagName);
}
function isStringLiteral(node) {
return t.isLiteral(node) && isString(node.value);
}
function cleanJSXElementLiteralChild(child, args) {
var lines = child.value.split(/\r\n|\n|\r/);
var lastNonEmptyLine = 0;
for (var i = 0; i < lines.length; i++) {
if (lines[i].match(/[^ \t]/)) {
lastNonEmptyLine = i;
}
}
var str = "";
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var isFirstLine = i === 0;
var isLastLine = i === lines.length - 1;
var isLastNonEmptyLine = i === lastNonEmptyLine;
// replace rendered whitespace tabs with spaces
var trimmedLine = line.replace(/\t/g, " ");
// trim whitespace touching a newline
if (!isFirstLine) {
trimmedLine = trimmedLine.replace(/^[ ]+/, "");
}
// trim whitespace touching an endline
if (!isLastLine) {
trimmedLine = trimmedLine.replace(/[ ]+$/, "");
}
if (trimmedLine) {
if (!isLastNonEmptyLine) {
trimmedLine += " ";
}
str += trimmedLine;
}
}
if (str) args.push(t.literal(str));
}
function buildChildren(node) {
var elems = [];
for (var i = 0; i < node.children.length; i++) {
var child = node.children[i];
if (t.isLiteral(child) && typeof child.value === "string") {
cleanJSXElementLiteralChild(child, elems);
continue;
}
if (t.isJSXExpressionContainer(child)) child = child.expression;
if (t.isJSXEmptyExpression(child)) continue;
elems.push(child);
}
return elems;
}

View File

@ -0,0 +1,24 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
exports.is = is;
exports.pullFlag = pullFlag;
exports.__esModule = true;
var pull = _interopRequire(require("lodash/array/pull"));
var t = _interopRequireWildcard(require("../../types"));
function is(node, flag) {
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf(flag) >= 0;
}
function pullFlag(node, flag) {
var flags = node.regex.flags.split("");
if (node.regex.flags.indexOf(flag) < 0) return;
pull(flags, flag);
node.regex.flags = flags.join("");
}

View File

@ -0,0 +1,62 @@
"use strict";
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var t = _interopRequireWildcard(require("../../types"));
var awaitVisitor = {
enter: function enter(node, parent, scope, state) {
if (t.isFunction(node)) this.skip();
if (t.isAwaitExpression(node)) {
node.type = "YieldExpression";
if (node.all) {
// await* foo; -> yield Promise.all(foo);
node.all = false;
node.argument = t.callExpression(t.memberExpression(t.identifier("Promise"), t.identifier("all")), [node.argument]);
}
}
}
};
var referenceVisitor = {
enter: function enter(node, parent, scope, state) {
var name = state.id.name;
if (t.isReferencedIdentifier(node, parent, { name: name }) && scope.bindingIdentifierEquals(name, state.id)) {
var _state;
return (_state = state, !_state.ref && (_state.ref = scope.generateUidIdentifier(name)), _state.ref);
}
}
};
module.exports = function (node, callId, scope) {
node.async = false;
node.generator = true;
scope.traverse(node, awaitVisitor, state);
var call = t.callExpression(callId, [node]);
var id = node.id;
node.id = null;
if (t.isFunctionDeclaration(node)) {
var declar = t.variableDeclaration("let", [t.variableDeclarator(id, call)]);
declar._blockHoist = true;
return declar;
} else {
if (id) {
var state = { id: id };
scope.traverse(node, referenceVisitor, state);
if (state.ref) {
scope.parent.push({ id: state.ref });
return t.assignmentExpression("=", state.ref, call);
}
}
return call;
}
};

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