diff --git a/.travis.yml b/.travis.yml index 05d8d58..c3b1e21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ +sudo: false language: ruby rvm: - - 1.9.3 - 2.0.0 - 2.1 - 2.2 diff --git a/README.md b/README.md index 98fd4b4..c7498a5 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ older stock runtimes like JSC on OSX and JScript on Windows may not. You should only count on ES3 features being available. Prefer feature checking these APIs rather than hard coding support for specific runtimes. -**Can I ExecJS be used to sandbox scripts?** +**Can ExecJS be used to sandbox scripts?** No, ExecJS shouldn't be used for any security related sandboxing. Since runtimes are automatically detected, each runtime has different sandboxing properties. diff --git a/lib/execjs/external_runtime.rb b/lib/execjs/external_runtime.rb index bd51eae..811dd69 100644 --- a/lib/execjs/external_runtime.rb +++ b/lib/execjs/external_runtime.rb @@ -24,12 +24,12 @@ module ExecJS def exec(source, options = {}) source = encode(source) - source = "#{@source}\n#{source}" if @source + source = "#{@source}\n#{source}" if @source != "" source = @runtime.compile_source(source) tmpfile = write_to_tempfile(source) begin - extract_result(@runtime.exec_runtime(tmpfile.path)) + extract_result(@runtime.exec_runtime(tmpfile.path), tmpfile.path) ensure File.unlink(tmpfile) end @@ -57,14 +57,25 @@ module ExecJS tmpfile end - def extract_result(output) - status, value = output.empty? ? [] : ::JSON.parse(output, create_additions: false) + def extract_result(output, filename) + status, value, stack = output.empty? ? [] : ::JSON.parse(output, create_additions: false) if status == "ok" value - elsif value =~ /SyntaxError:/ - raise RuntimeError, value else - raise ProgramError, value + stack ||= "" + real_filename = File.realpath(filename) + stack = stack.split("\n").map do |line| + line.sub(" at ", "") + .sub(real_filename, "(execjs)") + .sub(filename, "(execjs)") + .strip + end + stack.reject! { |line| ["eval code", "eval@[native code]"].include?(line) } + stack.shift unless stack[0].to_s.include?("(execjs)") + error_class = value =~ /SyntaxError:/ ? RuntimeError : ProgramError + error = error_class.new(value) + error.set_backtrace(stack + caller) + raise error end end end @@ -158,7 +169,7 @@ module ExecJS if $?.success? output else - raise RuntimeError, output + raise exec_runtime_error(output) end end @@ -181,7 +192,7 @@ module ExecJS if $?.success? output else - raise RuntimeError, output + raise exec_runtime_error(output) end end else @@ -193,13 +204,22 @@ module ExecJS if $?.success? output else - raise RuntimeError, output + raise exec_runtime_error(output) end end end # Internally exposed for Context. public :exec_runtime + def exec_runtime_error(output) + error = RuntimeError.new(output) + lines = output.split("\n") + lineno = lines[0][/:(\d+)$/, 1] if lines[0] + lineno ||= 1 + error.set_backtrace(["(execjs):#{lineno}"] + caller) + error + end + def which(command) Array(command).find do |name| name, args = name.split(/\s+/, 2) diff --git a/lib/execjs/ruby_racer_runtime.rb b/lib/execjs/ruby_racer_runtime.rb index d7c36b7..eee99fb 100644 --- a/lib/execjs/ruby_racer_runtime.rb +++ b/lib/execjs/ruby_racer_runtime.rb @@ -12,11 +12,7 @@ module ExecJS begin @v8_context.eval(source) rescue ::V8::JSError => e - if e.value["name"] == "SyntaxError" - raise RuntimeError, e.value.to_s - else - raise ProgramError, e.value.to_s - end + raise wrap_error(e) end end end @@ -37,11 +33,7 @@ module ExecJS begin unbox @v8_context.eval("(#{source})") rescue ::V8::JSError => e - if e.value["name"] == "SyntaxError" - raise RuntimeError, e.value.to_s - else - raise ProgramError, e.value.to_s - end + raise wrap_error(e) end end end @@ -52,11 +44,7 @@ module ExecJS begin unbox @v8_context.eval(properties).call(*args) rescue ::V8::JSError => e - if e.value["name"] == "SyntaxError" - raise RuntimeError, e.value.to_s - else - raise ProgramError, e.value.to_s - end + raise wrap_error(e) end end end @@ -96,6 +84,20 @@ module ExecJS result end end + + def wrap_error(e) + error_class = e.value["name"] == "SyntaxError" ? RuntimeError : ProgramError + + stack = e.value["stack"] || "" + stack = stack.split("\n") + stack.shift + stack = [e.message[/:\d+:\d+/, 0]].compact if stack.empty? + stack = stack.map { |line| line.sub(" at ", "").sub("", "(execjs)").strip } + + error = error_class.new(e.value.to_s) + error.set_backtrace(stack + caller) + error + end end def name diff --git a/lib/execjs/ruby_rhino_runtime.rb b/lib/execjs/ruby_rhino_runtime.rb index 5875bc1..13b7b3b 100644 --- a/lib/execjs/ruby_rhino_runtime.rb +++ b/lib/execjs/ruby_rhino_runtime.rb @@ -10,7 +10,7 @@ module ExecJS fix_memory_limit! @rhino_context @rhino_context.eval(source) rescue Exception => e - reraise_error(e) + raise wrap_error(e) end def exec(source, options = {}) @@ -28,13 +28,13 @@ module ExecJS unbox @rhino_context.eval("(#{source})") end rescue Exception => e - reraise_error(e) + raise wrap_error(e) end def call(properties, *args) unbox @rhino_context.eval(properties).call(*args) rescue Exception => e - reraise_error(e) + raise wrap_error(e) end def unbox(value) @@ -58,17 +58,18 @@ module ExecJS end end - def reraise_error(e) - case e - when ::Rhino::JSError - if e.message == "syntax error" - raise RuntimeError, e.message - else - raise ProgramError, e.message - end - else - raise e - end + def wrap_error(e) + return e unless e.is_a?(::Rhino::JSError) + + error_class = e.message == "syntax error" ? RuntimeError : ProgramError + + stack = e.backtrace + stack = stack.map { |line| line.sub(" at ", "").sub("", "(execjs)").strip } + stack.unshift("(execjs):1") if e.javascript_backtrace.empty? + + error = error_class.new(e.value.to_s) + error.set_backtrace(stack) + error end private diff --git a/lib/execjs/support/jsc_runner.js b/lib/execjs/support/jsc_runner.js index f7fbedb..c57a944 100644 --- a/lib/execjs/support/jsc_runner.js +++ b/lib/execjs/support/jsc_runner.js @@ -9,10 +9,10 @@ try { print(JSON.stringify(['ok', result])); } catch (err) { - print('["err"]'); + print(JSON.stringify(['err', '' + err, err.stack])); } } } catch (err) { - print(JSON.stringify(['err', '' + err])); + print(JSON.stringify(['err', '' + err, err.stack])); } }); diff --git a/lib/execjs/support/jscript_runner.js b/lib/execjs/support/jscript_runner.js index 4619e56..fc92b4a 100644 --- a/lib/execjs/support/jscript_runner.js +++ b/lib/execjs/support/jscript_runner.js @@ -13,10 +13,10 @@ try { print(JSON.stringify(['ok', result])); } catch (err) { - print('["err"]'); + print(JSON.stringify(['err', err.name + ': ' + err.message, err.stack])); } } } catch (err) { - print(JSON.stringify(['err', err.name + ': ' + err.message])); + print(JSON.stringify(['err', err.name + ': ' + err.message, err.stack])); } }); diff --git a/lib/execjs/support/node_runner.js b/lib/execjs/support/node_runner.js index 46210f9..ab0c6ec 100644 --- a/lib/execjs/support/node_runner.js +++ b/lib/execjs/support/node_runner.js @@ -11,10 +11,10 @@ try { print(JSON.stringify(['ok', result])); } catch (err) { - print('["err"]'); + print(JSON.stringify(['err', '' + err, err.stack])); } } } catch (err) { - print(JSON.stringify(['err', '' + err])); + print(JSON.stringify(['err', '' + err, err.stack])); } }); diff --git a/lib/execjs/support/spidermonkey_runner.js b/lib/execjs/support/spidermonkey_runner.js index f7fbedb..c57a944 100644 --- a/lib/execjs/support/spidermonkey_runner.js +++ b/lib/execjs/support/spidermonkey_runner.js @@ -9,10 +9,10 @@ try { print(JSON.stringify(['ok', result])); } catch (err) { - print('["err"]'); + print(JSON.stringify(['err', '' + err, err.stack])); } } } catch (err) { - print(JSON.stringify(['err', '' + err])); + print(JSON.stringify(['err', '' + err, err.stack])); } }); diff --git a/lib/execjs/version.rb b/lib/execjs/version.rb index 39020c8..a87567b 100644 --- a/lib/execjs/version.rb +++ b/lib/execjs/version.rb @@ -1,3 +1,3 @@ module ExecJS - VERSION = "2.3.0" + VERSION = "2.4.0" end diff --git a/test/fixtures/babel.js b/test/fixtures/babel.js new file mode 100644 index 0000000..add5feb --- /dev/null +++ b/test/fixtures/babel.js @@ -0,0 +1,43557 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.babel=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 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); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../../../package":338,"../transformation":41}],2:[function(require,module,exports){ +"use strict"; + +module.exports = Buffer; + +var repeating = require("repeating"); +var trimRight = require("trim-right"); +var isBoolean = require("lodash/lang/isBoolean"); +var includes = require("lodash/collection/includes"); +var isNumber = require("lodash/lang/isNumber"); + +function Buffer(position, format) { + this.position = position; + this._indent = format.indent.base; + this.format = format; + this.buf = ""; +} + +Buffer.prototype.get = function () { + return trimRight(this.buf); +}; + +Buffer.prototype.getIndent = function () { + if (this.format.compact || this.format.concise) { + return ""; + } else { + return repeating(this.format.indent.style, this._indent); + } +}; + +Buffer.prototype.indentSize = function () { + return this.getIndent().length; +}; + +Buffer.prototype.indent = function () { + this._indent++; +}; + +Buffer.prototype.dedent = function () { + this._indent--; +}; + +Buffer.prototype.semicolon = function () { + this.push(";"); +}; + +Buffer.prototype.ensureSemicolon = function () { + if (!this.isLast(";")) this.semicolon(); +}; + +Buffer.prototype.rightBrace = function () { + this.newline(true); + this.push("}"); +}; + +Buffer.prototype.keyword = function (name) { + this.push(name); + this.space(); +}; + +Buffer.prototype.space = function () { + if (this.format.compact) return; + if (this.buf && !this.isLast(" ") && !this.isLast("\n")) { + this.push(" "); + } +}; + +Buffer.prototype.removeLast = function (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 (i, removeLast) { + if (this.format.compact) return; + + if (this.format.concise) { + this.space(); + return; + } + + 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 (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 () { + 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 (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 (str) { + this.position.push(str); + this.buf += str; +}; + +Buffer.prototype.endsWith = function (str) { + return this.buf.slice(-str.length) === str; +}; + +Buffer.prototype.isLast = function (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; + } +}; + +},{"lodash/collection/includes":200,"lodash/lang/isBoolean":284,"lodash/lang/isNumber":288,"repeating":321,"trim-right":337}],3:[function(require,module,exports){ +"use strict"; + +exports.File = function (node, print) { + print(node.program); +}; + +exports.Program = function (node, print) { + print.sequence(node.body); +}; + +exports.BlockStatement = function (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(); + } +}; + +},{}],4:[function(require,module,exports){ +"use strict"; + +exports.ClassExpression = +exports.ClassDeclaration = function (node, print) { + this.push("class"); + + if (node.id) { + this.space(); + print(node.id); + } + + if (node.superClass) { + this.push(" extends "); + print(node.superClass); + } + + this.space(); + print(node.body); +}; + +exports.ClassBody = function (node, print) { + if (node.body.length === 0) { + this.push("{}"); + } else { + this.push("{"); + this.newline(); + + this.indent(); + print.sequence(node.body); + this.dedent(); + + this.rightBrace(); + } +}; + +exports.MethodDefinition = function (node, print) { + if (node.static) { + this.push("static "); + } + + this._method(node, print); +}; + +},{}],5:[function(require,module,exports){ +"use strict"; + +exports.ComprehensionBlock = function (node, print) { + this.keyword("for"); + this.push("("); + print(node.left); + this.push(" of "); + print(node.right); + this.push(")"); +}; + +exports.ComprehensionExpression = function (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 ? ")" : "]"); +}; + +},{}],6:[function(require,module,exports){ +"use strict"; + +var isInteger = require("is-integer"); +var isNumber = require("lodash/lang/isNumber"); +var t = require("../../types"); + +exports.UnaryExpression = function (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); +}; + +exports.UpdateExpression = function (node, print) { + if (node.prefix) { + this.push(node.operator); + print(node.argument); + } else { + print(node.argument); + this.push(node.operator); + } +}; + +exports.ConditionalExpression = function (node, print) { + print(node.test); + this.space(); + this.push("?"); + this.space(); + print(node.consequent); + this.space(); + this.push(":"); + this.space(); + print(node.alternate); +}; + +exports.NewExpression = function (node, print) { + this.push("new "); + print(node.callee); + this.push("("); + print.list(node.arguments); + this.push(")"); +}; + +exports.SequenceExpression = function (node, print) { + print.list(node.expressions); +}; + +exports.ThisExpression = function () { + this.push("this"); +}; + +exports.CallExpression = function (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 (keyword) { + return function (node, print) { + this.push(keyword); + + if (node.delegate || node.all) { + this.push("*"); + } + + if (node.argument) { + this.space(); + print(node.argument); + } + }; +}; + +exports.YieldExpression = buildYieldAwait("yield"); +exports.AwaitExpression = buildYieldAwait("await"); + +exports.EmptyStatement = function () { + this.semicolon(); +}; + +exports.ExpressionStatement = function (node, print) { + print(node.expression); + this.semicolon(); +}; + +exports.BinaryExpression = +exports.LogicalExpression = +exports.AssignmentPattern = +exports.AssignmentExpression = function (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); +}; + +var SCIENTIFIC_NOTATION = /e/i; + +exports.MemberExpression = function (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); + } +}; + +},{"../../types":119,"is-integer":184,"lodash/lang/isNumber":288}],7:[function(require,module,exports){ +"use strict"; + +exports.AnyTypeAnnotation = +exports.ArrayTypeAnnotation = +exports.BooleanTypeAnnotation = +exports.ClassProperty = +exports.DeclareClass = +exports.DeclareFunction = +exports.DeclareModule = +exports.DeclareVariable = +exports.FunctionTypeAnnotation = +exports.FunctionTypeParam = +exports.GenericTypeAnnotation = +exports.InterfaceExtends = +exports.InterfaceDeclaration = +exports.IntersectionTypeAnnotation = +exports.NullableTypeAnnotation = +exports.NumberTypeAnnotation = +exports.StringLiteralTypeAnnotation = +exports.StringTypeAnnotation = +exports.TupleTypeAnnotation = +exports.TypeofTypeAnnotation = +exports.TypeAlias = +exports.TypeAnnotation = +exports.TypeParameterDeclaration = +exports.TypeParameterInstantiation = +exports.ObjectTypeAnnotation = +exports.ObjectTypeCallProperty = +exports.ObjectTypeIndexer = +exports.ObjectTypeProperty = +exports.QualifiedTypeIdentifier = +exports.UnionTypeAnnotation = +exports.TypeCastExpression = +exports.VoidTypeAnnotation = function () { + // todo: implement these once we have a `--keep-types` option +}; + +},{}],8:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); +var each = require("lodash/collection/each"); + +exports.JSXAttribute = function (node, print) { + print(node.name); + if (node.value) { + this.push("="); + print(node.value); + } +}; + +exports.JSXIdentifier = function (node) { + this.push(node.name); +}; + +exports.JSXNamespacedName = function (node, print) { + print(node.namespace); + this.push(":"); + print(node.name); +}; + +exports.JSXMemberExpression = function (node, print) { + print(node.object); + this.push("."); + print(node.property); +}; + +exports.JSXSpreadAttribute = function (node, print) { + this.push("{..."); + print(node.argument); + this.push("}"); +}; + +exports.JSXExpressionContainer = function (node, print) { + this.push("{"); + print(node.expression); + this.push("}"); +}; + +exports.JSXElement = function (node, print) { + var self = this; + + var open = node.openingElement; + print(open); + if (open.selfClosing) return; + + this.indent(); + each(node.children, function (child) { + if (t.isLiteral(child)) { + self.push(child.value); + } else { + print(child); + } + }); + this.dedent(); + + print(node.closingElement); +}; + +exports.JSXOpeningElement = function (node, print) { + this.push("<"); + print(node.name); + if (node.attributes.length > 0) { + this.push(" "); + print.join(node.attributes, { separator: " " }); + } + this.push(node.selfClosing ? " />" : ">"); +}; + +exports.JSXClosingElement = function (node, print) { + this.push(""); +}; + +exports.JSXEmptyExpression = function () {}; + +},{"../../types":119,"lodash/collection/each":197}],9:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); + +exports._params = function (node, print) { + this.push("("); + print.list(node.params); + this.push(")"); +}; + +exports._method = function (node, print) { + var value = node.value; + var kind = node.kind; + var key = node.key; + + if (!kind || kind === "init") { + if (value.generator) { + this.push("*"); + } + } else { + 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); +}; + +exports.FunctionDeclaration = +exports.FunctionExpression = function (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.ArrowFunctionExpression = function (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(" => "); + print(node.body); +}; + +},{"../../types":119}],10:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); +var each = require("lodash/collection/each"); + +exports.ImportSpecifier = function (node, print) { + if (t.isSpecifierDefault(node)) { + print(t.getSpecifierName(node)); + } else { + return exports.ExportSpecifier.apply(this, arguments); + } +}; + +exports.ExportSpecifier = function (node, print) { + print(node.id); + if (node.name) { + this.push(" as "); + print(node.name); + } +}; + +exports.ExportBatchSpecifier = function () { + this.push("*"); +}; + +exports.ExportDeclaration = function (node, print) { + this.push("export "); + + var specifiers = node.specifiers; + + if (node.default) { + this.push("default "); + } + + if (node.declaration) { + print(node.declaration); + if (t.isStatement(node.declaration)) return; + } else { + if (specifiers.length === 1 && t.isExportBatchSpecifier(specifiers[0])) { + print(specifiers[0]); + } else { + 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(); +}; + +exports.ImportDeclaration = function (node, print) { + var self = this; + + this.push("import "); + + if (node.isType) { + this.push("type "); + } + + var specfiers = node.specifiers; + if (specfiers && specfiers.length) { + var foundImportSpecifier = false; + + each(node.specifiers, function (spec, i) { + if (+i > 0) { + self.push(", "); + } + + var isDefault = t.isSpecifierDefault(spec); + + if (!isDefault && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) { + foundImportSpecifier = true; + self.push("{ "); + } + + print(spec); + }); + + if (foundImportSpecifier) { + this.push(" }"); + } + + this.push(" from "); + } + + print(node.source); + this.semicolon(); +}; + +exports.ImportBatchSpecifier = function (node, print) { + this.push("* as "); + print(node.name); +}; + +},{"../../types":119,"lodash/collection/each":197}],11:[function(require,module,exports){ +"use strict"; + +var each = require("lodash/collection/each"); + +each(["BindMemberExpression", "BindFunctionExpression"], function (type) { + exports[type] = function () { + throw new ReferenceError("Trying to render non-standard playground node " + JSON.stringify(type)); + }; +}); + +},{"lodash/collection/each":197}],12:[function(require,module,exports){ +"use strict"; + +var repeating = require("repeating"); +var t = require("../../types"); + +exports.WithStatement = function (node, print) { + this.keyword("with"); + this.push("("); + print(node.object); + this.push(")"); + print.block(node.body); +}; + +exports.IfStatement = function (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); + } +}; + +exports.ForStatement = function (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); +}; + +exports.WhileStatement = function (node, print) { + this.keyword("while"); + this.push("("); + print(node.test); + this.push(")"); + print.block(node.body); +}; + +var buildForXStatement = function (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); + }; +}; + +exports.ForInStatement = buildForXStatement("in"); +exports.ForOfStatement = buildForXStatement("of"); + +exports.DoWhileStatement = function (node, print) { + this.keyword("do"); + print(node.body); + this.space(); + this.keyword("while"); + this.push("("); + print(node.test); + this.push(");"); +}; + +var buildLabelStatement = function (prefix, key) { + return function (node, print) { + this.push(prefix); + + var label = node[key || "label"]; + if (label) { + this.push(" "); + print(label); + } + + this.semicolon(); + }; +}; + +exports.ContinueStatement = buildLabelStatement("continue"); +exports.ReturnStatement = buildLabelStatement("return", "argument"); +exports.BreakStatement = buildLabelStatement("break"); + +exports.LabeledStatement = function (node, print) { + print(node.label); + this.push(": "); + print(node.body); +}; + +exports.TryStatement = function (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); + } +}; + +exports.CatchClause = function (node, print) { + this.keyword("catch"); + this.push("("); + print(node.param); + this.push(") "); + print(node.body); +}; + +exports.ThrowStatement = function (node, print) { + this.push("throw "); + print(node.argument); + this.semicolon(); +}; + +exports.SwitchStatement = function (node, print) { + this.keyword("switch"); + this.push("("); + print(node.discriminant); + this.push(")"); + this.space(); + this.push("{"); + + print.sequence(node.cases, { + indent: true, + addNewlines: function (leading, cas) { + if (!leading && node.cases[node.cases.length - 1] === cas) return -1; + } + }); + + this.push("}"); +}; + +exports.SwitchCase = function (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 }); + } +}; + +exports.DebuggerStatement = function () { + this.push("debugger;"); +}; + +exports.VariableDeclaration = function (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)) { + this.semicolon(); + } +}; + +exports.PrivateDeclaration = function (node, print) { + this.push("private "); + print.join(node.declarations, { separator: ", " }); + this.semicolon(); +}; + +exports.VariableDeclarator = function (node, print) { + if (node.init) { + print(node.id); + this.space(); + this.push("="); + this.space(); + print(node.init); + } else { + print(node.id); + } +}; + +},{"../../types":119,"repeating":321}],13:[function(require,module,exports){ +"use strict"; + +var each = require("lodash/collection/each"); + +exports.TaggedTemplateExpression = function (node, print) { + print(node.tag); + print(node.quasi); +}; + +exports.TemplateElement = function (node) { + this._push(node.value.raw); +}; + +exports.TemplateLiteral = function (node, print) { + this.push("`"); + + var quasis = node.quasis; + var self = this; + var len = quasis.length; + + each(quasis, function (quasi, i) { + print(quasi); + + if (i + 1 < len) { + self.push("${ "); + print(node.expressions[i]); + self.push(" }"); + } + }); + + this._push("`"); +}; + +},{"lodash/collection/each":197}],14:[function(require,module,exports){ +"use strict"; + +var each = require("lodash/collection/each"); + +exports.Identifier = function (node) { + this.push(node.name); +}; + +exports.RestElement = +exports.SpreadElement = +exports.SpreadProperty = function (node, print) { + this.push("..."); + print(node.argument); +}; + +exports.VirtualPropertyExpression = function (node, print) { + print(node.object); + this.push("::"); + print(node.property); +}; + +exports.ObjectExpression = +exports.ObjectPattern = function (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.Property = function (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); + } +}; + +exports.ArrayExpression = +exports.ArrayPattern = function (node, print) { + var elems = node.elements; + var self = this; + 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. + self.push(","); + } else { + if (i > 0) self.push(" "); + print(elem); + if (i < len - 1) self.push(","); + } + }); + + this.push("]"); +}; + +exports.Literal = function (node) { + var val = node.value; + var type = typeof val; + + if (type === "string") { + 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); + }); + + this.push(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"); + } +}; + +},{"lodash/collection/each":197}],15:[function(require,module,exports){ +"use strict"; + +module.exports = function (ast, opts, code) { + var gen = new CodeGenerator(ast, opts, code); + return gen.generate(); +}; + +module.exports.CodeGenerator = CodeGenerator; + +var detectIndent = require("detect-indent"); +var Whitespace = require("./whitespace"); +var repeating = require("repeating"); +var SourceMap = require("./source-map"); +var Position = require("./position"); +var messages = require("../messages"); +var Buffer = require("./buffer"); +var extend = require("lodash/object/extend"); +var each = require("lodash/collection/each"); +var n = require("./node"); +var t = require("../types"); + +function CodeGenerator(ast, opts, code) { + opts = opts || {}; + + this.comments = ast.comments || []; + this.tokens = ast.tokens || []; + this.format = CodeGenerator.normalizeOptions(code, opts); + 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); +} + +each(Buffer.prototype, function (fn, key) { + CodeGenerator.prototype[key] = function () { + return fn.apply(this.buffer, arguments); + }; +}); + +CodeGenerator.normalizeOptions = function (code, opts) { + 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, + 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.generators = { + templateLiterals: require("./generators/template-literals"), + comprehensions: require("./generators/comprehensions"), + expressions: require("./generators/expressions"), + statements: require("./generators/statements"), + playground: require("./generators/playground"), + 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") +}; + +each(CodeGenerator.generators, function (generator) { + extend(CodeGenerator.prototype, generator); +}); + +CodeGenerator.prototype.generate = function () { + 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 (parent) { + var self = this; + + var print = function (node, opts) { + return self.print(node, parent, opts); + }; + + print.sequence = function (nodes, opts) { + opts = opts || {}; + opts.statement = true; + return self.printJoin(print, nodes, opts); + }; + + print.join = function (nodes, opts) { + return self.printJoin(print, nodes, opts); + }; + + print.list = function (items, opts) { + opts = opts || {}; + opts.separator = opts.separator || ", "; + print.join(items, opts); + }; + + print.block = function (node) { + return self.printBlock(print, node); + }; + + print.indentOnComments = function (node) { + return self.printAndIndentOnComments(print, node); + }; + + return print; +}; + +CodeGenerator.prototype.print = function (node, parent, opts) { + if (!node) return ""; + + if (parent && parent._compact) { + node._compact = true; + } + + var oldConcise = this.format.concise; + if (node._compact) { + this.format.concise = true; + } + + var self = this; + + opts = opts || {}; + + 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 = self.whitespace.getNewlinesBefore(node); + } else { + lines = self.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 (!self.buffer.buf) lines = 0; + } + + self.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 (print, nodes, opts) { + if (!nodes || !nodes.length) return; + + opts = opts || {}; + + var self = this; + var len = nodes.length; + + if (opts.indent) self.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) { + self.push(opts.separator); + } + } + }); + }); + + if (opts.indent) self.dedent(); +}; + +CodeGenerator.prototype.printAndIndentOnComments = function (print, node) { + var indent = !!node.leadingComments; + if (indent) this.indent(); + print(node); + if (indent) this.dedent(); +}; + +CodeGenerator.prototype.printBlock = function (print, node) { + if (t.isEmptyStatement(node)) { + this.semicolon(); + } else { + this.push(" "); + print(node); + } +}; + +CodeGenerator.prototype.generateComment = function (comment) { + var val = comment.value; + if (comment.type === "Line") { + val = "//" + val; + } else { + val = "/*" + val + "*/"; + } + return val; +}; + +CodeGenerator.prototype.printTrailingComments = function (node, parent) { + this._printComments(this.getComments("trailingComments", node, parent)); +}; + +CodeGenerator.prototype.printLeadingComments = function (node, parent) { + this._printComments(this.getComments("leadingComments", node, parent)); +}; + +CodeGenerator.prototype.getComments = function (key, node, parent) { + if (t.isExpressionStatement(parent)) { + return []; + } + + var comments = []; + var nodes = [node]; + var self = this; + + if (t.isExpressionStatement(node)) { + nodes.push(node.argument); + } + + each(nodes, function (node) { + comments = comments.concat(self._getComments(key, node)); + }); + + return comments; +}; + +CodeGenerator.prototype._getComments = function (key, node) { + return (node && node[key]) || []; +}; + +CodeGenerator.prototype._printComments = function (comments) { + if (this.format.compact) return; + + if (!this.format.comments) return; + if (!comments || !comments.length) return; + + var self = this; + + each(comments, function (comment) { + var skip = false; + + // find the original comment in the ast and set it as displayed + each(self.ast.comments, function (origComment) { + if (origComment.start === comment.start) { + // comment has already been output + if (origComment._displayed) skip = true; + + origComment._displayed = true; + return false; + } + }); + + if (skip) return; + + // whitespace before + self.newline(self.whitespace.getNewlinesBefore(comment)); + + var column = self.position.column; + var val = self.generateComment(comment); + + if (column && !self.isLast(["\n", " ", "[", "{"])) { + self._push(" "); + column++; + } + + // + + if (comment.type === "Block" && self.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(self.indentSize(), column); + val = val.replace(/\n/g, "\n" + repeating(" ", indent)); + } + + if (column === 0) { + val = self.getIndent() + val; + } + + // + + self._push(val); + + // whitespace after + self.newline(self.whitespace.getNewlinesAfter(comment)); + }); +}; + +},{"../messages":27,"../types":119,"./buffer":2,"./generators/base":3,"./generators/classes":4,"./generators/comprehensions":5,"./generators/expressions":6,"./generators/flow":7,"./generators/jsx":8,"./generators/methods":9,"./generators/modules":10,"./generators/playground":11,"./generators/statements":12,"./generators/template-literals":13,"./generators/types":14,"./node":16,"./position":19,"./source-map":20,"./whitespace":21,"detect-indent":176,"lodash/collection/each":197,"lodash/object/extend":295,"repeating":321}],16:[function(require,module,exports){ +"use strict"; + +module.exports = Node; + +var whitespace = require("./whitespace"); +var parens = require("./parentheses"); +var each = require("lodash/collection/each"); +var some = require("lodash/collection/some"); +var t = require("../../types"); + +var find = function (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; +}; + +function Node(node, parent) { + this.parent = parent; + this.node = node; +} + +Node.isUserWhitespacable = function (node) { + return t.isUserWhitespacable(node); +}; + +Node.needsWhitespace = function (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 (node, parent) { + return Node.needsWhitespace(node, parent, "before"); +}; + +Node.needsWhitespaceAfter = function (node, parent) { + return Node.needsWhitespace(node, parent, "after"); +}; + +Node.needsParens = function (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 (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; +}; + +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); + }; +}); + +},{"../../types":119,"./parentheses":17,"./whitespace":18,"lodash/collection/each":197,"lodash/collection/some":203}],17:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); +var each = require("lodash/collection/each"); + +var PRECEDENCE = {}; + +each([ + ["||"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"], + ["**"] +], function (tier, i) { + each(tier, function (op) { + PRECEDENCE[op] = i; + }); +}); + +exports.UpdateExpression = function (node, parent) { + if (t.isMemberExpression(parent) && parent.object === node) { + // (foo++).test() + return true; + } +}; + +exports.ObjectExpression = function (node, parent) { + if (t.isExpressionStatement(parent)) { + // ({ foo: "bar" }); + return true; + } + + if (t.isMemberExpression(parent) && parent.object === node) { + // ({ foo: "bar" }).foo + return true; + } + + return false; +}; + +exports.Binary = function (node, parent) { + if ((t.isCallExpression(parent) || 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; + } + } +}; + +exports.BinaryExpression = function (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; + } + } +}; + +exports.SequenceExpression = function (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; +}; + +exports.YieldExpression = function (node, parent) { + return t.isBinary(parent) || + t.isUnaryLike(parent) || + t.isCallExpression(parent) || + t.isMemberExpression(parent) || + t.isNewExpression(parent) || + t.isConditionalExpression(parent) || + t.isYieldExpression(parent); +}; + +exports.ClassExpression = function (node, parent) { + return t.isExpressionStatement(parent); +}; + +exports.UnaryLike = function (node, parent) { + return t.isMemberExpression(parent) && parent.object === node; +}; + +exports.FunctionExpression = function (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; + } +}; + +exports.AssignmentExpression = +exports.ConditionalExpression = function (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; +}; + +},{"../../types":119,"lodash/collection/each":197}],18:[function(require,module,exports){ +"use strict"; + +var isBoolean = require("lodash/lang/isBoolean"); +var each = require("lodash/collection/each"); +var map = require("lodash/collection/map"); +var t = require("../../types"); + +var crawl = function (node, state) { + state = state || {}; + + 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)) { + state.hasHelper = state.hasHelper || isHelper(node.callee); + } + + return state; +}; + +var isHelper = function (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; + } +}; + +var isType = function (node) { + return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) || + t.isIdentifier(node) || t.isMemberExpression(node); +}; + +exports.nodes = { + AssignmentExpression: function (node) { + var state = crawl(node.right); + if ((state.hasCall && state.hasHelper) || state.hasFunction) { + return { + before: state.hasFunction, + after: true + }; + } + }, + + SwitchCase: function (node, parent) { + return { + before: node.consequent.length || parent.cases[0] === node + }; + }, + + LogicalExpression: function (node) { + if (t.isFunction(node.left) || t.isFunction(node.right)) { + return { + after: true + }; + } + }, + + Literal: function (node) { + if (node.value === "use strict") { + return { + after: true + }; + } + }, + + CallExpression: function (node) { + if (t.isFunction(node.callee) || isHelper(node)) { + return { + before: true, + after: true + }; + } + }, + + VariableDeclaration: function (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 (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 (node) { + return map(node.declarations, "init"); + }, + + ArrayExpression: function (node) { + return node.elements; + }, + + ObjectExpression: function (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; + }; + }); +}); + +},{"../../types":119,"lodash/collection/each":197,"lodash/collection/map":201,"lodash/lang/isBoolean":284}],19:[function(require,module,exports){ +"use strict"; + +module.exports = Position; + +function Position() { + this.line = 1; + this.column = 0; +} + +Position.prototype.push = function (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 (str) { + for (var i = 0; i < str.length; i++) { + if (str[i] === "\n") { + this.line--; + } else { + this.column--; + } + } +}; + +},{}],20:[function(require,module,exports){ +"use strict"; + +module.exports = SourceMap; + +var sourceMap = require("source-map"); +var t = require("../types"); + +function SourceMap(position, opts, code) { + this.position = position; + this.opts = opts; + + if (opts.sourceMap) { + 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 () { + var map = this.map; + if (map) { + return map.toJSON(); + } else { + return map; + } +}; + +SourceMap.prototype.mark = function (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 + }); +}; + +},{"../types":119,"source-map":326}],21:[function(require,module,exports){ +"use strict"; + +module.exports = Whitespace; + +var sortBy = 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; +} + +function Whitespace(tokens, comments) { + 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 (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 (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.type === "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 (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; +}; + +},{"lodash/collection/sortBy":204}],22:[function(require,module,exports){ +var lineNumbers = require("line-numbers"); +var repeating = require("repeating"); +var jsTokens = require("js-tokens"); +var esutils = require("esutils"); +var chalk = require("chalk"); +var ary = require("lodash/function/ary"); + +var defs = { + string: chalk.red, + punctuation: chalk.white.bold, + operator: chalk.white.bold, + curly: chalk.green, + parens: chalk.blue.bold, + square: chalk.yellow, + name: chalk.white, + keyword: chalk.cyan, + number: chalk.magenta, + regex: chalk.magenta, + comment: chalk.grey, + invalid: chalk.inverse +}; + +var newline = /\r\n|[\n\r\u2028\u2029]/; + +var highlight = function (text) { + var tokenType = function (match) { + var token = jsTokens.matchToToken(match); + if (token.type === "name" && esutils.keyword.isKeywordES6(token.value)) { + return "keyword"; + } + + if (token.type === "punctuation") { + switch (token.value) { + case "{": + case "}": + return "curly"; + case "(": + case ")": + return "parens"; + case "[": + case "]": + return "square"; + } + } + + return token.type; + }; + + return text.replace(jsTokens, function (match) { + var type = tokenType(arguments); + if (type in defs) { + var colorize = ary(defs[type], 1); + return match.split(newline).map(colorize).join("\n"); + } + return match; + }); +}; + +module.exports = function (lines, lineNumber, colNumber) { + colNumber = Math.max(colNumber, 0); + + if (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 "\n" + lineNumbers(lines.slice(start, end), { + start: start + 1, + before: " ", + after: " | ", + transform: function (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"); +}; + +},{"chalk":164,"esutils":181,"js-tokens":187,"line-numbers":189,"lodash/function/ary":206,"repeating":321}],23:[function(require,module,exports){ +var t = 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?"); + } +}; + +},{"../types":119}],24:[function(require,module,exports){ +"use strict"; + +module.exports = function () { + return Object.create(null); +}; + +},{}],25:[function(require,module,exports){ +var normalizeAst = require("./normalize-ast"); +var estraverse = require("estraverse"); +var codeFrame = require("./code-frame"); +var acorn = require("acorn-babel"); + +module.exports = function (opts, code, callback) { + try { + var comments = []; + var tokens = []; + + var ast = acorn.parse(code, { + allowImportExportEverywhere: opts.allowImportExportEverywhere, + allowReturnOutsideFunction: !opts._anal, + ecmaVersion: opts.experimental ? 7 : 6, + playground: opts.playground, + strictMode: opts.strictMode, + onComment: comments, + locations: true, + onToken: tokens, + ranges: true + }); + + 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 = opts.filename + ": " + err.message; + + var loc = err.loc; + if (loc) { + var frame = codeFrame(code, loc.line, loc.column + 1); + message += frame; + } + + if (err.stack) err.stack = err.stack.replace(err.message, message); + err.message = message; + } + + throw err; + } +}; + +},{"./code-frame":22,"./normalize-ast":23,"acorn-babel":122,"estraverse":177}],26:[function(require,module,exports){ +"use strict"; + +/** + * A trick from Bluebird to force V8 to use fast properties for an object. + * Read more: http://stackoverflow.com/questions/24987896/ + * + * Use %HasFastProperties(obj) and --allow-natives-syntax to check whether + * a particular object already has fast properties. + */ + +module.exports = function toFastProperties(obj) { + /*jshint -W027*/ + function f() {} + f.prototype = obj; + return f; + eval(obj); +}; + +},{}],27:[function(require,module,exports){ +var util = require("util"); + +exports.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", + 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." +}; + +exports.get = function (key) { + var msg = exports.messages[key]; + if (!msg) throw new ReferenceError("Unknown message `" + key + "`"); + + var args = []; + for (var i = 1; i < arguments.length; i++) { + args.push(arguments[i]); + } + args = exports.parseArgs(args); + + return msg.replace(/\$(\d+)/g, function (str, i) { + return args[--i]; + }); +}; + +exports.parseArgs = function (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); + } + } + }); +}; + +},{"util":163}],28:[function(require,module,exports){ +"use strict"; + +var extend = require("lodash/object/extend"); +var t = require("./types"); + +// estraverse + +var estraverse = require("estraverse"); +extend(estraverse.VisitorKeys, t.VISITOR_KEYS); + +// regenerator-babel/ast-types + +var types = require("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")); + +// Acorn - Same as ImportNamespaceSpecifier but `id` is `name` +def("ImportBatchSpecifier") + .bases("Specifier") + .build("name") + .field("name", def("Identifier")); + +def("RestElement") + .bases("Pattern") + .build("argument") + .field("argument", def("expression")); + +// Abstract references +def("VirtualPropertyExpression") + .bases("Expression") + .build("object", "property") + .field("object", def("Expression")) + .field("property", or(def("Identifier"), def("Expression"))); + +def("PrivateDeclaration") + .bases("Declaration") + .build("declarations") + .field("declarations", [def("Identifier")]); + +// Playground +def("BindMemberExpression") + .bases("Expression") + .build("object", "property", "arguments") + .field("object", def("Expression")) + .field("property", or(def("Identifier"), def("Expression"))) + .field("arguments", [def("Expression")]); + +def("BindFunctionExpression") + .bases("Expression") + .build("callee", "arguments") + .field("callee", def("Expression")) + .field("arguments", [def("Expression")]); + +types.finalize(); + +},{"./types":119,"ast-types":136,"estraverse":177,"lodash/object/extend":295}],29:[function(require,module,exports){ +"use strict"; + +module.exports = File; + +var sourceMapToComment = require("source-map-to-comment"); +var shebangRegex = require("shebang-regex"); +var isFunction = require("lodash/lang/isFunction"); +var transform = require("./index"); +var generate = require("../generation"); +var defaults = require("lodash/object/defaults"); +var includes = require("lodash/collection/includes"); +var assign = require("lodash/object/assign"); +var parse = require("../helpers/parse"); +var Scope = require("../traversal/scope"); +var slash = require("slash"); +var util = require("../util"); +var path = require("path"); +var each = require("lodash/collection/each"); +var t = require("../types"); + +function File(opts) { + this.dynamicImportedNoDefault = []; + this.dynamicImportIds = {}; + this.dynamicImported = []; + this.dynamicImports = []; + + this.dynamicData = {}; + this.data = {}; + + this.lastStatements = []; + this.opts = this.normalizeOptions(opts); + this.ast = {}; + + this.buildTransformers(); +} + +File.helpers = [ + "inherits", + "defaults", + "prototype-properties", + "apply-constructor", + "tagged-template-literal", + "tagged-template-literal-loose", + "interop-require", + "to-array", + "to-consumable-array", + "sliced-to-array", + "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" +]; + +File.validOptions = [ + "filename", + "filenameRelative", + "blacklist", + "whitelist", + "loose", + "optional", + "modules", + "sourceMap", + "sourceMapName", + "sourceFileName", + "sourceRoot", + "moduleRoot", + "moduleIds", + "comments", + "reactCompat", + "keepModuleIdExtensions", + "code", + "ast", + "playground", + "experimental", + "externalHelpers", + "auxiliaryComment", + "compact", + + "resolveModuleSource", + "moduleId", + + // legacy + "format", + + // these are used by plugins + "ignore", + "only", + "extensions", + "accept" +]; + +File.prototype.normalizeOptions = function (opts) { + opts = assign({}, opts); + + for (var key in opts) { + if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) { + throw new ReferenceError("Unknown option: " + key); + } + } + + defaults(opts, { + keepModuleIdExtensions: false, + resolveModuleSource: null, + externalHelpers: false, + auxilaryComment: "", + experimental: false, + reactCompat: false, + playground: false, + moduleIds: false, + blacklist: [], + whitelist: [], + sourceMap: false, + optional: [], + comments: true, + filename: "unknown", + modules: "common", + compact: "auto", + loose: [], + code: true, + ast: 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.blacklist = util.arrayify(opts.blacklist); + opts.whitelist = util.arrayify(opts.whitelist); + opts.optional = util.arrayify(opts.optional); + opts.compact = util.booleanify(opts.compact); + opts.loose = util.arrayify(opts.loose); + + if (includes(opts.loose, "all") || includes(opts.loose, true)) { + opts.loose = Object.keys(transform.transformers); + } + + 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.playground) { + opts.experimental = true; + } + + if (opts.externalHelpers) { + this.set("helpersNamespace", t.identifier("babelHelpers")); + } + + opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist); + opts.whitelist = transform._ensureTransformerNames("whitelist", opts.whitelist); + opts.optional = transform._ensureTransformerNames("optional", opts.optional); + opts.loose = transform._ensureTransformerNames("loose", opts.loose); + + if (opts.reactCompat) { + opts.optional.push("reactCompat"); + console.error("The reactCompat option has been moved into the optional transformer `reactCompat`"); + } + + var ensureEnabled = function (key) { + var namespace = transform.transformerNamespaces[key]; + if (namespace === "es7") opts.experimental = true; + if (namespace === "playground") opts.playground = true; + }; + + each(opts.whitelist, ensureEnabled); + each(opts.optional, ensureEnabled); + + return opts; +}; + +File.prototype.isLoose = function (key) { + return includes(this.opts.loose, key); +}; + +File.prototype.buildTransformers = function () { + var file = this; + + var transformers = {}; + + var secondaryStack = []; + var stack = []; + + each(transform.transformers, function (transformer, key) { + var pass = transformers[key] = transformer.buildPass(file); + + if (pass.canRun(file)) { + stack.push(pass); + + if (transformer.secondPass) { + secondaryStack.push(pass); + } + + if (transformer.manipulateOptions) { + transformer.manipulateOptions(file.opts, file); + } + } + }); + + this.transformerStack = stack.concat(secondaryStack); + this.transformers = transformers; +}; + +File.prototype.debug = function (msg) { + var parts = this.opts.filename; + if (msg) parts += ": " + msg; + util.debug(parts); +}; + +File.prototype.getModuleFormatter = function (type) { + var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type]; + + if (!ModuleFormatter) { + var loc = util.resolve(type); + if (loc) ModuleFormatter = require(loc); + } + + if (!ModuleFormatter) { + throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type)); + } + + return new ModuleFormatter(this); +}; + +File.prototype.parseShebang = function (code) { + var shebangMatch = shebangRegex.exec(code); + + if (shebangMatch) { + this.shebang = shebangMatch[0]; + + // remove shebang + code = code.replace(shebangRegex, ""); + } + + return code; +}; + +File.prototype.set = function (key, val) { + return this.data[key] = val; +}; + +File.prototype.setDynamic = function (key, fn) { + this.dynamicData[key] = fn; +}; + +File.prototype.get = function (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.addImport = function (source, name, noDefault) { + name = name || source; + var id = this.dynamicImportIds[name]; + + if (!id) { + id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name); + + var specifiers = [t.importSpecifier(t.identifier("default"), id)]; + var declar = t.importDeclaration(specifiers, t.literal(source)); + declar._blockHoist = 3; + + this.dynamicImported.push(declar); + if (noDefault) this.dynamicImportedNoDefault.push(declar); + + this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports); + } + + return id; +}; + +File.prototype.isConsequenceExpressionStatement = function (node) { + return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0; +}; + +File.prototype.attachAuxiliaryComment = function (node) { + var comment = this.opts.auxiliaryComment; + if (comment) { + node.leadingComments = node.leadingComments || []; + node.leadingComments.push({ + type: "Line", + value: " " + comment + }); + } + return node; +}; + +File.prototype.addHelper = function (name) { + if (!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; + + var runtime = this.get("helpersNamespace"); + if (runtime) { + name = t.identifier(t.toIdentifier(name)); + return t.memberExpression(runtime, name); + } else { + var ref = util.template(name); + ref._compact = true; + var uid = this.scope.generateUidIdentifier(name); + this.scope.push({ + key: name, + id: uid, + init: ref + }); + return uid; + } +}; + +File.prototype.logDeopt = function () { + // todo, (node, msg) +}; + +File.prototype.errorWithNode = function (node, msg, Error) { + Error = Error || SyntaxError; + + var loc = node.loc.start; + var err = new Error("Line " + loc.line + ": " + msg); + err.loc = loc; + return err; +}; + +File.prototype.addCode = function (code) { + code = (code || "") + ""; + this.code = code; + return this.parseShebang(code); +}; + +File.prototype.parse = function (code) { + var self = this; + + code = this.addCode(code); + + var opts = this.opts; + + opts.allowImportExportEverywhere = this.isLoose("es6.modules"); + opts.strictMode = this.transformers.useStrict.canRun(); + + return parse(opts, code, function (tree) { + self.transform(tree); + return self.generate(); + }); +}; + +File.prototype.transform = function (ast) { + this.debug(); + + this.ast = ast; + this.lastStatements = t.getLastStatements(ast.program); + this.scope = new Scope(ast.program, ast, null, this); + + var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules); + if (modFormatter.init && this.transformers["es6.modules"].canRun()) { + modFormatter.init(); + } + + this.checkNode(ast); + + this.call("pre"); + + each(this.transformerStack, function (pass) { + pass.transform(); + }); + + this.call("post"); +}; + +File.prototype.call = function (key) { + var stack = this.transformerStack; + for (var i = 0; i < stack.length; i++) { + var transformer = stack[i].transformer; + if (transformer[key]) { + transformer[key](this); + } + } +}; + +var checkTransformerVisitor = { + enter: function (node, parent, scope, state) { + checkNode(state.stack, node, scope); + } +}; + +var checkNode = function (stack, node, scope) { + each(stack, function (pass) { + if (pass.shouldRun) return; + pass.checkNode(node, scope); + }); +}; + +File.prototype.checkNode = function (node, scope) { + var stack = this.transformerStack; + scope = scope || this.scope; + + checkNode(stack, node, scope); + + scope.traverse(node, checkTransformerVisitor, { + stack: stack + }); +}; + +File.prototype.generate = function () { + var opts = this.opts; + var ast = this.ast; + + var result = { + code: "", + map: null, + ast: null + }; + + 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 (opts.sourceMap === "inline") { + result.code += "\n" + sourceMapToComment(result.map); + result.map = null; + } + + return result; +}; + +},{"../generation":15,"../helpers/parse":25,"../traversal/scope":116,"../types":119,"../util":121,"./index":41,"lodash/collection/each":197,"lodash/collection/includes":200,"lodash/lang/isFunction":286,"lodash/object/assign":293,"lodash/object/defaults":294,"path":146,"shebang-regex":323,"slash":324,"source-map-to-comment":325}],30:[function(require,module,exports){ +"use strict"; + +var explode = require("./explode-assignable-expression"); +var t = require("../../types"); + +module.exports = function (exports, opts) { + var isAssignment = function (node) { + return node.operator === opts.operator + "="; + }; + + var buildAssignment = function (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 t.toSequenceExpression(nodes, scope); + }; + + exports.BinaryExpression = function (node) { + if (node.operator !== opts.operator) return; + return opts.build(node.left, node.right); + }; +}; + +},{"../../types":119,"./explode-assignable-expression":35}],31:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); + +module.exports = 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]) + ); +}; + +},{"../../types":119}],32:[function(require,module,exports){ +"use strict"; + +var explode = require("./explode-assignable-expression"); +var t = require("../../types"); + +module.exports = function (exports, opts) { + var buildAssignment = function (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 t.toSequenceExpression(nodes, scope); + }; +}; + +},{"../../types":119,"./explode-assignable-expression":35}],33:[function(require,module,exports){ +"use strict"; + +// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser) +// https://github.com/RReverser/jsx-transpiler + +// jsx + +var isString = require("lodash/lang/isString"); +var messages = require("../../messages"); +var esutils = require("esutils"); +var react = require("./react"); +var t = 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.isIdentifierName(node.name)) { + node.type = "Identifier"; + } else { + return t.literal(node.name); + } + }; + + exports.JSXNamespacedName = function (node, parent, scope, file) { + throw file.errorWithNode(node, messages.get("JSXNamespacedTags")); + }; + + exports.JSXMemberExpression = { + exit: function (node) { + node.computed = t.isLiteral(node.property); + node.type = "MemberExpression"; + } + }; + + exports.JSXExpressionContainer = function (node) { + return node.expression; + }; + + exports.JSXAttribute = { + enter: function (node) { + var value = node.value; + if (t.isLiteral(value) && isString(value.value)) { + value.value = value.value.replace(/\n\s+/g, " "); + } + }, + + exit: function (node) { + var value = node.value || t.literal(true); + return t.inherits(t.property("init", node.name, value), node); + } + }; + + exports.JSXOpeningElement = { + exit: function (node, parent, scope, file) { + 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 (attribs, file) { + var _props = []; + var objs = []; + + var pushProps = function () { + 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 (node) { + var callExpr = node.openingElement; + + for (var i = 0; i < node.children.length; i++) { + var child = node.children[i]; + + if (t.isLiteral(child) && typeof child.value === "string") { + cleanJSXElementLiteralChild(child, callExpr.arguments); + continue; + } else if (t.isJSXEmptyExpression(child)) { + continue; + } + + callExpr.arguments.push(child); + } + + callExpr.arguments = flatten(callExpr.arguments); + + if (callExpr.arguments.length >= 3) { + callExpr._prettyCall = true; + } + + return t.inherits(callExpr, node); + } + }; + + var isStringLiteral = function (node) { + return t.isLiteral(node) && isString(node.value); + }; + + var flatten = function (args) { + var flattened = []; + var last; + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + if (isStringLiteral(arg) && isStringLiteral(last)) { + last.value += arg.value; + } else { + last = arg; + flattened.push(arg); + } + } + + return flattened; + }; + + var cleanJSXElementLiteralChild = function (child, args) { + var lines = child.value.split(/\r\n|\n|\r/); + + var lastNonEmptyLine = 0; + var i; + + for (i = 0; i < lines.length; i++) { + if (lines[i].match(/[^ \t]/)) { + lastNonEmptyLine = i; + } + } + + for (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 += " "; + } + + args.push(t.literal(trimmedLine)); + } + } + }; + + // display names + + var addDisplayName = function (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.ExportDeclaration = function (node, parent, scope, file) { + if (node.default && 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); + } + }; +}; + +},{"../../messages":27,"../../types":119,"./react":37,"esutils":181,"lodash/lang/isString":291}],34:[function(require,module,exports){ +var cloneDeep = require("lodash/lang/cloneDeep"); +var traverse = require("../../traversal"); +var clone = require("lodash/lang/clone"); +var each = require("lodash/collection/each"); +var has = require("lodash/object/has"); +var t = require("../../types"); + +exports.push = function (mutatorMap, key, kind, computed, value) { + var alias; + + if (t.isIdentifier(key)) { + alias = key.name; + if (computed) alias = "computed:" + alias; + } else if (t.isLiteral(key)) { + alias = String(key.value); + } else { + alias = JSON.stringify(traverse.removeProperties(cloneDeep(key))); + } + + var map; + if (has(mutatorMap, alias)) { + map = mutatorMap[alias]; + } else { + map = {}; + } + mutatorMap[alias] = map; + + map._key = key; + if (computed) { + map._computed = true; + } + + map[kind] = value; +}; + +exports.build = function (mutatorMap) { + var objExpr = t.objectExpression([]); + + each(mutatorMap, function (map) { + var mapNode = t.objectExpression([]); + + var propNode = t.property("init", map._key, mapNode, map._computed); + + if (!map.get && !map.set) { + map.writable = t.literal(true); + } + + if (map.enumerable === false) { + delete map.enumerable; + } else { + map.enumerable = t.literal(true); + } + + map.configurable = t.literal(true); + + each(map, function (node, key) { + if (key[0] === "_") return; + + node = clone(node); + var inheritNode = node; + if (t.isMethodDefinition(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; +}; + +},{"../../traversal":114,"../../types":119,"lodash/collection/each":197,"lodash/lang/clone":280,"lodash/lang/cloneDeep":281,"lodash/object/has":296}],35:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); + +var getObjRef = function (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 (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 + }; +}; + +},{"../../types":119}],36:[function(require,module,exports){ +"use strict"; + +var util = require("../../util"); +var t = require("../../types"); + +var visitor = { + enter: function (node, parent, scope, state) { + // check if this node is a referenced identifier that matches the same as our + // function id + if (!t.isReferencedIdentifier(node, parent, { 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 (state, method, id, scope) { + if (state.selfReference) { + var templateName = "property-method-assignment-wrapper"; + if (method.generator) templateName += "-generator"; + return util.template(templateName, { + FUNCTION: method, + FUNCTION_ID: id, + FUNCTION_KEY: scope.generateUidIdentifier(id.name), + WRAPPER_KEY: scope.generateUidIdentifier(id.name + "Wrapper") + }); + } else { + method.id = id; + return method; + } +}; + +var visit = function (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 = null; // todo: proper scope not being passed in es6/classes // 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 { + // 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 + } + } else { + scope.traverse(node, visitor, state); + } + + return state; +}; + +exports.property = function (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); + var id = t.identifier(name); + + var method = node.value; + var state = visit(method, name, scope); + node.value = wrap(state, method, id, scope); +}; + +exports.bare = function (node, parent, scope) { + // has an `id` so we don't need to infer one + if (node.id) return; + + var id; + if (t.isProperty(parent) && parent.kind === "init" && !parent.computed) { + // { foo: function () {} }; + id = parent.key; + } else if (t.isVariableDeclarator(parent)) { + // var foo = function () {}; + id = parent.id; + } else { + return; + } + + if (!t.isIdentifier(id)) return; + + var name = t.toIdentifier(id.name); + id = t.identifier(name); + + var state = visit(node, name, scope); + return wrap(state, node, id, scope); +}; + +},{"../../types":119,"../../util":121}],37:[function(require,module,exports){ +var t = require("../../types"); + +var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass"); + +exports.isCreateClass = function (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; +}; + +exports.isReactComponent = t.buildMatchMemberExpression("React.Component"); + +exports.isCompatTag = function (tagName) { + return tagName && /^[a-z]|\-/.test(tagName); +}; + +},{"../../types":119}],38:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); + +var visitor = { + enter: function (node) { + 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]); + } + } + } +}; + +module.exports = function (node, callId, scope) { + node.async = false; + node.generator = true; + + scope.traverse(node, visitor); + + var call = t.callExpression(callId, [node]); + var id = node.id; + delete node.id; + + if (t.isFunctionDeclaration(node)) { + var declar = t.variableDeclaration("let", [ + t.variableDeclarator(id, call) + ]); + declar._blockHoist = true; + return declar; + } else { + return call; + } +}; + +},{"../../types":119}],39:[function(require,module,exports){ +"use strict"; + +module.exports = ReplaceSupers; + +var messages = require("../../messages"); +var t = require("../../types"); + +/** + * Description + * + * @param {Object} opts + * @param {Boolean} [inClass] + */ + +function ReplaceSupers(opts, inClass) { + this.topLevelThisReference = opts.topLevelThisReference; + this.methodNode = opts.methodNode; + this.className = opts.className; + this.superName = opts.superName; + this.isStatic = opts.isStatic; + this.hasSuper = false; + this.inClass = inClass; + this.isLoose = opts.isLoose; + this.scope = opts.scope; + this.file = opts.file; +} + +/** + * Sets a super class value of the named property. + * + * @example + * + * _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this) + * + * @param {Node} property + * @param {Node} value + * @param {Boolean} isComputed + * @param {Node} thisExpression + * + * @returns {Node} + */ + +ReplaceSupers.prototype.setSuperProperty = function (property, value, isComputed, thisExpression) { + return t.callExpression( + this.file.addHelper("set"), + [ + t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")), + [ + this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype")) + ] + ), + isComputed ? property : t.literal(property.name), + value, + thisExpression + ] + ); +}; + +/** + * Gets a node representing the super class value of the named property. + * + * @example + * + * _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this) + * + * @param {Node} property + * @param {Boolean} isComputed + * @param {Node} thisExpression + * + * @returns {Node} + */ + +ReplaceSupers.prototype.getSuperProperty = function (property, isComputed, thisExpression) { + return t.callExpression( + this.file.addHelper("get"), + [ + t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")), + [ + this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype")) + ] + ), + isComputed ? property : t.literal(property.name), + thisExpression + ] + ); +}; + +/** + * Description + */ + +ReplaceSupers.prototype.replace = function () { + this.traverseLevel(this.methodNode.value, true); +}; + +var visitor = { + enter: function (node, parent, scope, state) { + var topLevel = state.topLevel; + var self = state.self; + + if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) { + // we need to call traverseLevel again so we're context aware + self.traverseLevel(node, false); + return this.skip(); + } + + if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) { + // break on object methods + return this.skip(); + } + + var getThisReference = topLevel ? + // top level so `this` is the instance + t.thisExpression : + // not in the top level so we need to create a reference + self.getThisReference.bind(self); + + var callback = self.specHandle; + if (self.isLoose) callback = self.looseHandle; + return callback.call(self, getThisReference, node, parent); + } +}; + +/** + * Description + * + * @param {Object} node + * @param {Boolean} topLevel + */ + +ReplaceSupers.prototype.traverseLevel = function (node, topLevel) { + var state = { self: this, topLevel: topLevel }; + this.scope.traverse(node, visitor, state); +}; + +/** + * Description + */ + +ReplaceSupers.prototype.getThisReference = function () { + if (this.topLevelThisReference) { + return this.topLevelThisReference; + } else { + var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this"); + this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(this.topLevelThisReference, t.thisExpression()) + ])); + return ref; + } +}; + +/** + * Description + * + * @param {Object} node + * @param {Object} id + * @param {Object} parent + * @returns {Object} + */ + +ReplaceSupers.prototype.getLooseSuperProperty = function (id, parent) { + var methodNode = this.methodNode; + var methodName = methodNode.key; + var superName = this.superName || t.identifier("Function"); + + if (parent.property === id) { + return; + } else if (t.isCallExpression(parent, { callee: id })) { + // super(); -> ClassName.prototype.MethodName.call(this); + parent.arguments.unshift(t.thisExpression()); + + if (methodName.name === "constructor") { + // constructor() { super(); } + return t.memberExpression(superName, t.identifier("call")); + } else { + id = superName; + + // foo() { super(); } + if (!methodNode.static) { + id = t.memberExpression(id, t.identifier("prototype")); + } + + id = t.memberExpression(id, methodName, methodNode.computed); + return t.memberExpression(id, t.identifier("call")); + } + } else if (t.isMemberExpression(parent) && !methodNode.static) { + // super.test -> ClassName.prototype.test + return t.memberExpression(superName, t.identifier("prototype")); + } else { + return superName; + } +}; + +/** + * Description + * + * @param {Function} getThisReference + * @param {Object} node + * @param {Object} parent + */ + +ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) { + if (t.isIdentifier(node, { name: "super" })) { + this.hasSuper = true; + return this.getLooseSuperProperty(node, parent); + } else if (t.isCallExpression(node)) { + var callee = node.callee; + if (!t.isMemberExpression(callee)) return; + if (callee.object.name !== "super") return; + + // super.test(); -> ClassName.prototype.MethodName.call(this); + this.hasSuper = true; + t.appendToMemberExpression(callee, t.identifier("call")); + node.arguments.unshift(getThisReference()); + } +}; + +/** + * Description + * + * @param {Function} getThisReference + * @param {Object} node + * @param {Object} parent + */ + +ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) { + var methodNode = this.methodNode; + var property; + var computed; + var args; + var thisReference; + + if (isIllegalBareSuper(node, parent)) { + throw this.file.errorWithNode(node, messages.get("classesIllegalBareSuper")); + } + + if (t.isCallExpression(node)) { + var callee = node.callee; + if (isSuper(callee, node)) { + // super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this); + property = methodNode.key; + computed = methodNode.computed; + args = node.arguments; + + // bare `super` call is illegal inside non-constructors + // - https://esdiscuss.org/topic/super-call-in-methods + // - https://twitter.com/wycats/status/544553184396836864 + if (methodNode.key.name !== "constructor" || !this.inClass) { + var methodName = methodNode.key.name || "METHOD_NAME"; + throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName)); + } + } else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) { + // super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this); + property = callee.property; + computed = callee.computed; + args = node.arguments; + } + } else if (t.isMemberExpression(node) && isSuper(node.object, node)) { + // super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this); + property = node.property; + computed = node.computed; + } else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") { + // super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this); + this.hasSuper = true; + return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference()); + } + + if (!property) return; + + this.hasSuper = true; + + thisReference = getThisReference(); + var superProperty = this.getSuperProperty(property, computed, thisReference); + if (args) { + if (args.length === 1 && t.isSpreadElement(args[0])) { + // super(...arguments); + return t.callExpression( + t.memberExpression(superProperty, t.identifier("apply")), + [thisReference, args[0].argument] + ); + } else { + return t.callExpression( + t.memberExpression(superProperty, t.identifier("call")), + [thisReference].concat(args) + ); + } + } else { + return superProperty; + } +}; + +var isIllegalBareSuper = function (node, parent) { + if (!isSuper(node, parent)) return false; + if (t.isMemberExpression(parent, { computed: false })) return false; + if (t.isCallExpression(parent, { callee: node })) return false; + return true; +}; + +var isSuper = function (node, parent) { + return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent); +}; + +},{"../../messages":27,"../../types":119}],40:[function(require,module,exports){ +"use strict"; + +var t = require("../../types"); + +exports.has = function (node) { + var first = node.body[0]; + return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" }); +}; + +exports.wrap = function (node, callback) { + var useStrictNode; + if (exports.has(node)) { + useStrictNode = node.body.shift(); + } + + callback(); + + if (useStrictNode) { + node.body.unshift(useStrictNode); + } +}; + +},{"../../types":119}],41:[function(require,module,exports){ +"use strict"; + +module.exports = transform; + +var normalizeAst = require("../helpers/normalize-ast"); +var Transformer = require("./transformer"); +var object = require("../helpers/object"); +var File = require("./file"); +var each = require("lodash/collection/each"); + +function transform(code, opts) { + var file = new File(opts); + return file.parse(code); +} + +transform.fromAst = function (ast, code, opts) { + ast = normalizeAst(ast); + + var file = new File(opts); + file.addCode(code); + file.transform(ast); + return file.generate(); +}; + +transform._ensureTransformerNames = function (type, rawKeys) { + var keys = []; + + for (var i = 0; i < rawKeys.length; i++) { + var key = rawKeys[i]; + + var deprecatedKey = transform.deprecatedTransformerMap[key]; + if (deprecatedKey) { + // deprecated key, remap it to the new one + console.error("The transformer " + key + " has been renamed to " + deprecatedKey); + rawKeys.push(deprecatedKey); + } else if (transform.transformers[key]) { + // valid key + keys.push(key); + } else if (transform.namespaces[key]) { + // namespace, append all transformers within this namespace + keys = keys.concat(transform.namespaces[key]); + } else { + // invalid key + throw new ReferenceError("Unknown transformer " + key + " specified in " + type); + } + } + + return keys; +}; + +transform.transformerNamespaces = object(); +transform.transformers = object(); +transform.namespaces = object(); + +transform.deprecatedTransformerMap = require("./transformers/deprecated"); +transform.moduleFormatters = require("./modules"); + +var rawTransformers = require("./transformers"); + +each(rawTransformers, function (transformer, key) { + var namespace = key.split(".")[0]; + + transform.namespaces[namespace] = transform.namespaces[namespace] || []; + transform.namespaces[namespace].push(key); + transform.transformerNamespaces[key] = namespace; + + transform.transformers[key] = new Transformer(key, transformer); +}); + +},{"../helpers/normalize-ast":23,"../helpers/object":24,"./file":29,"./modules":49,"./transformer":54,"./transformers":80,"./transformers/deprecated":55,"lodash/collection/each":197}],42:[function(require,module,exports){ +"use strict"; + +module.exports = DefaultFormatter; + +var messages = require("../../messages"); +var extend = require("lodash/object/extend"); +var object = require("../../helpers/object"); +var util = require("../../util"); +var t = require("../../types"); + +function DefaultFormatter(file) { + this.scope = file.scope; + this.file = file; + this.ids = object(); + + this.hasNonDefaultExports = false; + + this.hasLocalExports = false; + this.hasLocalImports = false; + + this.localImportOccurences = object(); + this.localExports = object(); + this.localImports = object(); + + this.getLocalExports(); + this.getLocalImports(); + + this.remapAssignments(); +} + +DefaultFormatter.prototype.doDefaultExportInterop = function (node) { + return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports; +}; + +DefaultFormatter.prototype.bumpImportOccurences = function (node) { + var source = node.source.value; + var occurs = this.localImportOccurences; + occurs[source] = occurs[source] || 0; + occurs[source] += node.specifiers.length; +}; + +var exportsVisitor = { + enter: function (node, parent, scope, formatter) { + var declar = node && node.declaration; + if (t.isExportDeclaration(node)) { + formatter.hasLocalImports = true; + + if (declar && t.isStatement(declar)) { + extend(formatter.localExports, t.getBindingIdentifiers(declar)); + } + + if (!node.default) { + formatter.hasNonDefaultExports = true; + } + + if (node.source) { + formatter.bumpImportOccurences(node); + } + } + } +}; + +DefaultFormatter.prototype.getLocalExports = function () { + this.file.scope.traverse(this.file.ast, exportsVisitor, this); +}; + +var importsVisitor = { + enter: function (node, parent, scope, formatter) { + if (t.isImportDeclaration(node)) { + formatter.hasLocalImports = true; + extend(formatter.localImports, t.getBindingIdentifiers(node)); + formatter.bumpImportOccurences(node); + } + } +}; + +DefaultFormatter.prototype.getLocalImports = function () { + this.file.scope.traverse(this.file.ast, importsVisitor, this); +}; + +var remapVisitor = { + enter: function (node, parent, scope, formatter) { + if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) { + this.skip(); + + // expand to long file assignment expression + var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1)); + + // remap this assignment expression + var remapped = formatter.remapExportAssignment(assign); + + // we don't need to change the result + if (t.isExpressionStatement(parent) || node.prefix) { + return remapped; + } + + var nodes = []; + nodes.push(remapped); + + var operator; + if (node.operator === "--") { + operator = "+"; + } else { // "++" + operator = "-"; + } + nodes.push(t.binaryExpression(operator, node.argument, t.literal(1))); + + return t.sequenceExpression(nodes); + } + + if (t.isAssignmentExpression(node) && formatter.isLocalReference(node.left, scope)) { + this.skip(); + return formatter.remapExportAssignment(node); + } + } +}; + +DefaultFormatter.prototype.remapAssignments = function () { + if (this.hasLocalImports) { + this.file.scope.traverse(this.file.ast, remapVisitor, this); + } +}; + +DefaultFormatter.prototype.isLocalReference = function (node) { + var localImports = this.localImports; + return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node; +}; + +DefaultFormatter.prototype.remapExportAssignment = function (node) { + return t.assignmentExpression( + "=", + node.left, + t.assignmentExpression( + node.operator, + t.memberExpression(t.identifier("exports"), node.left), + node.right + ) + ); +}; + +DefaultFormatter.prototype.isLocalReference = function (node, scope) { + var localExports = this.localExports; + var name = node.name; + return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name); +}; + +DefaultFormatter.prototype.getModuleName = function () { + var opts = this.file.opts; + if (opts.moduleId) return opts.moduleId; + + var filenameRelative = opts.filenameRelative; + var moduleName = ""; + + if (opts.moduleRoot) { + moduleName = opts.moduleRoot + "/"; + } + + if (!opts.filenameRelative) { + return moduleName + opts.filename.replace(/^\//, ""); + } + + if (opts.sourceRoot) { + // remove sourceRoot from filename + var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?"); + filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); + } + + if (!opts.keepModuleIdExtensions) { + // remove extension + filenameRelative = filenameRelative.replace(/\.(\w*?)$/, ""); + } + + moduleName += filenameRelative; + + // normalize path separators + moduleName = moduleName.replace(/\\/g, "/"); + + return moduleName; +}; + +DefaultFormatter.prototype._pushStatement = function (ref, nodes) { + if (t.isClass(ref) || t.isFunction(ref)) { + if (ref.id) { + nodes.push(t.toStatement(ref)); + ref = ref.id; + } + } + + return ref; +}; + +DefaultFormatter.prototype._hoistExport = function (declar, assign, priority) { + if (t.isFunctionDeclaration(declar)) { + assign._blockHoist = priority || 2; + } + + return assign; +}; + +DefaultFormatter.prototype.getExternalReference = function (node, nodes) { + var ids = this.ids; + var id = node.source.value; + + if (ids[id]) { + return ids[id]; + } else { + return this.ids[id] = this._getExternalReference(node, nodes); + } +}; + +DefaultFormatter.prototype.checkExportIdentifier = function (node) { + if (t.isIdentifier(node, { name: "__esModule" })) { + throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name)); + } +}; + +DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + if (node.source) { + var ref = this.getExternalReference(node, nodes); + + if (t.isExportBatchSpecifier(specifier)) { + // export * from "foo"; + nodes.push(this.buildExportsWildcard(ref, node)); + } else { + if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) { + // importing a default so we need to normalize it + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } else { + ref = t.memberExpression(ref, t.getSpecifierId(specifier)); + } + + // export { foo } from "test"; + nodes.push(this.buildExportsAssignment( + t.getSpecifierName(specifier), + ref, + node + )); + } + } else { + // export { foo }; + nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node)); + } +}; + +DefaultFormatter.prototype.buildExportsWildcard = function (objectIdentifier) { + return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [ + t.identifier("exports"), + t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier]) + ])); +}; + +DefaultFormatter.prototype.buildExportsAssignment = function (id, init) { + this.checkExportIdentifier(id); + return util.template("exports-assign", { + VALUE: init, + KEY: id + }, true); +}; + +DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { + var declar = node.declaration; + + var id = declar.id; + + if (node.default) { + id = t.identifier("default"); + } + + var assign; + + if (t.isVariableDeclaration(declar)) { + for (var i = 0; i < declar.declarations.length; i++) { + var decl = declar.declarations[i]; + + decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression; + + var newDeclar = t.variableDeclaration(declar.kind, [decl]); + if (i === 0) t.inherits(newDeclar, declar); + nodes.push(newDeclar); + } + } else { + var ref = declar; + + if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) { + ref = declar.id; + nodes.push(declar); + } + + assign = this.buildExportsAssignment(id, ref, node); + + nodes.push(assign); + + this._hoistExport(declar, assign); + } +}; + +},{"../../helpers/object":24,"../../messages":27,"../../types":119,"../../util":121,"lodash/object/extend":295}],43:[function(require,module,exports){ +"use strict"; + +var util = require("../../util"); + +module.exports = function (Parent) { + var Constructor = function () { + this.noInteropRequireImport = true; + this.noInteropRequireExport = true; + Parent.apply(this, arguments); + }; + + util.inherits(Constructor, Parent); + + return Constructor; +}; + +},{"../../util":121}],44:[function(require,module,exports){ +"use strict"; + +module.exports = require("./_strict")(require("./amd")); + +},{"./_strict":43,"./amd":45}],45:[function(require,module,exports){ +"use strict"; + +module.exports = AMDFormatter; + +var DefaultFormatter = require("./_default"); +var CommonFormatter = require("./common"); +var includes = require("lodash/collection/includes"); +var values = require("lodash/object/values"); +var util = require("../../util"); +var t = require("../../types"); + +function AMDFormatter() { + CommonFormatter.apply(this, arguments); +} + +util.inherits(AMDFormatter, DefaultFormatter); + +AMDFormatter.prototype.init = CommonFormatter.prototype.init; + +AMDFormatter.prototype.buildDependencyLiterals = function () { + var names = []; + for (var name in this.ids) { + names.push(t.literal(name)); + } + return names; +}; + +/** + * Wrap the entire body in a `define` wrapper. + */ + +AMDFormatter.prototype.transform = function (program) { + var body = program.body; + + // build an array of module names + + var names = [t.literal("exports")]; + if (this.passModuleArg) names.push(t.literal("module")); + names = names.concat(this.buildDependencyLiterals()); + names = t.arrayExpression(names); + + // build up define container + + var params = values(this.ids); + if (this.passModuleArg) params.unshift(t.identifier("module")); + params.unshift(t.identifier("exports")); + + var container = t.functionExpression(null, params, t.blockStatement(body)); + + var defineArgs = [names, container]; + var moduleName = this.getModuleName(); + if (moduleName) defineArgs.unshift(t.literal(moduleName)); + + var call = t.callExpression(t.identifier("define"), defineArgs); + + program.body = [t.expressionStatement(call)]; +}; + +/** + * Get the AMD module name that we'll prepend to the wrapper + * to define this module + */ + +AMDFormatter.prototype.getModuleName = function () { + if (this.file.opts.moduleIds) { + return DefaultFormatter.prototype.getModuleName.apply(this, arguments); + } else { + return null; + } +}; + +AMDFormatter.prototype._getExternalReference = function (node) { + return this.scope.generateUidIdentifier(node.source.value); +}; + +AMDFormatter.prototype.importDeclaration = function (node) { + this.getExternalReference(node); +}; + +AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) { + var key = t.getSpecifierName(specifier); + var ref = this.getExternalReference(node); + + if (includes(this.file.dynamicImportedNoDefault, node)) { + // Prevent unnecessary renaming of dynamic imports. + this.ids[node.source.value] = ref; + } else if (t.isImportBatchSpecifier(specifier)) { + // import * as bar from "foo"; + } else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) { + // import foo from "foo"; + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } else { + // import {foo} from "foo"; + ref = t.memberExpression(ref, t.getSpecifierId(specifier), false); + } + + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(key, ref) + ])); +}; + +AMDFormatter.prototype.exportDeclaration = function (node) { + if (this.doDefaultExportInterop(node)) { + this.passModuleArg = true; + } + + CommonFormatter.prototype.exportDeclaration.apply(this, arguments); +}; + +},{"../../types":119,"../../util":121,"./_default":42,"./common":47,"lodash/collection/includes":200,"lodash/object/values":299}],46:[function(require,module,exports){ +"use strict"; + +module.exports = require("./_strict")(require("./common")); + +},{"./_strict":43,"./common":47}],47:[function(require,module,exports){ +"use strict"; + +module.exports = CommonJSFormatter; + +var DefaultFormatter = require("./_default"); +var includes = require("lodash/collection/includes"); +var util = require("../../util"); +var t = require("../../types"); + +function CommonJSFormatter() { + DefaultFormatter.apply(this, arguments); +} + +util.inherits(CommonJSFormatter, DefaultFormatter); + +CommonJSFormatter.prototype.init = function () { + var file = this.file; + var scope = file.scope; + + scope.rename("module"); + + if (!this.noInteropRequireImport && this.hasNonDefaultExports) { + var templateName = "exports-module-declaration"; + if (this.file.isLoose("es6.modules")) templateName += "-loose"; + file.ast.program.body.push(util.template(templateName, true)); + } +}; + +CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { + var variableName = t.getSpecifierName(specifier); + + var ref = this.getExternalReference(node, nodes); + + // import foo from "foo"; + if (t.isSpecifierDefault(specifier)) { + if (!includes(this.file.dynamicImportedNoDefault, node)) { + if (this.noInteropRequireImport || includes(this.file.dynamicImported, node)) { + ref = t.memberExpression(ref, t.identifier("default")); + } else { + ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); + } + } + nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)])); + } else { + if (specifier.type === "ImportBatchSpecifier") { + + if (!this.noInteropRequireImport) { + ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]); + } + + // import * as bar from "foo"; + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(variableName, ref) + ])); + } else { + // import { foo } from "foo"; + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator( + variableName, + t.memberExpression(ref, t.getSpecifierId(specifier)) + ) + ])); + } + } +}; + +CommonJSFormatter.prototype.importDeclaration = function (node, nodes) { + // import "foo"; + nodes.push(util.template("require", { + MODULE_NAME: node.source + }, true)); +}; + +CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) { + if (this.doDefaultExportInterop(node)) { + var declar = node.declaration; + var assign = util.template("exports-default-assign", { + VALUE: this._pushStatement(declar, nodes) + }, true); + + if (t.isFunctionDeclaration(declar)) { + // we can hoist this assignment to the top of the file + assign._blockHoist = 3; + } + + nodes.push(assign); + return; + } + + DefaultFormatter.prototype.exportDeclaration.apply(this, arguments); +}; + +CommonJSFormatter.prototype._getExternalReference = function (node, nodes) { + var source = node.source.value; + var call = t.callExpression(t.identifier("require"), [node.source]); + + if (this.localImportOccurences[source] > 1) { + var uid = this.scope.generateUidIdentifier(source); + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(uid, call) + ])); + return uid; + } else { + return call; + } +}; + +},{"../../types":119,"../../util":121,"./_default":42,"lodash/collection/includes":200}],48:[function(require,module,exports){ +"use strict"; + +module.exports = IgnoreFormatter; + +var t = require("../../types"); + +function IgnoreFormatter() { + +} + +IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) { + var declar = t.toStatement(node.declaration, true); + if (declar) nodes.push(t.inherits(declar, node)); +}; + +IgnoreFormatter.prototype.importDeclaration = +IgnoreFormatter.prototype.importSpecifier = +IgnoreFormatter.prototype.exportSpecifier = function () { + +}; + +},{"../../types":119}],49:[function(require,module,exports){ +module.exports = { + commonStrict: require("./common-strict"), + amdStrict: require("./amd-strict"), + umdStrict: require("./umd-strict"), + common: require("./common"), + system: require("./system"), + ignore: require("./ignore"), + amd: require("./amd"), + umd: require("./umd") +}; + +},{"./amd":45,"./amd-strict":44,"./common":47,"./common-strict":46,"./ignore":48,"./system":50,"./umd":52,"./umd-strict":51}],50:[function(require,module,exports){ +"use strict"; + +module.exports = SystemFormatter; + +var DefaultFormatter = require("./_default"); +var AMDFormatter = require("./amd"); +var util = require("../../util"); +var last = require("lodash/array/last"); +var each = require("lodash/collection/each"); +var map = require("lodash/collection/map"); +var t = require("../../types"); + +function SystemFormatter(file) { + this.exportIdentifier = file.scope.generateUidIdentifier("export"); + this.noInteropRequireExport = true; + this.noInteropRequireImport = true; + + DefaultFormatter.apply(this, arguments); +} + +util.inherits(SystemFormatter, AMDFormatter); + +SystemFormatter.prototype.init = function () {}; + +SystemFormatter.prototype._addImportSource = function (node, exportNode) { + node._importSource = exportNode.source && exportNode.source.value; + return node; +}; + +SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) { + var leftIdentifier = this.scope.generateUidIdentifier("key"); + var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true); + + var left = t.variableDeclaration("var", [ + t.variableDeclarator(leftIdentifier) + ]); + + var right = objectIdentifier; + + var block = t.blockStatement([ + t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier)) + ]); + + return this._addImportSource(t.forInStatement(left, right, block), node); +}; + +SystemFormatter.prototype.buildExportsAssignment = function (id, init, node) { + var call = this.buildExportCall(t.literal(id.name), init, true); + return this._addImportSource(call, node); +}; + +SystemFormatter.prototype.remapExportAssignment = function (node) { + return this.buildExportCall(t.literal(node.left.name), node); +}; + +SystemFormatter.prototype.buildExportCall = function (id, init, isStatement) { + var call = t.callExpression(this.exportIdentifier, [id, init]); + if (isStatement) { + return t.expressionStatement(call); + } else { + return call; + } +}; + +SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) { + AMDFormatter.prototype.importSpecifier.apply(this, arguments); + this._addImportSource(last(nodes), node); +}; + +var runnerSettersVisitor = { + enter: function (node, parent, scope, state) { + if (node._importSource === state.source) { + if (t.isVariableDeclaration(node)) { + each(node.declarations, function (declar) { + state.hoistDeclarators.push(t.variableDeclarator(declar.id)); + state.nodes.push(t.expressionStatement( + t.assignmentExpression("=", declar.id, declar.init) + )); + }); + } else { + state.nodes.push(node); + } + + this.remove(); + } + } +}; + +SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) { + var scope = this.file.scope; + + return t.arrayExpression(map(this.ids, function (uid, source) { + var state = { + source: source, + nodes: [], + hoistDeclarators: hoistDeclarators + }; + + scope.traverse(block, runnerSettersVisitor, state); + + return t.functionExpression(null, [uid], t.blockStatement(state.nodes)); + })); +}; + +var hoistVariablesVisitor = { + enter: function (node, parent, scope, hoistDeclarators) { + if (t.isFunction(node)) { + // nothing inside is accessible + return this.skip(); + } + + if (t.isVariableDeclaration(node)) { + if (node.kind !== "var" && !t.isProgram(parent)) { // let, const + // can't be accessed + return; + } + + // ignore block hoisted nodes as these can be left in + if (node._blockHoist) return; + + var nodes = []; + + for (var i = 0; i < node.declarations.length; i++) { + var declar = node.declarations[i]; + hoistDeclarators.push(t.variableDeclarator(declar.id)); + if (declar.init) { + // no initializer so we can just hoist it as-is + var assign = t.expressionStatement(t.assignmentExpression("=", declar.id, declar.init)); + nodes.push(assign); + } + } + + // for (var i in test) + // for (var i = 0;;) + if (t.isFor(parent)) { + if (parent.left === node) { + return node.declarations[0].id; + } + + if (parent.init === node) { + return t.toSequenceExpression(nodes, scope); + } + } + + return nodes; + } + } +}; + +var hoistFunctionsVisitor = { + enter: function (node, parent, scope, handlerBody) { + if (t.isFunction(node)) this.skip(); + + if (t.isFunctionDeclaration(node) || node._blockHoist) { + handlerBody.push(node); + this.remove(); + } + } +}; + +SystemFormatter.prototype.transform = function (program) { + var hoistDeclarators = []; + var moduleName = this.getModuleName(); + var moduleNameLiteral = t.literal(moduleName); + + var block = t.blockStatement(program.body); + + var runner = util.template("system", { + MODULE_NAME: moduleNameLiteral, + MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()), + EXPORT_IDENTIFIER: this.exportIdentifier, + SETTERS: this.buildRunnerSetters(block, hoistDeclarators), + EXECUTE: t.functionExpression(null, [], block) + }, true); + + var handlerBody = runner.expression.arguments[2].body.body; + if (!moduleName) runner.expression.arguments.shift(); + + var returnStatement = handlerBody.pop(); + + // hoist up all variable declarations + this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators); + + if (hoistDeclarators.length) { + var hoistDeclar = t.variableDeclaration("var", hoistDeclarators); + hoistDeclar._blockHoist = true; + handlerBody.unshift(hoistDeclar); + } + + // hoist up function declarations for circular references + this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody); + + handlerBody.push(returnStatement); + + program.body = [runner]; +}; + +},{"../../types":119,"../../util":121,"./_default":42,"./amd":45,"lodash/array/last":193,"lodash/collection/each":197,"lodash/collection/map":201}],51:[function(require,module,exports){ +"use strict"; + +module.exports = require("./_strict")(require("./umd")); + +},{"./_strict":43,"./umd":52}],52:[function(require,module,exports){ +"use strict"; + +module.exports = UMDFormatter; + +var AMDFormatter = require("./amd"); +var util = require("../../util"); +var t = require("../../types"); +var values = require("lodash/object/values"); + +function UMDFormatter() { + AMDFormatter.apply(this, arguments); +} + +util.inherits(UMDFormatter, AMDFormatter); + +UMDFormatter.prototype.transform = function (program) { + var body = program.body; + + // build an array of module names + + var names = []; + for (var name in this.ids) { + names.push(t.literal(name)); + } + + // factory + + var ids = values(this.ids); + var args = [t.identifier("exports")]; + if (this.passModuleArg) args.push(t.identifier("module")); + args = args.concat(ids); + + var factory = t.functionExpression(null, args, t.blockStatement(body)); + + // amd + + var defineArgs = [t.literal("exports")]; + if (this.passModuleArg) defineArgs.push(t.literal("module")); + defineArgs = defineArgs.concat(names); + defineArgs = [t.arrayExpression(defineArgs)]; + + // common + + var testExports = util.template("test-exports"); + var testModule = util.template("test-module"); + var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; + + var commonArgs = [t.identifier("exports")]; + if (this.passModuleArg) commonArgs.push(t.identifier("module")); + commonArgs = commonArgs.concat(names.map(function (name) { + return t.callExpression(t.identifier("require"), [name]); + })); + + // globals + + //var umdArgs = []; + + // + + var moduleName = this.getModuleName(); + if (moduleName) defineArgs.unshift(t.literal(moduleName)); + + var runner = util.template("umd-runner-body", { + AMD_ARGUMENTS: defineArgs, + COMMON_TEST: commonTests, + COMMON_ARGUMENTS: commonArgs + }); + + // + + var call = t.callExpression(runner, [factory]); + program.body = [t.expressionStatement(call)]; +}; + +},{"../../types":119,"../../util":121,"./amd":45,"lodash/object/values":299}],53:[function(require,module,exports){ +module.exports = TransformerPass; + +var includes = require("lodash/collection/includes"); + +/** + * This class is responsible for traversing over the provided `File`s + * AST and running it's parent transformers handlers over it. + */ + +function TransformerPass(file, transformer) { + this.transformer = transformer; + this.shouldRun = !transformer.check; + this.handlers = transformer.handlers; + this.file = file; +} + +TransformerPass.prototype.canRun = function () { + var transformer = this.transformer; + + var opts = this.file.opts; + var key = transformer.key; + + // internal + if (key[0] === "_") return true; + + // blacklist + var blacklist = opts.blacklist; + if (blacklist.length && includes(blacklist, key)) return false; + + // whitelist + var whitelist = opts.whitelist; + if (whitelist.length) return includes(whitelist, key); + + // optional + if (transformer.optional && !includes(opts.optional, key)) return false; + + // experimental + if (transformer.experimental && !opts.experimental) return false; + + // playground + if (transformer.playground && !opts.playground) return false; + + return true; +}; + +TransformerPass.prototype.checkNode = function (node) { + var check = this.transformer.check; + if (check) { + return this.shouldRun = check(node); + } else { + return true; + } +}; + +TransformerPass.prototype.transform = function () { + if (!this.shouldRun) return; + + var file = this.file; + + file.debug("Running transformer " + this.transformer.key); + + file.scope.traverse(file.ast, this.handlers, file); +}; + +},{"lodash/collection/includes":200}],54:[function(require,module,exports){ +"use strict"; + +module.exports = Transformer; + +var TransformerPass = require("./transformer-pass"); +var isFunction = require("lodash/lang/isFunction"); +var traverse = require("../traversal"); +var isObject = require("lodash/lang/isObject"); +var assign = require("lodash/object/assign"); +var each = require("lodash/collection/each"); + +/** + * This is the class responsible for normalising a transformers handlers + * as well as constructing a `TransformerPass` that is repsonsible for + * actually running the transformer over the provided `File`. + */ + +function Transformer(key, transformer, opts) { + transformer = assign({}, transformer); + + var take = function (key) { + var val = transformer[key]; + delete transformer[key]; + return val; + }; + + this.manipulateOptions = take("manipulateOptions"); + this.check = take("check"); + this.post = take("post"); + this.pre = take("pre"); + + this.experimental = !!take("experimental"); + this.playground = !!take("playground"); + this.secondPass = !!take("secondPass"); + this.optional = !!take("optional"); + + this.handlers = this.normalize(transformer); + this.opts = opts || {}; + this.key = key; +} + +Transformer.prototype.normalize = function (transformer) { + var self = this; + + if (isFunction(transformer)) { + transformer = { ast: transformer }; + } + + traverse.explode(transformer); + + each(transformer, function (fns, type) { + // hidden property + if (type[0] === "_") { + self[type] = fns; + return; + } + + if (type === "enter" || type === "exit") return; + + if (isFunction(fns)) fns = { enter: fns }; + + if (!isObject(fns)) return; + + if (!fns.enter) fns.enter = function () { }; + if (!fns.exit) fns.exit = function () { }; + + transformer[type] = fns; + }); + + return transformer; +}; + +Transformer.prototype.buildPass = function (file) { + return new TransformerPass(file, this); +}; + +},{"../traversal":114,"./transformer-pass":53,"lodash/collection/each":197,"lodash/lang/isFunction":286,"lodash/lang/isObject":289,"lodash/object/assign":293}],55:[function(require,module,exports){ +module.exports={ + "selfContained": "runtime" +} + +},{}],56:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.MemberExpression = function (node) { + var prop = node.property; + if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { + // foo["bar"] => foo.bar + node.property = t.identifier(prop.value); + node.computed = false; + } else if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) { + // foo.default -> foo["default"] + node.property = t.literal(prop.name); + node.computed = true; + } +}; + +},{"../../../types":119}],57:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.Property = function (node) { + var key = node.key; + if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { + // "foo": "bar" -> foo: "bar" + node.key = t.identifier(key.value); + node.computed = false; + } else if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) { + // default: "bar" -> "default": "bar" + node.key = t.literal(key.name); + } +}; + +},{"../../../types":119}],58:[function(require,module,exports){ +"use strict"; + +var defineMap = require("../../helpers/define-map"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isProperty(node) && (node.kind === "get" || node.kind === "set"); +}; + +exports.ObjectExpression = function (node) { + var mutatorMap = {}; + var hasAny = false; + + node.properties = node.properties.filter(function (prop) { + if (prop.kind === "get" || prop.kind === "set") { + hasAny = true; + defineMap.push(mutatorMap, prop.key, prop.kind, prop.computed, prop.value); + return false; + } else { + return true; + } + }); + + if (!hasAny) return; + + return t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), + [node, defineMap.build(mutatorMap)] + ); +}; + +},{"../../../types":119,"../../helpers/define-map":34}],59:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.check = t.isArrowFunctionExpression; + +exports.ArrowFunctionExpression = function (node) { + t.ensureBlock(node); + + node._aliasFunction = "arrow"; + node.expression = false; + node.type = "FunctionExpression"; + + return node; +}; + +},{"../../../types":119}],60:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +var visitor = { + enter: function (node, parent, scope, state) { + if (!t.isReferencedIdentifier(node, parent)) return; + + var declared = state.letRefs[node.name]; + if (!declared) return; + + // declared node is different in this scope + if (scope.getBindingIdentifier(node.name) !== declared) return; + + var assert = t.callExpression( + state.file.addHelper("temporal-assert-defined"), + [node, t.literal(node.name), state.file.addHelper("temporal-undefined")] + ); + + this.skip(); + + if (t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) { + if (parent._ignoreBlockScopingTDZ) return; + this.parentPath.node = t.sequenceExpression([assert, parent]); + } else { + return t.logicalExpression("&&", assert, node); + } + } +}; + +exports.optional = true; + +exports.Loop = +exports.Program = +exports.BlockStatement = function (node, parent, scope, file) { + var letRefs = node._letReferences; + if (!letRefs) return; + + var state = { + letRefs: letRefs, + file: file + }; + + scope.traverse(node, visitor, state); +}; + +},{"../../../types":119}],61:[function(require,module,exports){ +"use strict"; + +var traverse = require("../../../traversal"); +var object = require("../../../helpers/object"); +var util = require("../../../util"); +var t = require("../../../types"); +var values = require("lodash/object/values"); +var extend = require("lodash/object/extend"); + +exports.check = function (node) { + return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const"); +}; + +var isLet = function (node, parent) { + if (!t.isVariableDeclaration(node)) return false; + if (node._let) return true; + if (node.kind !== "let") return false; + + // https://github.com/babel/babel/issues/255 + if (isLetInitable(node, parent)) { + for (var i = 0; i < node.declarations.length; i++) { + var declar = node.declarations[i]; + declar.init = declar.init || t.identifier("undefined"); + } + } + + node._let = true; + node.kind = "var"; + return true; +}; + +var isLetInitable = function (node, parent) { + return !t.isFor(parent) || !t.isFor(parent, { left: node }); +}; + +var isVar = function (node, parent) { + return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent); +}; + +var standardizeLets = function (declars) { + for (var i = 0; i < declars.length; i++) { + delete declars[i]._let; + } +}; + +exports.VariableDeclaration = function (node, parent, scope, file) { + if (!isLet(node, parent)) return; + + if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) { + var nodes = [node]; + + for (var i = 0; i < node.declarations.length; i++) { + var decl = node.declarations[i]; + if (decl.init) { + var assign = t.assignmentExpression("=", decl.id, decl.init); + assign._ignoreBlockScopingTDZ = true; + nodes.push(t.expressionStatement(assign)); + } + decl.init = file.addHelper("temporal-undefined"); + } + + node._blockHoist = 2; + + return nodes; + } +}; + +exports.Loop = function (node, parent, scope, file) { + var init = node.left || node.init; + if (isLet(init, node)) { + t.ensureBlock(node); + node.body._letDeclarators = [init]; + } + var blockScoping = new BlockScoping(node, node.body, parent, scope, file); + blockScoping.run(); +}; + +exports.Program = +exports.BlockStatement = function (block, parent, scope, file) { + if (!t.isLoop(parent)) { + var blockScoping = new BlockScoping(false, block, parent, scope, file); + blockScoping.run(); + } +}; + +/** + * Description + * + * @param {Boolean|Node} loopParent + * @param {Node} block + * @param {Node} parent + * @param {Scope} scope + * @param {File} file + */ + +function BlockScoping(loopParent, block, parent, scope, file) { + this.loopParent = loopParent; + this.parent = parent; + this.scope = scope; + this.block = block; + this.file = file; + + this.outsideLetReferences = object(); + this.hasLetReferences = false; + this.letReferences = block._letReferences = object(); + this.body = []; +} + +/** + * Start the ball rolling. + */ + +BlockScoping.prototype.run = function () { + var block = this.block; + if (block._letDone) return; + block._letDone = true; + + var needsClosure = this.getLetReferences(); + + // this is a block within a `Function/Program` so we can safely leave it be + if (t.isFunction(this.parent) || t.isProgram(this.block)) return; + + // we can skip everything + if (!this.hasLetReferences) return; + + if (needsClosure) { + this.wrapClosure(); + } else { + this.remap(); + } +}; + +function replace(node, parent, scope, remaps) { + if (!t.isReferencedIdentifier(node, parent)) return; + + var remap = remaps[node.name]; + if (!remap) return; + + var ownBinding = scope.getBindingIdentifier(node.name); + if (ownBinding === remap.binding) { + node.name = remap.uid; + } else { + // scope already has it's own binding that doesn't + // match the one we have a stored replacement for + if (this) this.skip(); + } +} + +var replaceVisitor = { + enter: replace +}; + +function traverseReplace(node, parent, scope, remaps) { + replace(node, parent, scope, remaps); + scope.traverse(node, replaceVisitor, remaps); +} + +/** + * Description + */ + +BlockScoping.prototype.remap = function () { + var hasRemaps = false; + var letRefs = this.letReferences; + var scope = this.scope; + + // alright, so since we aren't wrapping this block in a closure + // we have to check if any of our let variables collide with + // those in upper scopes and then if they do, generate a uid + // for them and replace all references with it + var remaps = object(); + + for (var key in letRefs) { + // just an Identifier node we collected in `getLetReferences` + // this is the defining identifier of a declaration + var ref = letRefs[key]; + + if (scope.parentHasBinding(key) || scope.hasGlobal(key)) { + var uid = scope.generateUidIdentifier(ref.name).name; + ref.name = uid; + + hasRemaps = true; + remaps[key] = remaps[uid] = { + binding: ref, + uid: uid + }; + } + } + + if (!hasRemaps) return; + + // + + var loopParent = this.loopParent; + if (loopParent) { + traverseReplace(loopParent.right, loopParent, scope, remaps); + traverseReplace(loopParent.test, loopParent, scope, remaps); + traverseReplace(loopParent.update, loopParent, scope, remaps); + } + + scope.traverse(this.block, replaceVisitor, remaps); +}; + +/** + * Description + */ + +BlockScoping.prototype.wrapClosure = function () { + var block = this.block; + + var outsideRefs = this.outsideLetReferences; + + // remap loop heads with colliding variables + if (this.loopParent) { + for (var name in outsideRefs) { + var id = outsideRefs[name]; + + if (this.scope.hasGlobal(id.name)) { + delete outsideRefs[id.name]; + delete this.letReferences[id.name]; + + this.scope.rename(id.name); + + this.letReferences[id.name] = id; + outsideRefs[id.name] = id; + } + } + } + + // if we're inside of a for loop then we search to see if there are any + // `break`s, `continue`s, `return`s etc + this.has = this.checkLoop(); + + // hoist var references to retain scope + this.hoistVarDeclarations(); + + // turn outsideLetReferences into an array + var params = values(outsideRefs); + + // build the closure that we're going to wrap the block with + var fn = t.functionExpression(null, params, t.blockStatement(block.body)); + fn._aliasFunction = true; + + // replace the current block body with the one we're going to build + block.body = this.body; + + // build a call and a unique id that we can assign the return value to + var call = t.callExpression(fn, params); + var ret = this.scope.generateUidIdentifier("ret"); + + // handle generators + var hasYield = traverse.hasType(fn.body, this.scope, "YieldExpression", t.FUNCTION_TYPES); + if (hasYield) { + fn.generator = true; + call = t.yieldExpression(call, true); + } + + // handlers async functions + var hasAsync = traverse.hasType(fn.body, this.scope, "AwaitExpression", t.FUNCTION_TYPES); + if (hasAsync) { + fn.async = true; + call = t.awaitExpression(call, true); + } + + this.build(ret, call); +}; + +var letReferenceFunctionVisitor = { + enter: function (node, parent, scope, state) { + // not a direct reference + if (!t.isReferencedIdentifier(node, parent)) return; + + // this scope has a variable with the same name so it couldn't belong + // to our let scope + if (scope.hasOwnBinding(node.name)) return; + + // not a part of our scope + if (!state.letReferences[node.name]) return; + + state.closurify = true; + } +}; + +var letReferenceBlockVisitor = { + enter: function (node, parent, scope, state) { + if (t.isFunction(node)) { + scope.traverse(node, letReferenceFunctionVisitor, state); + return this.skip(); + } + } +}; + +/** + * Description + */ + +BlockScoping.prototype.getLetReferences = function () { + var block = this.block; + + var declarators = block._letDeclarators || []; + var declar; + + // + for (var i = 0; i < declarators.length; i++) { + declar = declarators[i]; + extend(this.outsideLetReferences, t.getBindingIdentifiers(declar)); + } + + // + if (block.body) { + for (i = 0; i < block.body.length; i++) { + declar = block.body[i]; + if (isLet(declar, block)) { + declarators = declarators.concat(declar.declarations); + } + } + } + + // + for (i = 0; i < declarators.length; i++) { + declar = declarators[i]; + var keys = t.getBindingIdentifiers(declar); + extend(this.letReferences, keys); + this.hasLetReferences = true; + } + + // no let references so we can just quit + if (!this.hasLetReferences) return; + + // set let references to plain var references + standardizeLets(declarators); + + var state = { + letReferences: this.letReferences, + closurify: false + }; + + // traverse through this block, stopping on functions and checking if they + // contain any local let references + this.scope.traverse(this.block, letReferenceBlockVisitor, state); + + return state.closurify; +}; + +var loopNodeTo = function (node) { + if (t.isBreakStatement(node)) { + return "break"; + } else if (t.isContinueStatement(node)) { + return "continue"; + } +}; + +var loopVisitor = { + enter: function (node, parent, scope, state) { + var replace; + + if (t.isLoop(node)) { + state.ignoreLabeless = true; + scope.traverse(node, loopVisitor, state); + state.ignoreLabeless = false; + } + + if (t.isFunction(node) || t.isLoop(node)) { + return this.skip(); + } + + var loopText = loopNodeTo(node); + + if (loopText) { + if (node.label) { + // we shouldn't be transforming this because it exists somewhere inside + if (state.innerLabels.indexOf(node.label.name) >= 0) { + return; + } + + loopText = loopText + "|" + node.label.name; + } else { + // we shouldn't be transforming these statements because + // they don't refer to the actual loop we're scopifying + if (state.ignoreLabeless) return; + + // break statements mean something different in this context + if (t.isBreakStatement(node) && t.isSwitchCase(parent)) return; + } + + state.hasBreakContinue = true; + state.map[loopText] = node; + replace = t.literal(loopText); + } + + if (t.isReturnStatement(node)) { + state.hasReturn = true; + replace = t.objectExpression([ + t.property("init", t.identifier("v"), node.argument || t.identifier("undefined")) + ]); + } + + if (replace) { + replace = t.returnStatement(replace); + return t.inherits(replace, node); + } + } +}; + +var loopLabelVisitor = { + enter: function (node, parent, scope, state) { + if (t.isLabeledStatement(node)) { + state.innerLabels.push(node.label.name); + } + } +}; + +/** + * If we're inside of a loop then traverse it and check if it has one of + * the following node types `ReturnStatement`, `BreakStatement`, + * `ContinueStatement` and replace it with a return value that we can track + * later on. + * + * @returns {Object} + */ + +BlockScoping.prototype.checkLoop = function () { + var state = { + hasBreakContinue: false, + ignoreLabeless: false, + innerLabels: [], + hasReturn: false, + isLoop: !!this.loopParent, + map: {} + }; + + this.scope.traverse(this.block, loopLabelVisitor, state); + this.scope.traverse(this.block, loopVisitor, state); + + return state; +}; + +var hoistVarDeclarationsVisitor = { + enter: function (node, parent, scope, self) { + if (t.isForStatement(node)) { + if (isVar(node.init, node)) { + node.init = t.sequenceExpression(self.pushDeclar(node.init)); + } + } else if (t.isFor(node)) { + if (isVar(node.left, node)) { + node.left = node.left.declarations[0].id; + } + } else if (isVar(node, parent)) { + return self.pushDeclar(node).map(t.expressionStatement); + } else if (t.isFunction(node)) { + return this.skip(); + } + } +}; + +/** + * Hoist all var declarations in this block to before it so they retain scope + * once we wrap everything in a closure. + */ + +BlockScoping.prototype.hoistVarDeclarations = function () { + traverse(this.block, hoistVarDeclarationsVisitor, this.scope, this); +}; + +/** + * Turn a `VariableDeclaration` into an array of `AssignmentExpressions` with + * their declarations hoisted to before the closure wrapper. + * + * @param {Node} node VariableDeclaration + * @returns {Array} + */ + +BlockScoping.prototype.pushDeclar = function (node) { + this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) { + return t.variableDeclarator(declar.id); + }))); + + var replace = []; + + for (var i = 0; i < node.declarations.length; i++) { + var declar = node.declarations[i]; + if (!declar.init) continue; + + var expr = t.assignmentExpression("=", declar.id, declar.init); + replace.push(t.inherits(expr, declar)); + } + + return replace; +}; + +/** + * Push the closure to the body. + * + * @param {Node} ret Identifier + * @param {Node} call CallExpression + */ + +BlockScoping.prototype.build = function (ret, call) { + var has = this.has; + if (has.hasReturn || has.hasBreakContinue) { + this.buildHas(ret, call); + } else { + this.body.push(t.expressionStatement(call)); + } +}; + +/** + * Description + * + * @param {Node} ret Identifier + * @param {Node} call CallExpression + */ + +BlockScoping.prototype.buildHas = function (ret, call) { + var body = this.body; + + body.push(t.variableDeclaration("var", [ + t.variableDeclarator(ret, call) + ])); + + var loopParent = this.loopParent; + var retCheck; + var has = this.has; + var cases = []; + + if (has.hasReturn) { + // typeof ret === "object" + retCheck = util.template("let-scoping-return", { + RETURN: ret + }); + } + + if (has.hasBreakContinue) { + if (!loopParent) { + throw new Error("Has no loop parent but we're trying to reassign breaks " + + "and continues, something is going wrong here."); + } + + for (var key in has.map) { + cases.push(t.switchCase(t.literal(key), [has.map[key]])); + } + + if (has.hasReturn) { + cases.push(t.switchCase(null, [retCheck])); + } + + if (cases.length === 1) { + var single = cases[0]; + body.push(this.file.attachAuxiliaryComment(t.ifStatement( + t.binaryExpression("===", ret, single.test), + single.consequent[0] + ))); + } else { + body.push(this.file.attachAuxiliaryComment(t.switchStatement(ret, cases))); + } + } else { + if (has.hasReturn) { + body.push(this.file.attachAuxiliaryComment(retCheck)); + } + } +}; + +},{"../../../helpers/object":24,"../../../traversal":114,"../../../types":119,"../../../util":121,"lodash/object/extend":295,"lodash/object/values":299}],62:[function(require,module,exports){ +"use strict"; + +var ReplaceSupers = require("../../helpers/replace-supers"); +var nameMethod = require("../../helpers/name-method"); +var defineMap = require("../../helpers/define-map"); +var messages = require("../../../messages"); +var util = require("../../../util"); +var t = require("../../../types"); + +exports.check = t.isClass; + +exports.ClassDeclaration = function (node, parent, scope, file) { + return new ClassTransformer(node, file, scope, true).run(); +}; + +exports.ClassExpression = function (node, parent, scope, file) { + if (!node.id) { + if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) { + // var o = { foo: class {} }; + node.id = parent.key; + } + + if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) { + // var foo = class {}; + node.id = parent.id; + } + } + + return new ClassTransformer(node, file, scope, false).run(); +}; + +/** + * Description + * + * @param {Node} node + * @param {File} file + * @param {Scope} scope + * @param {Boolean} isStatement + */ + +function ClassTransformer(node, file, scope, isStatement) { + this.isStatement = isStatement; + this.scope = scope; + this.node = node; + this.file = file; + + this.hasInstanceMutators = false; + this.hasStaticMutators = false; + + this.instanceMutatorMap = {}; + this.staticMutatorMap = {}; + this.hasConstructor = false; + this.className = node.id || scope.generateUidIdentifier("class"); + this.superName = node.superClass || t.identifier("Function"); + this.hasSuper = !!node.superClass; + this.isLoose = file.isLoose("es6.classes"); +} + +/** + * Description + * + * @returns {Array} + */ + +ClassTransformer.prototype.run = function () { + var superName = this.superName; + var className = this.className; + var classBody = this.node.body.body; + var file = this.file; + + // + + var body = this.body = []; + + var constructorBody = t.blockStatement([ + t.expressionStatement(t.callExpression(file.addHelper("class-call-check"), [ + t.thisExpression(), + className + ])) + ]); + + var constructor; + if (this.node.id) { + constructor = t.functionDeclaration(className, [], constructorBody); + body.push(constructor); + } else { + var constructorName = null; + // when a class has no parent and there is only a constructor or no body + // then the constructor is not wrapped in a closure and needs to be named + var containsOnlyConstructor = classBody.length === 1 && classBody[0].key.name === "constructor"; + if (!this.hasSuper && (classBody.length === 0 || containsOnlyConstructor)) { + constructorName = className; + } + + constructor = t.functionExpression(constructorName, [], constructorBody); + body.push(t.variableDeclaration("var", [ + t.variableDeclarator(className, constructor) + ])); + } + this.constructor = constructor; + + var closureParams = []; + var closureArgs = []; + + // + + if (this.hasSuper) { + closureArgs.push(superName); + + if (!t.isIdentifier(superName)) { + superName = this.scope.generateUidBasedOnNode(superName, this.file); + } + + closureParams.push(superName); + + this.superName = superName; + body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName]))); + } + + this.buildBody(); + + t.inheritsComments(body[0], this.node); + + var init; + + if (body.length === 1) { + // only a constructor so no need for a closure container + init = t.toExpression(constructor); + } else { + body.push(t.returnStatement(className)); + init = t.callExpression( + t.functionExpression(null, closureParams, t.blockStatement(body)), + closureArgs + ); + } + + if (this.isStatement) { + return t.variableDeclaration("let", [ + t.variableDeclarator(className, init) + ]); + } else { + return init; + } +}; + +/** + * Description + */ + +ClassTransformer.prototype.buildBody = function () { + var constructor = this.constructor; + var className = this.className; + var superName = this.superName; + var classBody = this.node.body.body; + var body = this.body; + + for (var i = 0; i < classBody.length; i++) { + var node = classBody[i]; + if (t.isMethodDefinition(node)) { + var replaceSupers = new ReplaceSupers({ + methodNode: node, + className: this.className, + superName: this.superName, + isStatic: node.static, + isLoose: this.isLoose, + scope: this.scope, + file: this.file + }, true); + replaceSupers.replace(); + + if ((!node.computed && t.isIdentifier(node.key, { name: "constructor" })) || t.isLiteral(node.key, { value: "constructor" })) { + this.pushConstructor(node); + } else { + this.pushMethod(node); + } + } else if (t.isPrivateDeclaration(node)) { + this.closure = true; + body.unshift(node); + } else if (t.isClassProperty(node)) { + this.pushProperty(node); + } + } + + // we have no constructor, we have a super, and the super doesn't appear to be falsy + if (!this.hasConstructor && this.hasSuper && !t.isFalsyExpression(superName)) { + var helperName = "class-super-constructor-call"; + if (this.isLoose) helperName += "-loose"; + constructor.body.body.push(util.template(helperName, { + CLASS_NAME: className, + SUPER_NAME: this.superName + }, true)); + } + + var instanceProps; + var staticProps; + + if (this.hasInstanceMutators) { + instanceProps = defineMap.build(this.instanceMutatorMap); + } + + if (this.hasStaticMutators) { + staticProps = defineMap.build(this.staticMutatorMap); + } + + if (instanceProps || staticProps) { + staticProps = staticProps || t.literal(null); + + var args = [className, staticProps]; + if (instanceProps) args.push(instanceProps); + + body.push(t.expressionStatement( + t.callExpression(this.file.addHelper("prototype-properties"), args) + )); + } +}; + +/** + * Push a method to its respective mutatorMap. + * + * @param {Node} node MethodDefinition + */ + +ClassTransformer.prototype.pushMethod = function (node) { + var methodName = node.key; + + var kind = node.kind; + + if (kind === "") { + nameMethod.property(node, this.file, this.scope); + + if (this.isLoose) { + // use assignments instead of define properties for loose classes + + var className = this.className; + if (!node.static) className = t.memberExpression(className, t.identifier("prototype")); + methodName = t.memberExpression(className, methodName, node.computed); + + var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value)); + t.inheritsComments(expr, node); + this.body.push(expr); + return; + } + + kind = "value"; + } + + var mutatorMap = this.instanceMutatorMap; + if (node.static) { + this.hasStaticMutators = true; + mutatorMap = this.staticMutatorMap; + } else { + this.hasInstanceMutators = true; + } + + defineMap.push(mutatorMap, methodName, kind, node.computed, node); + defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false); +}; + +/** + * Description + * + * @param {Node} node + */ + +ClassTransformer.prototype.pushProperty = function (node) { + if (!node.value) return; + + var key; + + if (node.static) { + key = t.memberExpression(this.className, node.key); + this.body.push( + t.expressionStatement(t.assignmentExpression("=", key, node.value)) + ); + } else { + key = t.memberExpression(t.thisExpression(), node.key); + this.constructor.body.body.unshift( + t.expressionStatement(t.assignmentExpression("=", key, node.value)) + ); + } +}; + +/** + * Replace the constructor body of our class. + * + * @param {Node} method MethodDefinition + */ + +ClassTransformer.prototype.pushConstructor = function (method) { + if (method.kind) { + throw this.file.errorWithNode(method, messages.get("classesIllegalConstructorKind")); + } + + var construct = this.constructor; + var fn = method.value; + + this.hasConstructor = true; + + t.inherits(construct, fn); + t.inheritsComments(construct, method); + + construct._ignoreUserWhitespace = true; + construct.params = fn.params; + construct.body.body = construct.body.body.concat(fn.body.body); +}; + +},{"../../../messages":27,"../../../types":119,"../../../util":121,"../../helpers/define-map":34,"../../helpers/name-method":36,"../../helpers/replace-supers":39}],63:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isVariableDeclaration(node, { kind: "const" }); +}; + +var visitor = { + enter: function (node, parent, scope, state) { + if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) { + var ids = t.getBindingIdentifiers(node); + + for (var name in ids) { + var id = ids[name]; + + var constant = state.constants[name]; + + // no constant exists + if (!constant) continue; + + var constantIdentifier = constant.identifier; + + // check if the assignment id matches the constant declaration id + // if it does then it was the id used to initially declare the + // constant so we can just ignore it + if (id === constantIdentifier) continue; + + // check if there's been a local binding that shadows this constant + if (!scope.bindingIdentifierEquals(name, constantIdentifier)) continue; + + throw state.file.errorWithNode(id, messages.get("readOnly", name)); + } + } else if (t.isScope(node, parent)) { + this.skip(); + } + } +}; + +exports.Scopable = function (node, parent, scope, file) { + scope.traverse(node, visitor, { + constants: scope.getAllBindingsOfKind("const"), + file: file + }); +}; + +exports.VariableDeclaration = function (node) { + if (node.kind === "const") node.kind = "let"; +}; + +},{"../../../messages":27,"../../../types":119}],64:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var t = require("../../../types"); + +exports.check = t.isPattern; + +function DestructuringTransformer(opts) { + this.blockHoist = opts.blockHoist; + this.operator = opts.operator; + this.nodes = opts.nodes; + this.scope = opts.scope; + this.file = opts.file; + this.kind = opts.kind; +} + +DestructuringTransformer.prototype.buildVariableAssignment = function (id, init) { + var op = this.operator; + if (t.isMemberExpression(id)) op = "="; + + var node; + + if (op) { + node = t.expressionStatement(t.assignmentExpression(op, id, init)); + } else { + node = t.variableDeclaration(this.kind, [ + t.variableDeclarator(id, init) + ]); + } + + node._blockHoist = this.blockHoist; + + return node; +}; + +DestructuringTransformer.prototype.buildVariableDeclaration = function (id, init) { + var declar = t.variableDeclaration("var", [ + t.variableDeclarator(id, init) + ]); + declar._blockHoist = this.blockHoist; + return declar; +}; + +DestructuringTransformer.prototype.push = function (id, init) { + if (t.isObjectPattern(id)) { + this.pushObjectPattern(id, init); + } else if (t.isArrayPattern(id)) { + this.pushArrayPattern(id, init); + } else if (t.isAssignmentPattern(id)) { + this.pushAssignmentPattern(id, init); + } else { + this.nodes.push(this.buildVariableAssignment(id, init)); + } +}; + +DestructuringTransformer.prototype.get = function () { + +}; + +DestructuringTransformer.prototype.pushAssignmentPattern = function (pattern, valueRef) { + // we need to assign the current value of the assignment to avoid evaluating + // it more than once + + var tempValueRef = this.scope.generateUidBasedOnNode(valueRef); + + var declar = t.variableDeclaration("var", [ + t.variableDeclarator(tempValueRef, valueRef) + ]); + declar._blockHoist = this.blockHoist; + this.nodes.push(declar); + + // + + this.nodes.push(this.buildVariableAssignment( + pattern.left, + t.conditionalExpression( + t.binaryExpression("===", tempValueRef, t.identifier("undefined")), + pattern.right, + tempValueRef + ) + )); +}; + +DestructuringTransformer.prototype.pushObjectSpread = function (pattern, objRef, spreadProp, spreadPropIndex) { + // get all the keys that appear in this object before the current spread + + var keys = []; + + for (var i = 0; i < pattern.properties.length; i++) { + var prop = pattern.properties[i]; + + // we've exceeded the index of the spread property to all properties to the + // right need to be ignored + if (i >= spreadPropIndex) break; + + // ignore other spread properties + if (t.isSpreadProperty(prop)) continue; + + var key = prop.key; + if (t.isIdentifier(key)) key = t.literal(prop.key.name); + keys.push(key); + } + + keys = t.arrayExpression(keys); + + // + + var value = t.callExpression(this.file.addHelper("object-without-properties"), [objRef, keys]); + this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value)); +}; + +DestructuringTransformer.prototype.pushObjectProperty = function (prop, propRef) { + if (t.isLiteral(prop.key)) prop.computed = true; + + var pattern = prop.value; + var objRef = t.memberExpression(propRef, prop.key, prop.computed); + + if (t.isPattern(pattern)) { + this.push(pattern, objRef); + } else { + this.nodes.push(this.buildVariableAssignment(pattern, objRef)); + } +}; + +DestructuringTransformer.prototype.pushObjectPattern = function (pattern, objRef) { + // https://github.com/babel/babel/issues/681 + + if (!pattern.properties.length) { + this.nodes.push(t.expressionStatement( + t.callExpression(this.file.addHelper("object-destructuring-empty"), [objRef]) + )); + } + + // if we have more than one properties in this pattern and the objectRef is a + // member expression then we need to assign it to a temporary variable so it's + // only evaluated once + + if (pattern.properties.length > 1 && t.isMemberExpression(objRef)) { + var temp = this.scope.generateUidBasedOnNode(objRef, this.file); + this.nodes.push(this.buildVariableDeclaration(temp, objRef)); + objRef = temp; + } + + // + + for (var i = 0; i < pattern.properties.length; i++) { + var prop = pattern.properties[i]; + if (t.isSpreadProperty(prop)) { + this.pushObjectSpread(pattern, objRef, prop, i); + } else { + this.pushObjectProperty(prop, objRef); + } + } +}; + +var hasRest = function (pattern) { + for (var i = 0; i < pattern.elements.length; i++) { + if (t.isRestElement(pattern.elements[i])) { + return true; + } + } + return false; +}; + +DestructuringTransformer.prototype.canUnpackArrayPattern = function (pattern, arr) { + // not an array so there's no way we can deal with this + if (!t.isArrayExpression(arr)) return false; + + // pattern has less elements than the array and doesn't have a rest so some + // elements wont be evaluated + if (pattern.elements.length > arr.elements.length) return; + if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false; + + // deopt on holes + for (var i = 0; i < pattern.elements.length; i++) { + if (!pattern.elements[i]) return false; + } + + return true; +}; + +DestructuringTransformer.prototype.pushUnpackedArrayPattern = function (pattern, arr) { + for (var i = 0; i < pattern.elements.length; i++) { + var elem = pattern.elements[i]; + if (t.isRestElement(elem)) { + this.push(elem.argument, t.arrayExpression(arr.elements.slice(i))); + } else { + this.push(elem, arr.elements[i]); + } + } +}; + +DestructuringTransformer.prototype.pushArrayPattern = function (pattern, arrayRef) { + if (!pattern.elements) return; + + // optimise basic array destructuring of an array expression + // + // we can't do this to a pattern of unequal size to it's right hand + // array expression as then there will be values that wont be evaluated + // + // eg: var [a, b] = [1, 2]; + + if (this.canUnpackArrayPattern(pattern, arrayRef)) { + return this.pushUnpackedArrayPattern(pattern, arrayRef); + } + + // if we have a rest then we need all the elements so don't tell + // `scope.toArray` to only get a certain amount + + var count = !hasRest(pattern) && pattern.elements.length; + + // so we need to ensure that the `arrayRef` is an array, `scope.toArray` will + // return a locally bound identifier if it's been inferred to be an array, + // otherwise it'll be a call to a helper that will ensure it's one + + var toArray = this.scope.toArray(arrayRef, count); + + if (t.isIdentifier(toArray)) { + // we've been given an identifier so it must have been inferred to be an + // array + arrayRef = toArray; + } else { + arrayRef = this.scope.generateUidBasedOnNode(arrayRef); + this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray)); + this.scope.assignTypeGeneric(arrayRef.name, "Array"); + } + + // + + for (var i = 0; i < pattern.elements.length; i++) { + var elem = pattern.elements[i]; + + // hole + if (!elem) continue; + + var elemRef; + + if (t.isRestElement(elem)) { + elemRef = this.scope.toArray(arrayRef); + + if (i > 0) { + elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")), [t.literal(i)]); + } + + // set the element to the rest element argument since we've dealt with it + // being a rest already + elem = elem.argument; + } else { + elemRef = t.memberExpression(arrayRef, t.literal(i), true); + } + + this.push(elem, elemRef); + } +}; + +DestructuringTransformer.prototype.init = function (pattern, ref) { + // trying to destructure a value that we can't evaluate more than once so we + // need to save it to a variable + + if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref) && !t.isIdentifier(ref)) { + var key = this.scope.generateUidBasedOnNode(ref); + this.nodes.push(this.buildVariableDeclaration(key, ref)); + ref = key; + } + + // + + this.push(pattern, ref); +}; + +exports.ForInStatement = +exports.ForOfStatement = function (node, parent, scope, file) { + var left = node.left; + + if (t.isPattern(left)) { + // for ({ length: k } in { abc: 3 }); + + var temp = scope.generateUidIdentifier("ref"); + + node.left = t.variableDeclaration("var", [ + t.variableDeclarator(temp) + ]); + + t.ensureBlock(node); + + node.body.body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(left, temp) + ])); + + return; + } + + if (!t.isVariableDeclaration(left)) return; + + var pattern = left.declarations[0].id; + if (!t.isPattern(pattern)) return; + + var key = scope.generateUidIdentifier("ref"); + node.left = t.variableDeclaration(left.kind, [ + t.variableDeclarator(key, null) + ]); + + var nodes = []; + + var destructuring = new DestructuringTransformer({ + kind: left.kind, + file: file, + scope: scope, + nodes: nodes + }); + + destructuring.init(pattern, key); + + t.ensureBlock(node); + + var block = node.body; + block.body = nodes.concat(block.body); +}; + +exports.Function = function (node, parent, scope, file) { + var nodes = []; + + var hasDestructuringTransformer = false; + + node.params = node.params.map(function (pattern, i) { + if (!t.isPattern(pattern)) return pattern; + + hasDestructuringTransformer = true; + var ref = scope.generateUidIdentifier("ref"); + + var destructuring = new DestructuringTransformer({ + blockHoist: node.params.length - i, + nodes: nodes, + scope: scope, + file: file, + kind: "var", + }); + destructuring.init(pattern, ref); + + return ref; + }); + + if (!hasDestructuringTransformer) return; + + t.ensureBlock(node); + + var block = node.body; + block.body = nodes.concat(block.body); +}; + +exports.CatchClause = function (node, parent, scope, file) { + var pattern = node.param; + if (!t.isPattern(pattern)) return; + + var ref = scope.generateUidIdentifier("ref"); + node.param = ref; + + var nodes = []; + + var destructuring = new DestructuringTransformer({ + kind: "let", + file: file, + scope: scope, + nodes: nodes + }); + destructuring.init(pattern, ref); + + node.body.body = nodes.concat(node.body.body); + + return node; +}; + +exports.ExpressionStatement = function (node, parent, scope, file) { + var expr = node.expression; + if (expr.type !== "AssignmentExpression") return; + if (!t.isPattern(expr.left)) return; + if (file.isConsequenceExpressionStatement(node)) return; + + var nodes = []; + + var ref = scope.generateUidIdentifier("ref"); + nodes.push(t.variableDeclaration("var", [ + t.variableDeclarator(ref, expr.right) + ])); + + var destructuring = new DestructuringTransformer({ + operator: expr.operator, + file: file, + scope: scope, + nodes: nodes + }); + destructuring.init(expr.left, ref); + + return nodes; +}; + +exports.AssignmentExpression = function (node, parent, scope, file) { + if (!t.isPattern(node.left)) return; + + var ref = scope.generateUidIdentifier("temp"); + scope.push({ + key: ref.name, + id: ref + }); + + var nodes = []; + nodes.push(t.assignmentExpression("=", ref, node.right)); + + var destructuring = new DestructuringTransformer({ + operator: node.operator, + file: file, + scope: scope, + nodes: nodes + }); + destructuring.init(node.left, ref); + + nodes.push(ref); + + return t.toSequenceExpression(nodes, scope); +}; + +var variableDeclarationHasPattern = function (node) { + for (var i = 0; i < node.declarations.length; i++) { + if (t.isPattern(node.declarations[i].id)) { + return true; + } + } + return false; +}; + +exports.VariableDeclaration = function (node, parent, scope, file) { + if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return; + if (!variableDeclarationHasPattern(node)) return; + + var nodes = []; + var declar; + + for (var i = 0; i < node.declarations.length; i++) { + declar = node.declarations[i]; + + var patternId = declar.init; + var pattern = declar.id; + + var destructuring = new DestructuringTransformer({ + nodes: nodes, + scope: scope, + kind: node.kind, + file: file + }); + + if (t.isPattern(pattern) && patternId) { + destructuring.init(pattern, patternId); + + if (+i !== node.declarations.length - 1) { + // we aren't the last declarator so let's just make the + // last transformed node inherit from us + t.inherits(nodes[nodes.length - 1], declar); + } + } else { + nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar)); + } + } + + if (!t.isProgram(parent) && !t.isBlockStatement(parent)) { + // https://github.com/babel/babel/issues/113 + // for (let [x] = [0]; false;) {} + + declar = null; + + for (i = 0; i < nodes.length; i++) { + node = nodes[i]; + declar = declar || t.variableDeclaration(node.kind, []); + + if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) { + throw file.errorWithNode(node, messages.get("invalidParentForThisNode")); + } + + declar.declarations = declar.declarations.concat(node.declarations); + } + + return declar; + } + + return nodes; +}; + +},{"../../../messages":27,"../../../types":119}],65:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var util = require("../../../util"); +var t = require("../../../types"); + +exports.check = t.isForOfStatement; + +exports.ForOfStatement = function (node, parent, scope, file) { + var callback = spec; + if (file.isLoose("es6.forOf")) callback = loose; + + var build = callback(node, parent, scope, file); + var declar = build.declar; + var loop = build.loop; + var block = loop.body; + + // inherit comments from the original loop + t.inheritsComments(loop, node); + + // ensure that it's a block so we can take all its statements + t.ensureBlock(node); + + // add the value declaration to the new loop body + if (declar) { + block.body.push(declar); + } + + // push the rest of the original loop body onto our new body + block.body = block.body.concat(node.body.body); + + t.inherits(loop, node); + + // todo: find out why this is necessary? #538 + loop._scopeInfo = node._scopeInfo; + + return loop; +}; + +var breakVisitor = { + enter: function (node, parent, scope, state) { + if (t.isLoop(node)) { + state.ignoreLabeless = true; + scope.traverse(node, breakVisitor, state); + state.ignoreLabeless = false; + return this.skip(); + } + + if (t.isBreakStatement(node)) { + if (!node.label && state.ignoreLabeless) return; + if (node.label && node.label.name !== state.label) return; + + var ret = t.expressionStatement( + t.callExpression(t.memberExpression(state.iteratorKey, t.identifier("return")), []) + ); + ret = state.wrapReturn(ret); + + this.skip(); + return [ret, node]; + } + } +}; + +var loose = function (node, parent, scope, file) { + var left = node.left; + var declar, id; + + if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) { + // for (i of test), for ({ i } of test) + id = left; + } else if (t.isVariableDeclaration(left)) { + // for (var i of test) + id = scope.generateUidIdentifier("ref"); + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(left.declarations[0].id, id) + ]); + } else { + throw file.errorWithNode(left, messages.get("unknownForHead", left.type)); + } + + var iteratorKey = scope.generateUidIdentifier("iterator"); + var isArrayKey = scope.generateUidIdentifier("isArray"); + + var loop = util.template("for-of-loose", { + LOOP_OBJECT: iteratorKey, + IS_ARRAY: isArrayKey, + OBJECT: node.right, + INDEX: scope.generateUidIdentifier("i"), + ID: id + }); + + if (!declar) { + // no declaration so we need to remove the variable declaration at the top of + // the for-of-loose template + loop.body.body.shift(); + } + + // + + scope.traverse(node, breakVisitor, { + iteratorKey: iteratorKey, + wrapReturn: function (node) { + return t.ifStatement( + t.logicalExpression( + "&&", + t.unaryExpression("!", isArrayKey, true), + t.memberExpression(iteratorKey, t.identifier("return") + ) + ), node); + }, + label: t.isLabeledStatement(parent) && parent.label.name + }); + + // + + return { + declar: declar, + loop: loop + }; +}; + +var spec = function (node, parent, scope, file) { + var left = node.left; + var declar; + + var stepKey = scope.generateUidIdentifier("step"); + var stepValue = t.memberExpression(stepKey, t.identifier("value")); + + if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) { + // for (i of test), for ({ i } of test) + declar = t.expressionStatement(t.assignmentExpression("=", left, stepValue)); + } else if (t.isVariableDeclaration(left)) { + // for (var i of test) + declar = t.variableDeclaration(left.kind, [ + t.variableDeclarator(left.declarations[0].id, stepValue) + ]); + } else { + throw file.errorWithNode(left, messages.get("unknownForHead", left.type)); + } + + // + + var iteratorKey = scope.generateUidIdentifier("iterator"); + + var loop = util.template("for-of", { + ITERATOR_KEY: iteratorKey, + STEP_KEY: stepKey, + OBJECT: node.right + }); + + // + + scope.traverse(node, breakVisitor, { + iteratorKey: iteratorKey, + wrapReturn: function (node) { + return t.ifStatement(t.memberExpression(iteratorKey, t.identifier("return")), node); + }, + label: t.isLabeledStatement(parent) && parent.label.name + }); + + // + + return { + declar: declar, + loop: loop + }; +}; + +},{"../../../messages":27,"../../../types":119,"../../../util":121}],66:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.check = require("../internal/modules").check; + +exports.ImportDeclaration = function (node, parent, scope, file) { + // flow type + if (node.isType) return; + + var nodes = []; + + if (node.specifiers.length) { + for (var i = 0; i < node.specifiers.length; i++) { + file.moduleFormatter.importSpecifier(node.specifiers[i], node, nodes, parent); + } + } else { + file.moduleFormatter.importDeclaration(node, nodes, parent); + } + + if (nodes.length === 1) { + // inherit `_blockHoist` - this is for `_blockHoist` in File.prototype.addImport + nodes[0]._blockHoist = node._blockHoist; + } + + return nodes; +}; + +exports.ExportDeclaration = function (node, parent, scope, file) { + // flow type + if (t.isTypeAlias(node.declaration)) return; + + var nodes = []; + var i; + + if (node.declaration) { + // make sure variable exports have an initializer + // this is done here to avoid duplicating it in the module formatters + if (t.isVariableDeclaration(node.declaration)) { + var declar = node.declaration.declarations[0]; + declar.init = declar.init || t.identifier("undefined"); + } + + file.moduleFormatter.exportDeclaration(node, nodes, parent); + } else if (node.specifiers) { + for (i = 0; i < node.specifiers.length; i++) { + file.moduleFormatter.exportSpecifier(node.specifiers[i], node, nodes, parent); + } + } + + if (node._blockHoist) { + for (i = 0; i < nodes.length; i++) { + nodes[i]._blockHoist = node._blockHoist; + } + } + + return nodes; +}; + +},{"../../../types":119,"../internal/modules":86}],67:[function(require,module,exports){ +"use strict"; + +var ReplaceSupers = require("../../helpers/replace-supers"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isIdentifier(node, { name: "super" }); +}; + +exports.Property = function (node, parent, scope, file) { + if (!node.method) return; + + var value = node.value; + var thisExpr = scope.generateUidIdentifier("this"); + + var replaceSupers = new ReplaceSupers({ + topLevelThisReference: thisExpr, + methodNode: node, + className: thisExpr, + isStatic: true, + scope: scope, + file: file + }); + + replaceSupers.replace(); + + if (replaceSupers.hasSuper) { + value.body.body.unshift( + t.variableDeclaration("var", [ + t.variableDeclarator(thisExpr, t.thisExpression()) + ]) + ); + } +}; + +},{"../../../types":119,"../../helpers/replace-supers":39}],68:[function(require,module,exports){ +"use strict"; + +var util = require("../../../util"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isFunction(node) && hasDefaults(node); +}; + +var hasDefaults = function (node) { + for (var i = 0; i < node.params.length; i++) { + if (!t.isIdentifier(node.params[i])) return true; + } + return false; +}; + +var iifeVisitor = { + enter: function (node, parent, scope, state) { + if (!t.isReferencedIdentifier(node, parent)) return; + if (!state.scope.hasOwnBinding(node.name)) return; + if (state.scope.bindingIdentifierEquals(node.name, node)) return; + + state.iife = true; + this.stop(); + } +}; + +exports.Function = function (node, parent, scope, file) { + if (!hasDefaults(node)) return; + + t.ensureBlock(node); + + var body = []; + + var argsIdentifier = t.identifier("arguments"); + argsIdentifier._ignoreAliasFunctions = true; + + var lastNonDefaultParam = 0; + + var state = { iife: false, scope: scope }; + + var pushDefNode = function (left, right, i) { + var defNode = util.template("default-parameter", { + VARIABLE_NAME: left, + DEFAULT_VALUE: right, + ARGUMENT_KEY: t.literal(i), + ARGUMENTS: argsIdentifier + }, true); + file.checkNode(defNode); + defNode._blockHoist = node.params.length - i; + body.push(defNode); + }; + + for (var i = 0; i < node.params.length; i++) { + var param = node.params[i]; + + if (!t.isAssignmentPattern(param)) { + if (!t.isRestElement(param)) { + lastNonDefaultParam = i + 1; + } + + if (!t.isIdentifier(param)) { + scope.traverse(param, iifeVisitor, state); + } + + if (file.transformers["es6.blockScopingTDZ"].canRun()) { + pushDefNode(param, t.identifier("undefined"), i); + } + + continue; + } + + var left = param.left; + var right = param.right; + + var placeholder = scope.generateUidIdentifier("x"); + placeholder._isDefaultPlaceholder = true; + node.params[i] = placeholder; + + if (!state.iife) { + if (t.isIdentifier(right) && scope.hasOwnBinding(right.name)) { + state.iife = true; + } else { + scope.traverse(right, iifeVisitor, state); + } + } + + pushDefNode(left, right, i); + } + + // we need to cut off all trailing default parameters + node.params = node.params.slice(0, lastNonDefaultParam); + + if (state.iife) { + var container = t.functionExpression(null, [], node.body, node.generator); + container._aliasFunction = true; + + body.push(t.returnStatement(t.callExpression(container, []))); + + node.body = t.blockStatement(body); + } else { + node.body.body = body.concat(node.body.body); + } +}; + +},{"../../../types":119,"../../../util":121}],69:[function(require,module,exports){ +"use strict"; + +var util = require("../../../util"); +var t = require("../../../types"); + +exports.check = t.isRestElement; + +var hasRest = function (node) { + return t.isRestElement(node.params[node.params.length - 1]); +}; + +exports.Function = function (node, parent, scope) { + if (!hasRest(node)) return; + + var rest = node.params.pop().argument; + + var argsId = t.identifier("arguments"); + + // otherwise `arguments` will be remapped in arrow functions + argsId._ignoreAliasFunctions = true; + + var start = t.literal(node.params.length); + var key = scope.generateUidIdentifier("key"); + var len = scope.generateUidIdentifier("len"); + + var arrKey = key; + var arrLen = len; + if (node.params.length) { + // this method has additional params, so we need to subtract + // the index of the current argument position from the + // position in the array that we want to populate + arrKey = t.binaryExpression("-", key, start); + + // we need to work out the size of the array that we're + // going to store all the rest parameters + // + // we need to add a check to avoid constructing the array + // with <0 if there are less arguments than params as it'll + // cause an error + arrLen = t.conditionalExpression( + t.binaryExpression(">", len, start), + t.binaryExpression("-", len, start), + t.literal(0) + ); + } + + // support patterns + if (t.isPattern(rest)) { + var pattern = rest; + rest = scope.generateUidIdentifier("ref"); + + // let the destructuring transformer handle this + var restDeclar = t.variableDeclaration("var", [ + t.variableDeclarator(pattern, rest) + ]); + + // retain evaluation position + restDeclar._blockHoist = node.params.length + 1; + + node.body.body.unshift(restDeclar); + } + + scope.assignTypeGeneric(rest.name, "Array"); + + var loop = util.template("rest", { + ARGUMENTS: argsId, + ARRAY_KEY: arrKey, + ARRAY_LEN: arrLen, + START: start, + ARRAY: rest, + KEY: key, + LEN: len, + }); + loop._blockHoist = node.params.length + 1; + node.body.body.unshift(loop); +}; + +},{"../../../types":119,"../../../util":121}],70:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.check = function (node) { + return t.isProperty(node) && node.computed; +}; + +exports.ObjectExpression = function (node, parent, scope, file) { + var hasComputed = false; + + for (var i = 0; i < node.properties.length; i++) { + hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); + if (hasComputed) break; + } + + if (!hasComputed) return; + + var initProps = []; + var objId = scope.generateUidBasedOnNode(parent); + + // + + var body = []; + var container = t.functionExpression(null, [], t.blockStatement(body)); + container._aliasFunction = true; + + // + + var callback = spec; + if (file.isLoose("es6.properties.computed")) callback = loose; + + var result = callback(node, body, objId, initProps, file); + if (result) return result; + + // + + body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(objId, t.objectExpression(initProps)) + ])); + + body.push(t.returnStatement(objId)); + + return t.callExpression(container, []); +}; + +var loose = function (node, body, objId) { + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i]; + + body.push(t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(objId, prop.key, prop.computed || t.isLiteral(prop.key)), + prop.value + ) + )); + } +}; + +var spec = function (node, body, objId, initProps, file) { + var props = node.properties; + var prop, key; + + // normalize key + + for (var i = 0; i < props.length; i++) { + prop = props[i]; + if (prop.kind !== "init") continue; + + key = prop.key; + + if (!prop.computed && t.isIdentifier(key)) { + prop.key = t.literal(key.name); + } + } + + // add all non-computed properties and `__proto__` properties to the initializer + + var broken = false; + + for (i = 0; i < props.length; i++) { + prop = props[i]; + + if (prop.computed) { + broken = true; + } + + if (prop.kind !== "init" || !broken || t.isLiteral(t.toComputedKey(prop, prop.key), { value: "__proto__" })) { + initProps.push(prop); + props[i] = null; + } + } + + // add a simple assignment for all Symbol member expressions due to symbol polyfill limitations + // otherwise use Object.defineProperty + + for (i = 0; i < props.length; i++) { + prop = props[i]; + if (!prop) continue; + + key = prop.key; + var bodyNode; + + if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) { + // { [Symbol.iterator]: "foo" } + bodyNode = t.assignmentExpression( + "=", + t.memberExpression(objId, key, true), + prop.value + ); + } else { + bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]); + } + + body.push(t.expressionStatement(bodyNode)); + } + + // only one node and it's a Object.defineProperty that returns the object + + if (body.length === 1) { + var first = body[0].expression; + + if (t.isCallExpression(first)) { + first.arguments[0] = t.objectExpression(initProps); + return first; + } + } +}; + +},{"../../../types":119}],71:[function(require,module,exports){ +"use strict"; + +var clone = require("lodash/lang/clone"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isProperty(node) && (node.method || node.shorthand); +}; + +exports.Property = function (node) { + if (node.method) { + node.method = false; + } + + if (node.shorthand) { + node.shorthand = false; + node.key = t.removeComments(clone(node.key)); + } +}; + +},{"../../../types":119,"lodash/lang/clone":280}],72:[function(require,module,exports){ +"use strict"; + +var includes = require("lodash/collection/includes"); +var t = require("../../../types"); + +exports.check = t.isSpreadElement; + +var getSpreadLiteral = function (spread, scope) { + return scope.toArray(spread.argument, true); +}; + +var hasSpread = function (nodes) { + for (var i = 0; i < nodes.length; i++) { + if (t.isSpreadElement(nodes[i])) { + return true; + } + } + return false; +}; + +var build = function (props, scope) { + var nodes = []; + + var _props = []; + + var push = function () { + if (!_props.length) return; + nodes.push(t.arrayExpression(_props)); + _props = []; + }; + + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (t.isSpreadElement(prop)) { + push(); + nodes.push(getSpreadLiteral(prop, scope)); + } else { + _props.push(prop); + } + } + + push(); + + return nodes; +}; + +exports.ArrayExpression = function (node, parent, scope) { + var elements = node.elements; + if (!hasSpread(elements)) return; + + var nodes = build(elements, scope); + var first = nodes.shift(); + + if (!t.isArrayExpression(first)) { + nodes.unshift(first); + first = t.arrayExpression([]); + } + + return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes); +}; + +exports.CallExpression = function (node, parent, scope) { + var args = node.arguments; + if (!hasSpread(args)) return; + + var contextLiteral = t.identifier("undefined"); + + node.arguments = []; + + var nodes; + if (args.length === 1 && args[0].argument.name === "arguments") { + nodes = [args[0].argument]; + } else { + nodes = build(args, scope); + } + + var first = nodes.shift(); + if (nodes.length) { + node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes)); + } else { + node.arguments.push(first); + } + + var callee = node.callee; + + if (t.isMemberExpression(callee)) { + var temp = scope.generateTempBasedOnNode(callee.object); + if (temp) { + callee.object = t.assignmentExpression("=", temp, callee.object); + contextLiteral = temp; + } else { + contextLiteral = callee.object; + } + t.appendToMemberExpression(callee, t.identifier("apply")); + } else { + node.callee = t.memberExpression(node.callee, t.identifier("apply")); + } + + node.arguments.unshift(contextLiteral); +}; + +exports.NewExpression = function (node, parent, scope, file) { + var args = node.arguments; + if (!hasSpread(args)) return; + + var nativeType = t.isIdentifier(node.callee) && includes(t.NATIVE_TYPE_NAMES, node.callee.name); + + var nodes = build(args, scope); + + if (nativeType) { + nodes.unshift(t.arrayExpression([t.literal(null)])); + } + + var first = nodes.shift(); + + if (nodes.length) { + args = t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes); + } else { + args = first; + } + + if (nativeType) { + return t.newExpression( + t.callExpression( + t.memberExpression(file.addHelper("bind"), t.identifier("apply")), + [node.callee, args] + ), + [] + ); + } else { + return t.callExpression(file.addHelper("apply-constructor"), [node.callee, args]); + } +}; + +},{"../../../types":119,"lodash/collection/includes":200}],73:[function(require,module,exports){ +"use strict"; + +var reduceRight = require("lodash/collection/reduceRight"); +var messages = require("../../../messages"); +var flatten = require("lodash/array/flatten"); +var util = require("../../../util"); +var map = require("lodash/collection/map"); +var t = require("../../../types"); + +function returnBlock(expr) { + return t.blockStatement([t.returnStatement(expr)]); +} + +function TailCallTransformer(node, scope, file) { + this.hasTailRecursion = false; + this.needsArguments = false; + this.setsArguments = false; + this.needsThis = false; + this.ownerId = node.id; + this.vars = []; + + this.scope = scope; + this.file = file; + this.node = node; +} + +TailCallTransformer.prototype.getArgumentsId = function () { + return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments"); +}; + +TailCallTransformer.prototype.getThisId = function () { + return this.thisId = this.thisId || this.scope.generateUidIdentifier("this"); +}; + +TailCallTransformer.prototype.getLeftId = function () { + return this.leftId = this.leftId || this.scope.generateUidIdentifier("left"); +}; + +TailCallTransformer.prototype.getFunctionId = function () { + return this.functionId = this.functionId || this.scope.generateUidIdentifier("function"); +}; + +TailCallTransformer.prototype.getAgainId = function () { + return this.againId = this.againId || this.scope.generateUidIdentifier("again"); +}; + +TailCallTransformer.prototype.getParams = function () { + var params = this.params; + + if (!params) { + params = this.node.params; + this.paramDecls = []; + + for (var i = 0; i < params.length; i++) { + var param = params[i]; + if (!param._isDefaultPlaceholder) { + this.paramDecls.push(t.variableDeclarator( + param, + params[i] = this.scope.generateUidIdentifier("x") + )); + } + } + } + + return this.params = params; +}; + +TailCallTransformer.prototype.hasDeopt = function () { + // check if the ownerId has been reassigned, if it has then it's not safe to + // perform optimisations + var ownerIdInfo = this.scope.getBindingInfo(this.ownerId.name); + return ownerIdInfo && ownerIdInfo.reassigned; +}; + +TailCallTransformer.prototype.run = function () { + var scope = this.scope; + var node = this.node; + + // only tail recursion can be optimized as for now, so we can skip anonymous + // functions entirely + var ownerId = this.ownerId; + if (!ownerId) return; + + // traverse the function and look for tail recursion + scope.traverse(node, firstPass, this); + + if (!this.hasTailRecursion) return; + + if (this.hasDeopt()) { + this.file.logDeopt(node, messages.get("tailCallReassignmentDeopt")); + return; + } + + // + + scope.traverse(node, secondPass, this); + + if (!this.needsThis || !this.needsArguments) { + scope.traverse(node, thirdPass, this); + } + + var body = t.ensureBlock(node).body; + + if (this.vars.length > 0) { + var declarations = flatten(map(this.vars, function (decl) { + return decl.declarations; + }, this)); + var statement = reduceRight(declarations, function (expr, decl) { + return t.assignmentExpression("=", decl.id, expr); + }, t.identifier("undefined")); + body.unshift(t.expressionStatement(statement)); + } + + var paramDecls = this.paramDecls; + if (paramDecls.length > 0) { + body.unshift(t.variableDeclaration("var", paramDecls)); + } + + body.unshift(t.expressionStatement( + t.assignmentExpression("=", this.getAgainId(), t.literal(false))) + ); + + node.body = util.template("tail-call-body", { + AGAIN_ID: this.getAgainId(), + THIS_ID: this.thisId, + ARGUMENTS_ID: this.argumentsId, + FUNCTION_ID: this.getFunctionId(), + BLOCK: node.body + }); + + var topVars = []; + + if (this.needsThis) { + topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression())); + } + + if (this.needsArguments || this.setsArguments) { + var decl = t.variableDeclarator(this.getArgumentsId()); + if (this.needsArguments) { + decl.init = t.identifier("arguments"); + } + topVars.push(decl); + } + + var leftId = this.leftId; + if (leftId) { + topVars.push(t.variableDeclarator(leftId)); + } + + if (topVars.length > 0) { + node.body.body.unshift(t.variableDeclaration("var", topVars)); + } +}; + +TailCallTransformer.prototype.subTransform = function (node) { + if (!node) return; + + var handler = this["subTransform" + node.type]; + if (handler) return handler.call(this, node); +}; + +TailCallTransformer.prototype.subTransformConditionalExpression = function (node) { + var callConsequent = this.subTransform(node.consequent); + var callAlternate = this.subTransform(node.alternate); + if (!callConsequent && !callAlternate) { + return; + } + + // if ternary operator had tail recursion in value, convert to optimized if-statement + node.type = "IfStatement"; + node.consequent = callConsequent ? t.toBlock(callConsequent) : returnBlock(node.consequent); + + if (callAlternate) { + node.alternate = t.isIfStatement(callAlternate) ? callAlternate : t.toBlock(callAlternate); + } else { + node.alternate = returnBlock(node.alternate); + } + + return [node]; +}; + +TailCallTransformer.prototype.subTransformLogicalExpression = function (node) { + // only call in right-value of can be optimized + var callRight = this.subTransform(node.right); + if (!callRight) return; + + // cache left value as it might have side-effects + var leftId = this.getLeftId(); + var testExpr = t.assignmentExpression( + "=", + leftId, + node.left + ); + + if (node.operator === "&&") { + testExpr = t.unaryExpression("!", testExpr); + } + + return [t.ifStatement(testExpr, returnBlock(leftId))].concat(callRight); +}; + +TailCallTransformer.prototype.subTransformSequenceExpression = function (node) { + var seq = node.expressions; + + // only last element can be optimized + var lastCall = this.subTransform(seq[seq.length - 1]); + if (!lastCall) { + return; + } + + // remove converted expression from sequence + // and convert to regular expression if needed + if (--seq.length === 1) { + node = seq[0]; + } + + return [t.expressionStatement(node)].concat(lastCall); +}; + +TailCallTransformer.prototype.subTransformCallExpression = function (node) { + var callee = node.callee, thisBinding, args; + + if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) { + switch (callee.property.name) { + case "call": + args = t.arrayExpression(node.arguments.slice(1)); + break; + + case "apply": + args = node.arguments[1] || t.identifier("undefined"); + break; + + default: + return; + } + + thisBinding = node.arguments[0]; + callee = callee.object; + } + + // only tail recursion can be optimized as for now + if (!t.isIdentifier(callee) || !this.scope.bindingIdentifierEquals(callee.name, this.ownerId)) { + return; + } + + this.hasTailRecursion = true; + + if (this.hasDeopt()) return; + + var body = []; + + if (!t.isThisExpression(thisBinding)) { + body.push(t.expressionStatement(t.assignmentExpression( + "=", + this.getThisId(), + thisBinding || t.identifier("undefined") + ))); + } + + if (!args) { + args = t.arrayExpression(node.arguments); + } + + var argumentsId = this.getArgumentsId(); + var params = this.getParams(); + + body.push(t.expressionStatement(t.assignmentExpression( + "=", + argumentsId, + args + ))); + + var i, param; + + if (t.isArrayExpression(args)) { + var elems = args.elements; + for (i = 0; i < elems.length && i < params.length; i++) { + param = params[i]; + var elem = elems[i] || (elems[i] = t.identifier("undefined")); + if (!param._isDefaultPlaceholder) { + elems[i] = t.assignmentExpression("=", param, elem); + } + } + } else { + this.setsArguments = true; + for (i = 0; i < params.length; i++) { + param = params[i]; + if (!param._isDefaultPlaceholder) { + body.push(t.expressionStatement(t.assignmentExpression( + "=", + param, + t.memberExpression(argumentsId, t.literal(i), true) + ))); + } + } + } + + body.push(t.expressionStatement( + t.assignmentExpression("=", this.getAgainId(), t.literal(true)) + )); + body.push(t.continueStatement(this.getFunctionId())); + + return body; +}; + +// looks for and replaces tail recursion calls +var firstPass = { + enter: function (node, parent, scope, state) { + if (t.isIfStatement(node)) { + if (t.isReturnStatement(node.alternate)) { + t.ensureBlock(node, "alternate"); + } + + if (t.isReturnStatement(node.consequent)) { + t.ensureBlock(node, "consequent"); + } + } else if (t.isReturnStatement(node)) { + this.skip(); + return state.subTransform(node.argument); + } else if (t.isTryStatement(parent)) { + if (node === parent.block) { + this.skip(); + } else if (parent.finalizer && node !== parent.finalizer) { + this.skip(); + } + } else if (t.isFunction(node)) { + this.skip(); + } else if (t.isVariableDeclaration(node)) { + this.skip(); + state.vars.push(node); + } + } +}; + +// hoists up function declarations, replaces `this` and `arguments` and marks +// them as needed +var secondPass = { + enter: function (node, parent, scope, state) { + if (t.isThisExpression(node)) { + state.needsThis = true; + return state.getThisId(); + } else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) { + state.needsArguments = true; + return state.getArgumentsId(); + } else if (t.isFunction(node)) { + this.skip(); + if (t.isFunctionDeclaration(node)) { + node = t.variableDeclaration("var", [ + t.variableDeclarator(node.id, t.toExpression(node)) + ]); + node._blockHoist = 2; + return node; + } + } + } +}; + +// optimizes recursion by removing `this` and `arguments` if they aren't used +var thirdPass = { + enter: function (node, parent, scope, state) { + if (!t.isExpressionStatement(node)) return; + + var expr = node.expression; + if (!t.isAssignmentExpression(expr)) return; + + if (!state.needsThis && expr.left === state.getThisId()) { + this.remove(); + } else if (!state.needsArguments && expr.left === state.getArgumentsId() && t.isArrayExpression(expr.right)) { + return map(expr.right.elements, function (elem) { + return t.expressionStatement(elem); + }); + } + } +}; + +exports.Function = function (node, parent, scope, file) { + var tailCall = new TailCallTransformer(node, scope, file); + tailCall.run(); +}; + +},{"../../../messages":27,"../../../types":119,"../../../util":121,"lodash/array/flatten":192,"lodash/collection/map":201,"lodash/collection/reduceRight":202}],74:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +var buildBinaryExpression = function (left, right) { + return t.binaryExpression("+", left, right); +}; + +exports.check = function (node) { + return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node); +}; + +exports.TaggedTemplateExpression = function (node, parent, scope, file) { + var args = []; + var quasi = node.quasi; + + var strings = []; + var raw = []; + + for (var i = 0; i < quasi.quasis.length; i++) { + var elem = quasi.quasis[i]; + strings.push(t.literal(elem.value.cooked)); + raw.push(t.literal(elem.value.raw)); + } + + strings = t.arrayExpression(strings); + raw = t.arrayExpression(raw); + + var templateName = "tagged-template-literal"; + if (file.isLoose("es6.templateLiterals")) templateName += "-loose"; + args.push(t.callExpression(file.addHelper(templateName), [strings, raw])); + + args = args.concat(quasi.expressions); + + return t.callExpression(node.tag, args); +}; + +exports.TemplateLiteral = function (node) { + var nodes = []; + var i; + + for (i = 0; i < node.quasis.length; i++) { + var elem = node.quasis[i]; + + nodes.push(t.literal(elem.value.cooked)); + + var expr = node.expressions.shift(); + if (expr) nodes.push(expr); + } + + if (nodes.length > 1) { + // remove redundant '' at the end of the expression + var last = nodes[nodes.length - 1]; + if (t.isLiteral(last, { value: "" })) nodes.pop(); + + var root = buildBinaryExpression(nodes.shift(), nodes.shift()); + + for (i = 0; i < nodes.length; i++) { + root = buildBinaryExpression(root, nodes[i]); + } + + return root; + } else { + return nodes[0]; + } +}; + +},{"../../../types":119}],75:[function(require,module,exports){ +"use strict"; + +var rewritePattern = require("regexpu/rewrite-pattern"); +var pull = require("lodash/array/pull"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isLiteral(node) && node.regex && node.regex.flags.indexOf("u") >= 0; +}; + +exports.Literal = function (node) { + var regex = node.regex; + if (!regex) return; + + var flags = regex.flags.split(""); + if (regex.flags.indexOf("u") < 0) return; + pull(flags, "u"); + + regex.pattern = rewritePattern(regex.pattern, regex.flags); + regex.flags = flags.join(""); +}; + +},{"../../../types":119,"lodash/array/pull":194,"regexpu/rewrite-pattern":320}],76:[function(require,module,exports){ +"use strict"; + +// https://github.com/zenparsing/es-abstract-refs + +var util = require("../../../util"); +var t = require("../../../types"); + +exports.experimental = true; + +var container = function (parent, call, ret, file) { + if (t.isExpressionStatement(parent) && !file.isConsequenceExpressionStatement(parent)) { + // we don't need to worry about return values + return call; + } else { + var exprs = []; + if (t.isSequenceExpression(call)) { + exprs = call.expressions; + } else { + exprs.push(call); + } + exprs.push(ret); + return t.sequenceExpression(exprs); + } +}; + +exports.AssignmentExpression = function (node, parent, scope, file) { + var left = node.left; + if (!t.isVirtualPropertyExpression(left)) return; + + var value = node.right; + var temp; + + // we need to return `node.right` + if (!t.isExpressionStatement(parent)) { + temp = scope.generateTempBasedOnNode(node.right); + if (temp) value = temp; + } + + if (node.operator !== "=") { + value = t.binaryExpression( + node.operator[0], + util.template("abstract-expression-get", { + PROPERTY: node.property, + OBJECT: node.object + }), + value + ); + } + + var call = util.template("abstract-expression-set", { + PROPERTY: left.property, + OBJECT: left.object, + VALUE: value + }); + + if (temp) { + call = t.sequenceExpression([ + t.assignmentExpression("=", temp, node.right), + call + ]); + } + + return container(parent, call, value, file); +}; + +exports.UnaryExpression = function (node, parent, scope, file) { + var arg = node.argument; + if (!t.isVirtualPropertyExpression(arg)) return; + if (node.operator !== "delete") return; + + var call = util.template("abstract-expression-delete", { + PROPERTY: arg.property, + OBJECT: arg.object + }); + + return container(parent, call, t.literal(true), file); +}; + +exports.CallExpression = function (node, parent, scope) { + var callee = node.callee; + if (!t.isVirtualPropertyExpression(callee)) return; + + var temp = scope.generateTempBasedOnNode(callee.object); + + var call = util.template("abstract-expression-call", { + PROPERTY: callee.property, + OBJECT: temp || callee.object + }); + + call.arguments = call.arguments.concat(node.arguments); + + if (temp) { + return t.sequenceExpression([ + t.assignmentExpression("=", temp, callee.object), + call + ]); + } else { + return call; + } +}; + +exports.VirtualPropertyExpression = function (node) { + return util.template("abstract-expression-get", { + PROPERTY: node.property, + OBJECT: node.object + }); +}; + +exports.PrivateDeclaration = function (node) { + return t.variableDeclaration("const", node.declarations.map(function (id) { + return t.variableDeclarator(id, t.newExpression(t.identifier("WeakMap"), [])); + })); +}; + +},{"../../../types":119,"../../../util":121}],77:[function(require,module,exports){ +"use strict"; + +var buildComprehension = require("../../helpers/build-comprehension"); +var traverse = require("../../../traversal"); +var util = require("../../../util"); +var t = require("../../../types"); + +exports.experimental = true; + +exports.ComprehensionExpression = function (node, parent, scope, file) { + var callback = array; + if (node.generator) callback = generator; + return callback(node, parent, scope, file); +}; + +var generator = function (node) { + var body = []; + var container = t.functionExpression(null, [], t.blockStatement(body), true); + container._aliasFunction = true; + + body.push(buildComprehension(node, function () { + return t.expressionStatement(t.yieldExpression(node.body)); + })); + + return t.callExpression(container, []); +}; + +var array = function (node, parent, scope, file) { + var uid = scope.generateUidBasedOnNode(parent, file); + + var container = util.template("array-comprehension-container", { + KEY: uid + }); + container.callee._aliasFunction = true; + + var block = container.callee.body; + var body = block.body; + + if (traverse.hasType(node, scope, "YieldExpression", t.FUNCTION_TYPES)) { + container.callee.generator = true; + container = t.yieldExpression(container, true); + } + + var returnStatement = body.pop(); + + body.push(buildComprehension(node, function () { + return util.template("array-push", { + STATEMENT: node.body, + KEY: uid + }, true); + })); + body.push(returnStatement); + + return container; +}; + +},{"../../../traversal":114,"../../../types":119,"../../../util":121,"../../helpers/build-comprehension":31}],78:[function(require,module,exports){ +"use strict"; + +// https://github.com/rwaldron/exponentiation-operator + +exports.experimental = true; + +var build = require("../../helpers/build-binary-assignment-operator-transformer"); +var t = require("../../../types"); + +var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow")); + +build(exports, { + operator: "**", + + build: function (left, right) { + return t.callExpression(MATH_POW, [left, right]); + } +}); + +},{"../../../types":119,"../../helpers/build-binary-assignment-operator-transformer":30}],79:[function(require,module,exports){ +"use strict"; + +// https://github.com/sebmarkbage/ecmascript-rest-spread + +var t = require("../../../types"); + +exports.experimental = true; + +exports.manipulateOptions = function (opts) { + if (opts.whitelist.length) opts.whitelist.push("es6.destructuring"); +}; + +var hasSpread = function (node) { + for (var i = 0; i < node.properties.length; i++) { + if (t.isSpreadProperty(node.properties[i])) { + return true; + } + } + return false; +}; + +exports.ObjectExpression = function (node, parent, scope, file) { + if (!hasSpread(node)) return; + + var args = []; + var props = []; + + var push = function () { + if (!props.length) return; + args.push(t.objectExpression(props)); + props = []; + }; + + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i]; + if (t.isSpreadProperty(prop)) { + push(); + args.push(prop.argument); + } else { + props.push(prop); + } + } + + push(); + + if (!t.isObjectExpression(args[0])) { + args.unshift(t.objectExpression([])); + } + + return t.callExpression(file.addHelper("extends"), args); +}; + +},{"../../../types":119}],80:[function(require,module,exports){ +module.exports = { + useStrict: require("./other/use-strict"), + + // this goes at the start so we only transform the original user code + "spec.functionName": require("./spec/function-name"), + + "validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"), + "validation.noForInOfAssignment": require("./validation/no-for-in-of-assignment"), + "validation.setters": require("./validation/setters"), + "validation.react": require("./validation/react"), + "spec.blockScopedFunctions": require("./spec/block-scoped-functions"), + + // needs to be before `_aliasFunction` + "es6.arrowFunctions": require("./es6/arrow-functions"), + + "playground.malletOperator": require("./playground/mallet-operator"), + "playground.methodBinding": require("./playground/method-binding"), + "playground.memoizationOperator": require("./playground/memoization-operator"), + "playground.objectGetterMemoization": require("./playground/object-getter-memoization"), + + reactCompat: require("./other/react-compat"), + flow: require("./other/flow"), + react: require("./other/react"), + + _modules: require("./internal/modules"), + + // needs to be before `regenerator` due to generator comprehensions + // needs to be before `_aliasFunction` + "es7.comprehensions": require("./es7/comprehensions"), + + "es6.classes": require("./es6/classes"), + + asyncToGenerator: require("./other/async-to-generator"), + bluebirdCoroutines: require("./other/bluebird-coroutines"), + + "es6.objectSuper": require("./es6/object-super"), + "es7.objectRestSpread": require("./es7/object-rest-spread"), + "es7.exponentiationOperator": require("./es7/exponentiation-operator"), + "es6.templateLiterals": require("./es6/template-literals"), + + "es5.properties.mutators": require("./es5/properties.mutators"), + "es6.properties.shorthand": require("./es6/properties.shorthand"), + + // needs to be before `_aliasFunction` due to define property closure + "es6.properties.computed": require("./es6/properties.computed"), + + "es6.forOf": require("./es6/for-of"), + + "es6.unicodeRegex": require("./es6/unicode-regex"), + "es7.abstractReferences": require("./es7/abstract-references"), + + "es6.constants": require("./es6/constants"), + + // needs to be before `es6.parameters.default` as default parameters will destroy the rest param + "es6.parameters.rest": require("./es6/parameters.rest"), + + // needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one + "es6.spread": require("./es6/spread"), + + // needs to be before `es6.blockScoping` as default parameters have a TDZ + "es6.parameters.default": require("./es6/parameters.default"), + + // needs to be before `es6.blockScoping` as let variables may be produced + "es6.destructuring": require("./es6/destructuring"), + + // needs to be before `_aliasFunction` due to block scopes sometimes being wrapped in a + // closure + "es6.blockScoping": require("./es6/block-scoping"), + + // needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks + "es6.blockScopingTDZ": require("./es6/block-scoping-tdz"), + + // needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure + // identifiers in parameters and variable declarators + "es6.tailCall": require("./es6/tail-call"), + + regenerator: require("./other/regenerator"), + + // needs to be after `regenerator` due to needing `regeneratorRuntime` references + // needs to be after `es6.forOf` due to needing `Symbol.iterator` references + // needs to be before `es6.modules` due to dynamic imports + runtime: require("./other/runtime"), + + // needs to be before `_blockHoist` due to function hoisting etc + "es6.modules": require("./es6/modules"), + + _blockHoist: require("./internal/block-hoist"), + + "spec.protoToAssign": require("./spec/proto-to-assign"), + + _declarations: require("./internal/declarations"), + + _aliasFunctions: require("./internal/alias-functions"), + + "spec.typeofSymbol": require("./spec/typeof-symbol"), + "spec.undefinedToVoid": require("./spec/undefined-to-void"), + + _useStrict: require("./internal/use-strict"), + _moduleFormatter: require("./internal/module-formatter"), + + "es3.propertyLiterals": require("./es3/property-literals"), + "es3.memberExpressionLiterals": require("./es3/member-expression-literals"), + + "minification.removeDebugger": require("./minification/remove-debugger"), + "minification.removeConsoleCalls": require("./minification/remove-console-calls"), + "minification.deadCodeElimination": require("./minification/dead-code-elimination"), + "minification.renameLocalVariables": require("./minification/rename-local-variables"), + + _cleanUp: require("./internal/cleanup") +}; + +},{"./es3/member-expression-literals":56,"./es3/property-literals":57,"./es5/properties.mutators":58,"./es6/arrow-functions":59,"./es6/block-scoping":61,"./es6/block-scoping-tdz":60,"./es6/classes":62,"./es6/constants":63,"./es6/destructuring":64,"./es6/for-of":65,"./es6/modules":66,"./es6/object-super":67,"./es6/parameters.default":68,"./es6/parameters.rest":69,"./es6/properties.computed":70,"./es6/properties.shorthand":71,"./es6/spread":72,"./es6/tail-call":73,"./es6/template-literals":74,"./es6/unicode-regex":75,"./es7/abstract-references":76,"./es7/comprehensions":77,"./es7/exponentiation-operator":78,"./es7/object-rest-spread":79,"./internal/alias-functions":81,"./internal/block-hoist":82,"./internal/cleanup":83,"./internal/declarations":84,"./internal/module-formatter":85,"./internal/modules":86,"./internal/use-strict":87,"./minification/dead-code-elimination":88,"./minification/remove-console-calls":89,"./minification/remove-debugger":90,"./minification/rename-local-variables":91,"./other/async-to-generator":92,"./other/bluebird-coroutines":93,"./other/flow":94,"./other/react":96,"./other/react-compat":95,"./other/regenerator":97,"./other/runtime":98,"./other/use-strict":99,"./playground/mallet-operator":100,"./playground/memoization-operator":101,"./playground/method-binding":102,"./playground/object-getter-memoization":103,"./spec/block-scoped-functions":104,"./spec/function-name":105,"./spec/proto-to-assign":106,"./spec/typeof-symbol":107,"./spec/undefined-to-void":108,"./validation/no-for-in-of-assignment":109,"./validation/react":110,"./validation/setters":111,"./validation/undeclared-variable-check":112}],81:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +var functionChildrenVisitor = { + enter: function (node, parent, scope, state) { + if (t.isFunction(node) && !node._aliasFunction) { + return this.skip(); + } + + if (node._ignoreAliasFunctions) return this.skip(); + + var getId; + + if (t.isIdentifier(node) && node.name === "arguments") { + getId = state.getArgumentsId; + } else if (t.isThisExpression(node)) { + getId = state.getThisId; + } else { + return; + } + + if (t.isReferenced(node, parent)) return getId(); + } +}; + +var functionVisitor = { + enter: function (node, parent, scope, state) { + if (!node._aliasFunction) { + if (t.isFunction(node)) { + // stop traversal of this node as it'll be hit again by this transformer + return this.skip(); + } else { + return; + } + } + + // traverse all child nodes of this function and find `arguments` and `this` + scope.traverse(node, functionChildrenVisitor, state); + + return this.skip(); + } +}; + +var go = function (getBody, node, scope) { + var argumentsId; + var thisId; + + var state = { + getArgumentsId: function () { + return argumentsId = argumentsId || scope.generateUidIdentifier("arguments"); + }, + getThisId: function () { + return thisId = thisId || scope.generateUidIdentifier("this"); + } + }; + + // traverse the function and find all alias functions so we can alias + // `arguments` and `this` if necessary + scope.traverse(node, functionVisitor, state); + + var body; + + var pushDeclaration = function (id, init) { + body = body || getBody(); + body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(id, init) + ])); + }; + + if (argumentsId) { + pushDeclaration(argumentsId, t.identifier("arguments")); + } + + if (thisId) { + pushDeclaration(thisId, t.thisExpression()); + } +}; + +exports.Program = function (node, parent, scope) { + go(function () { + return node.body; + }, node, scope); +}; + +exports.FunctionDeclaration = +exports.FunctionExpression = function (node, parent, scope) { + go(function () { + t.ensureBlock(node); + return node.body.body; + }, node, scope); +}; + +},{"../../../types":119}],82:[function(require,module,exports){ +"use strict"; + +var groupBy = require("lodash/collection/groupBy"); +var flatten = require("lodash/array/flatten"); +var values = require("lodash/object/values"); + +// Priority: +// +// - 0 We want this to be at the **very** bottom +// - 1 Default node position +// - 2 Priority over normal nodes +// - 3 We want this to be at the **very** top + +exports.BlockStatement = +exports.Program = { + exit: function (node) { + var hasChange = false; + for (var i = 0; i < node.body.length; i++) { + var bodyNode = node.body[i]; + if (bodyNode && bodyNode._blockHoist != null) hasChange = true; + } + if (!hasChange) return; + + var nodePriorities = groupBy(node.body, function (bodyNode) { + var priority = bodyNode._blockHoist; + if (priority == null) priority = 1; + if (priority === true) priority = 2; + return priority; + }); + + node.body = flatten(values(nodePriorities).reverse()); + } +}; + +},{"lodash/array/flatten":192,"lodash/collection/groupBy":199,"lodash/object/values":299}],83:[function(require,module,exports){ +exports.SequenceExpression = function (node) { + if (node.expressions.length === 1) { + return node.expressions[0]; + } +}; + +},{}],84:[function(require,module,exports){ +"use strict"; + +var useStrict = require("../../helpers/use-strict"); +var t = require("../../../types"); + +exports.secondPass = true; + +exports.BlockStatement = +exports.Program = function (node, parent, scope, file) { + if (!node._declarations) return; + + useStrict.wrap(node, function () { + var kinds = {}; + var kind; + + for (var i in node._declarations) { + var declar = node._declarations[i]; + + kind = declar.kind || "var"; + var declarNode = t.variableDeclarator(declar.id, declar.init); + + if (declar.init) { + node.body.unshift(file.attachAuxiliaryComment(t.variableDeclaration(kind, [declarNode]))); + } else { + kinds[kind] = kinds[kind] || []; + kinds[kind].push(declarNode); + } + } + + for (kind in kinds) { + node.body.unshift(file.attachAuxiliaryComment(t.variableDeclaration(kind, kinds[kind]))); + } + + node._declarations = null; + }); +}; + +},{"../../../types":119,"../../helpers/use-strict":40}],85:[function(require,module,exports){ +"use strict"; + +var useStrict = require("../../helpers/use-strict"); + +exports.Program = function (program, parent, scope, file) { + if (!file.transformers["es6.modules"].canRun()) return; + + useStrict.wrap(program, function () { + program.body = file.dynamicImports.concat(program.body); + }); + + if (file.moduleFormatter.transform) { + file.moduleFormatter.transform(program); + } +}; + +},{"../../helpers/use-strict":40}],86:[function(require,module,exports){ +"use strict"; + +// in this transformer we have to split up classes and function declarations +// from their exports. why? because sometimes we need to replace classes with +// nodes that aren't allowed in the same contexts. also, if you're exporting +// a generator function as a default then regenerator will destroy the export +// declaration and leave a variable declaration in it's place... yeah, handy. + +var t = require("../../../types"); + +var resolveModuleSource = function (node, parent, scope, file) { + var resolveModuleSource = file.opts.resolveModuleSource; + if (node.source && resolveModuleSource) { + node.source.value = resolveModuleSource(node.source.value); + } +}; + +exports.check = function (node) { + return t.isImportDeclaration(node) || t.isExportDeclaration(node); +}; + +exports.ImportDeclaration = resolveModuleSource; + +exports.ExportDeclaration = function (node, parent, scope) { + resolveModuleSource.apply(null, arguments); + + // flow type + if (node.isType) return; + + var declar = node.declaration; + + if (node.default) { + if (t.isClassDeclaration(declar)) { + node.declaration = declar.id; + return [declar, node]; + } else if (t.isClassExpression(declar)) { + var temp = scope.generateUidIdentifier("default"); + declar = t.variableDeclaration("var", [ + t.variableDeclarator(temp, declar) + ]); + node.declaration = temp; + return [declar, node]; + } else if (t.isFunctionDeclaration(declar)) { + node._blockHoist = 2; + node.declaration = declar.id; + return [declar, node]; + } + } else { + if (t.isFunctionDeclaration(declar)) { + node.specifiers = [t.importSpecifier(declar.id, declar.id)]; + node.declaration = null; + node._blockHoist = 2; + return [declar, node]; + } + } +}; + +},{"../../../types":119}],87:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.Program = function (program, parent, scope, file) { + if (file.transformers.useStrict.canRun()) { + program.body.unshift(t.expressionStatement(t.literal("use strict"))); + } +}; + +},{"../../../types":119}],88:[function(require,module,exports){ +var t = require("../../../types"); + +exports.optional = true; + +exports.ExpressionStatement = function (node) { + // remove consequence-less expressions such as local variables and literals + // note: will remove directives + // + // var foo = true; foo; -> var foo = true; + // "foo"; -> + // + + var expr = node.expression; + if (t.isLiteral(expr) || (t.isIdentifier(node) && t.hasBinding(node.name))) { + this.remove(); + } +}; + +exports.IfStatement = { + exit: function (node) { + // todo: in scenarios where we can just return the consequent or + // alternate we should drop the block statement if it contains no + // block scoped variables + + var consequent = node.consequent; + var alternate = node.alternate; + var test = node.test; + + // we can check if a test will be truthy 100% and if so then we can inline + // the consequent and completely ignore the alternate + // + // if (true) { foo; } -> { foo; } + // if ("foo") { foo; } -> { foo; } + // + + if (t.isLiteral(test) && test.value) { + return consequent; + } + + // we can check if a test will be falsy 100% and if so we can inline the + // alternate if there is one and completely remove the consequent + // + // if ("") { bar; } else { foo; } -> { foo; } + // if ("") { bar; } -> + // + + if (t.isFalsyExpression(test)) { + if (alternate) { + return alternate; + } else { + return this.remove(); + } + } + + // remove alternate blocks that are empty + // + // if (foo) { foo; } else {} -> if (foo) { foo; } + // + + if (t.isBlockStatement(alternate) && !alternate.body.length) { + alternate = node.alternate = null; + } + + // if the consequent block is empty turn alternate blocks into a consequent + // and flip the test + // + // if (foo) {} else { bar; } -> if (!foo) { bar; } + // + + if (t.blockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) { + node.consequent = node.alternate; + node.alternate = null; + node.test = t.unaryExpression("!", test, true); + } + } +}; + +},{"../../../types":119}],89:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +var isConsole = t.buildMatchMemberExpression("console", true); + +exports.optional = true; + +exports.CallExpression = function (node, parent) { + if (isConsole(node.callee)) { + if (t.isExpressionStatement(parent)) { + this.parentPath.remove(); + } else { + this.remove(); + } + } +}; + +},{"../../../types":119}],90:[function(require,module,exports){ +var t = require("../../../types"); + +exports.optional = true; + +exports.ExpressionStatement = function (node) { + if (t.isIdentifier(node.expression, { name: "debugger" })) { + this.remove(); + } +}; + +},{"../../../types":119}],91:[function(require,module,exports){ +//var t = require("../../../types"); + +exports.optional = true; + +exports.Scopable = function () { + //for (var name in scope.bindings) { + // scope.rename(name, scope.generateUidIdentifier("a").name); + //} +}; + +},{}],92:[function(require,module,exports){ +"use strict"; + +var remapAsyncToGenerator = require("../../helpers/remap-async-to-generator"); +var bluebirdCoroutines = require("./bluebird-coroutines"); + +exports.optional = true; + +exports.manipulateOptions = bluebirdCoroutines.manipulateOptions; + +exports.Function = function (node, parent, scope, file) { + if (!node.async || node.generator) return; + + return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope); +}; + +},{"../../helpers/remap-async-to-generator":38,"./bluebird-coroutines":93}],93:[function(require,module,exports){ +"use strict"; + +var remapAsyncToGenerator = require("../../helpers/remap-async-to-generator"); +var t = require("../../../types"); + +exports.manipulateOptions = function (opts) { + opts.experimental = true; + opts.blacklist.push("regenerator"); +}; + +exports.optional = true; + +exports.Function = function (node, parent, scope, file) { + if (!node.async || node.generator) return; + + return remapAsyncToGenerator( + node, + t.memberExpression(file.addImport("bluebird", null, true), t.identifier("coroutine")), + scope + ); +}; + +},{"../../../types":119,"../../helpers/remap-async-to-generator":38}],94:[function(require,module,exports){ +var t = require("../../../types"); + +exports.TypeCastExpression = function (node) { + return node.expression; +}; + +exports.ImportDeclaration = function (node) { + if (node.isType) this.remove(); +}; + +exports.ExportDeclaration = function (node) { + if (t.isTypeAlias(node.declaration)) this.remove(); +}; + +},{"../../../types":119}],95:[function(require,module,exports){ +"use strict"; + +var react = require("../../helpers/react"); +var t = require("../../../types"); + +exports.manipulateOptions = function (opts) { + opts.blacklist.push("react"); +}; + +exports.optional = true; + +require("../../helpers/build-react-transformer")(exports, { + pre: function (state) { + state.callee = state.tagExpr; + }, + + post: function (state) { + if (react.isCompatTag(state.tagName)) { + state.call = t.callExpression( + t.memberExpression( + t.memberExpression(t.identifier("React"), t.identifier("DOM")), + state.tagExpr, + t.isLiteral(state.tagExpr) + ), + state.args + ); + } + } +}); + +},{"../../../types":119,"../../helpers/build-react-transformer":33,"../../helpers/react":37}],96:[function(require,module,exports){ +"use strict"; + +var react = require("../../helpers/react"); +var t = require("../../../types"); + +var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/; + +exports.Program = function (node, parent, scope, file) { + var id = "React.createElement"; + + for (var i = 0; i < file.ast.comments.length; i++) { + var comment = file.ast.comments[i]; + var matches = JSX_ANNOTATION_REGEX.exec(comment.value); + if (matches) { + id = matches[1]; + if (id === "React.DOM") { + throw file.errorWithNode(comment, "The @jsx React.DOM pragma has been deprecated as of React 0.12"); + } else { + break; + } + } + } + + file.set("jsxIdentifier", id.split(".").map(t.identifier).reduce(function (object, property) { + return t.memberExpression(object, property); + })); +}; + +require("../../helpers/build-react-transformer")(exports, { + pre: function (state) { + var tagName = state.tagName; + var args = state.args; + if (react.isCompatTag(tagName)) { + args.push(t.literal(tagName)); + } else { + args.push(state.tagExpr); + } + }, + + post: function (state, file) { + state.callee = file.get("jsxIdentifier"); + } +}); + +},{"../../../types":119,"../../helpers/build-react-transformer":33,"../../helpers/react":37}],97:[function(require,module,exports){ +"use strict"; + +var regenerator = require("regenerator-babel"); +var t = require("../../../types"); + +exports.check = function (node) { + return t.isFunction(node) && (node.async || node.generator); +}; + +exports.Program = { + enter: function (ast) { + regenerator.transform(ast); + this.stop(); + } +}; + +},{"../../../types":119,"regenerator-babel":312}],98:[function(require,module,exports){ +"use strict"; + +var includes = require("lodash/collection/includes"); +var util = require("../../../util"); +var core = require("core-js/library"); +var has = require("lodash/object/has"); +var t = require("../../../types"); + +var isSymboliterator = t.buildMatchMemberExpression("Symbol.iterator"); + +var coreHas = function (node) { + return node.name !== "_" && has(core, node.name); +}; + +var ALIASABLE_CONSTRUCTORS = [ + "Symbol", + "Promise", + "Map", + "WeakMap", + "Set", + "WeakSet" +]; + +var astVisitor = { + enter: function (node, parent, scope, file) { + var prop; + + if (t.isMemberExpression(node) && t.isReferenced(node, parent)) { + // Array.from -> _core.Array.from + var obj = node.object; + prop = node.property; + + if (!t.isReferenced(obj, node)) return; + + if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBindingIdentifier(obj.name)) { + this.skip(); + return t.prependToMemberExpression(node, file.get("coreIdentifier")); + } + } else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && includes(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBindingIdentifier(node.name)) { + // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise + return t.memberExpression(file.get("coreIdentifier"), node); + } else if (t.isCallExpression(node)) { + // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) + + var callee = node.callee; + if (node.arguments.length) return false; + + if (!t.isMemberExpression(callee)) return false; + if (!callee.computed) return false; + + prop = callee.property; + if (!isSymboliterator(prop)) return false; + + return util.template("corejs-iterator", { + CORE_ID: file.get("coreIdentifier"), + VALUE: callee.object + }); + } else if (t.isBinaryExpression(node)) { + // Symbol.iterator in arr -> core.$for.isIterable(arr) + + if (node.operator !== "in") return; + + var left = node.left; + if (!isSymboliterator(left)) return; + + return util.template("corejs-is-iterator", { + CORE_ID: file.get("coreIdentifier"), + VALUE: node.right + }); + } + } +}; + +exports.optional = true; + +exports.manipulateOptions = function (opts) { + if (opts.whitelist.length) opts.whitelist.push("es6.modules"); +}; + +exports.Program = function (node, parent, scope, file) { + scope.traverse(node, astVisitor, file); +}; + +exports.pre = function (file) { + file.setDynamic("helpersNamespace", function () { + return file.addImport("babel-runtime/helpers", "babelHelpers"); + }); + + file.setDynamic("coreIdentifier", function () { + return file.addImport("babel-runtime/core-js", "core"); + }); + + file.setDynamic("regeneratorIdentifier", function () { + return file.addImport("babel-runtime/regenerator", "regeneratorRuntime"); + }); +}; + +exports.Identifier = function (node, parent, scope, file) { + if (t.isReferencedIdentifier(node, parent, { name: "regeneratorRuntime" })) { + return file.get("regeneratorIdentifier"); + } +}; + +},{"../../../types":119,"../../../util":121,"core-js/library":172,"lodash/collection/includes":200,"lodash/object/has":296}],99:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var t = require("../../../types"); + +exports.Program = function (program) { + var first = program.body[0]; + if (t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" })) { + program.body.shift(); + } +}; + +exports.FunctionDeclaration = +exports.FunctionExpression = function () { + this.skip(); +}; + +exports.ThisExpression = function () { + return t.identifier("undefined"); +}; + +exports.CallExpression = function (node, parent, scope, file) { + if (t.isIdentifier(node.callee, { name: "eval" })) { + throw file.errorWithNode(node, messages.get("evalInStrictMode")); + } +}; + +},{"../../../messages":27,"../../../types":119}],100:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var build = require("../../helpers/build-conditional-assignment-operator-transformer"); +var t = require("../../../types"); + +exports.playground = true; + +build(exports, { + is: function (node, file) { + var is = t.isAssignmentExpression(node) && node.operator === "||="; + if (is) { + var left = node.left; + if (!t.isMemberExpression(left) && !t.isIdentifier(left)) { + throw file.errorWithNode(left, messages.get("expectedMemberExpressionOrIdentifier")); + } + return true; + } + }, + + build: function (node) { + return t.unaryExpression("!", node, true); + } +}); + +},{"../../../messages":27,"../../../types":119,"../../helpers/build-conditional-assignment-operator-transformer":32}],101:[function(require,module,exports){ +"use strict"; + +var build = require("../../helpers/build-conditional-assignment-operator-transformer"); +var t = require("../../../types"); + +exports.playground = true; + +build(exports, { + is: function (node) { + var is = t.isAssignmentExpression(node) && node.operator === "?="; + if (is) t.assertMemberExpression(node.left); + return is; + }, + + build: function (node, file) { + return t.unaryExpression( + "!", + t.callExpression( + t.memberExpression(file.addHelper("has-own"), t.identifier("call")), + [node.object, node.property] + ), + true + ); + } +}); + +},{"../../../types":119,"../../helpers/build-conditional-assignment-operator-transformer":32}],102:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.playground = true; + +exports.BindMemberExpression = function (node, parent, scope) { + var object = node.object; + var prop = node.property; + + var temp = scope.generateTempBasedOnNode(node.object); + if (temp) object = temp; + + var call = t.callExpression( + t.memberExpression(t.memberExpression(object, prop), t.identifier("bind")), + [object].concat(node.arguments) + ); + + if (temp) { + return t.sequenceExpression([ + t.assignmentExpression("=", temp, node.object), + call + ]); + } else { + return call; + } +}; + +exports.BindFunctionExpression = function (node, parent, scope) { + var buildCall = function (args) { + var param = scope.generateUidIdentifier("val"); + return t.functionExpression(null, [param], t.blockStatement([ + t.returnStatement(t.callExpression(t.memberExpression(param, node.callee), args)) + ])); + }; + + var temp = scope.generateTemp("args"); + + return t.sequenceExpression([ + t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)), + buildCall(node.arguments.map(function (node, i) { + return t.memberExpression(temp, t.literal(i), true); + })) + ]); +}; + +},{"../../../types":119}],103:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.playground = true; + +var visitor = { + enter: function (node, parent, scope, state) { + if (t.isFunction(node)) return this.skip(); + + if (t.isReturnStatement(node) && node.argument) { + node.argument = t.memberExpression(t.callExpression(state.file.addHelper("define-property"), [ + t.thisExpression(), + state.key, + node.argument + ]), state.key, true); + } + } +}; + +exports.Property = +exports.MethodDefinition = function (node, parent, scope, file) { + if (node.kind !== "memo") return; + node.kind = "get"; + + var value = node.value; + t.ensureBlock(value); + + var key = node.key; + + if (t.isIdentifier(key) && !node.computed) { + key = t.literal(key.name); + } + + var state = { + key: key, + file: file + }; + + scope.traverse(value, visitor, state); + + return node; +}; + +},{"../../../types":119}],104:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.BlockStatement = function (node, parent, scope, file) { + if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) { + return; + } + + for (var i = 0; i < node.body.length; i++) { + var func = node.body[i]; + if (!t.isFunctionDeclaration(func)) continue; + + var declar = t.variableDeclaration("let", [ + t.variableDeclarator(func.id, t.toExpression(func)) + ]); + + // hoist it up above everything else + declar._blockHoist = 2; + + // todo: name this + func.id = null; + + node.body[i] = declar; + + file.checkNode(declar); + } +}; + +},{"../../../types":119}],105:[function(require,module,exports){ +"use strict"; + +var nameMethod = require("../../helpers/name-method"); + +exports.FunctionExpression = nameMethod.bare; + +},{"../../helpers/name-method":36}],106:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); +var pull = require("lodash/array/pull"); + +var isProtoKey = function (node) { + return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" }); +}; + +var isProtoAssignmentExpression = function (node) { + var left = node.left; + return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" }); +}; + +var buildDefaultsCallExpression = function (expr, ref, file) { + return t.expressionStatement(t.callExpression(file.addHelper("defaults"), [ref, expr.right])); +}; + +exports.optional = true; +exports.secondPass = true; + +exports.AssignmentExpression = function (node, parent, scope, file) { + if (!isProtoAssignmentExpression(node)) return; + + var nodes = []; + var left = node.left.object; + var temp = scope.generateTempBasedOnNode(node.left.object); + + nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left))); + nodes.push(buildDefaultsCallExpression(node, temp, file)); + if (temp) nodes.push(temp); + + return t.toSequenceExpression(nodes); +}; + +exports.ExpressionStatement = function (node, parent, scope, file) { + var expr = node.expression; + if (!t.isAssignmentExpression(expr, { operator: "=" })) return; + + if (isProtoAssignmentExpression(expr)) { + return buildDefaultsCallExpression(expr, expr.left.object, file); + } +}; + +exports.ObjectExpression = function (node, parent, scope, file) { + var proto; + + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i]; + + if (isProtoKey(prop)) { + proto = prop.value; + pull(node.properties, prop); + } + } + + if (proto) { + var args = [t.objectExpression([]), proto]; + if (node.properties.length) args.push(node); + return t.callExpression(file.addHelper("extends"), args); + } +}; + +},{"../../../types":119,"lodash/array/pull":194}],107:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.optional = true; + +exports.UnaryExpression = function (node, parent, scope, file) { + this.skip(); + + if (node.operator === "typeof") { + var call = t.callExpression(file.addHelper("typeof"), [node.argument]); + if (t.isIdentifier(node.argument)) { + var undefLiteral = t.literal("undefined"); + return t.conditionalExpression( + t.binaryExpression("===", t.unaryExpression("typeof", node.argument), undefLiteral), + undefLiteral, + call + ); + } else { + return call; + } + } +}; + +},{"../../../types":119}],108:[function(require,module,exports){ +"use strict"; + +var t = require("../../../types"); + +exports.optional = true; + +exports.Identifier = function (node, parent) { + if (node.name === "undefined" && t.isReferenced(node, parent)) { + return t.unaryExpression("void", t.literal(0), true); + } +}; + +},{"../../../types":119}],109:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); +var t = require("../../../types"); + +exports.check = t.isFor; + +exports.ForInStatement = +exports.ForOfStatement = function (node, parent, scope, file) { + var left = node.left; + if (t.isVariableDeclaration(left)) { + var declar = left.declarations[0]; + if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead")); + } +}; + +},{"../../../messages":27,"../../../types":119}],110:[function(require,module,exports){ +var messages = require("../../../messages"); +var t = require("../../../types"); + +// check if the input Literal `source` is an alternate casing of "react" +var check = function (source, file) { + if (t.isLiteral(source)) { + var name = source.value; + var lower = name.toLowerCase(); + + if (lower === "react" && name !== lower) { + throw file.errorWithNode(source, messages.get("didYouMean", "react")); + } + } +}; + +exports.CallExpression = function (node, parent, scope, file) { + if (t.isIdentifier(node.callee, { name: "require" }) && node.arguments.length === 1) { + check(node.arguments[0], file); + } +}; + +exports.ImportDeclaration = +exports.ExportDeclaration = function (node, parent, scope, file) { + check(node.source, file); +}; + +},{"../../../messages":27,"../../../types":119}],111:[function(require,module,exports){ +"use strict"; + +var messages = require("../../../messages"); + +exports.check = function (node) { + return node.kind === "set"; +}; + +exports.MethodDefinition = +exports.Property = function (node, parent, scope, file) { + if (node.kind === "set" && node.value.params.length !== 1) { + throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength")); + } +}; + +},{"../../../messages":27}],112:[function(require,module,exports){ +"use strict"; + +var levenshtein = require("leven"); +var messages = require("../../../messages"); +var t = require("../../../types"); + +exports.optional = true; + +exports.Identifier = function (node, parent, scope, file) { + if (!t.isReferenced(node, parent)) return; + if (scope.hasBinding(node.name)) return; + + // get the closest declaration to offer as a suggestion + // the variable name may have just been mistyped + + var bindings = scope.getAllBindings(); + + var closest; + var shortest = -1; + + for (var name in bindings) { + var distance = levenshtein(node.name, name); + if (distance <= 0 || distance > 3) continue; + if (distance <= shortest) continue; + + closest = name; + shortest = distance; + } + + var msg; + if (closest) { + msg = messages.get("undeclaredVariableSuggestion", node.name, closest); + } else { + msg = messages.get("undeclaredVariable", node.name); + } + + // + + throw file.errorWithNode(node, msg, ReferenceError); +}; + +},{"../../../messages":27,"../../../types":119,"leven":188}],113:[function(require,module,exports){ +"use strict"; + +module.exports = TraversalContext; + +var TraversalPath = require("./path"); +var flatten = require("lodash/array/flatten"); +var compact = require("lodash/array/compact"); + +function TraversalContext(scope, opts, state, parentPath) { + this.shouldFlatten = false; + this.parentPath = parentPath; + + this.scope = scope; + this.state = state; + this.opts = opts; +} + +TraversalContext.prototype.flatten = function () { + this.shouldFlatten = true; +}; + +TraversalContext.prototype.visitNode = function (node, obj, key) { + var iteration = new TraversalPath(this, node, obj, key); + return iteration.visit(); +}; + +TraversalContext.prototype.visit = function (node, key) { + var nodes = node[key]; + if (!nodes) return; + + if (!Array.isArray(nodes)) { + return this.visitNode(node, node, key); + } + + // nothing to traverse! + if (nodes.length === 0) { + return; + } + + for (var i = 0; i < nodes.length; i++) { + if (nodes[i] && this.visitNode(node, nodes, i)) { + return true; + } + } + + if (this.shouldFlatten) { + node[key] = flatten(node[key]); + + if (key === "body") { + // we can safely compact this + node[key] = compact(node[key]); + } + } +}; + +},{"./path":115,"lodash/array/compact":191,"lodash/array/flatten":192}],114:[function(require,module,exports){ +"use strict"; + +module.exports = traverse; + +var TraversalContext = require("./context"); +var includes = require("lodash/collection/includes"); +var t = require("../types"); + +function traverse(parent, opts, scope, state) { + if (!parent) return; + + if (!opts.noScope && !scope) { + if (parent.type !== "Program" && parent.type !== "File") { + throw new Error("Must pass a scope unless traversing a Program/File got a " + parent.type + " node"); + } + } + + if (!opts) opts = {}; + if (!opts.enter) opts.enter = function () { }; + if (!opts.exit) opts.exit = function () { }; + + // array of nodes + if (Array.isArray(parent)) { + for (var i = 0; i < parent.length; i++) { + traverse.node(parent[i], opts, scope, state); + } + } else { + traverse.node(parent, opts, scope, state); + } +} + +traverse.node = function (node, opts, scope, state, parentPath) { + var keys = t.VISITOR_KEYS[node.type]; + if (!keys) return; + + var context = new TraversalContext(scope, opts, state, parentPath); + for (var i = 0; i < keys.length; i++) { + if (context.visit(node, keys[i])) { + return; + } + } +}; + +function clearNode(node) { + node._declarations = null; + node.extendedRange = null; + node._scopeInfo = null; + node.tokens = null; + node.range = null; + node.start = null; + node.end = null; + node.loc = null; + node.raw = null; + + if (Array.isArray(node.trailingComments)) { + clearComments(node.trailingComments); + } + + if (Array.isArray(node.leadingComments)) { + clearComments(node.leadingComments); + } +} + +var clearVisitor = { + noScope: true, + enter: clearNode +}; + +function clearComments(comments) { + for (var i = 0; i < comments.length; i++) { + clearNode(comments[i]); + } +} + +traverse.removeProperties = function (tree) { + clearNode(tree); + traverse(tree, clearVisitor); + + return tree; +}; + +traverse.explode = function (obj) { + for (var type in obj) { + var fns = obj[type]; + + var aliases = t.FLIPPED_ALIAS_KEYS[type]; + if (aliases) { + for (var i = 0; i < aliases.length; i++) { + obj[aliases[i]] = fns; + } + } + } + return obj; +}; + +function hasBlacklistedType(node, parent, scope, state) { + if (node.type === state.type) { + state.has = true; + this.skip(); + } +} + +traverse.hasType = function (tree, scope, type, blacklistTypes) { + // the node we're searching in is blacklisted + if (includes(blacklistTypes, tree.type)) return false; + + // the type we're looking for is the same as the passed node + if (tree.type === type) return true; + + var state = { + has: false, + type: type + }; + + traverse(tree, { + blacklist: blacklistTypes, + enter: hasBlacklistedType + }, scope, state); + + return state.has; +}; + +},{"../types":119,"./context":113,"lodash/collection/includes":200}],115:[function(require,module,exports){ +"use strict"; + +module.exports = TraversalPath; + +var traverse = require("./index"); +var includes = require("lodash/collection/includes"); +var Scope = require("./scope"); +var t = require("../types"); + +function TraversalPath(context, parent, container, key) { + this.shouldRemove = false; + this.shouldSkip = false; + this.shouldStop = false; + + this.parentPath = context.parentPath; + this.context = context; + this.state = this.context.state; + this.opts = this.context.opts; + + this.container = container; + this.key = key; + + this.parent = parent; + this.state = context.state; + + this.setScope(); +} + +TraversalPath.getScope = function (node, parent, scope) { + var ourScope = scope; + + // we're entering a new scope so let's construct it! + if (t.isScope(node, parent)) { + ourScope = new Scope(node, parent, scope); + } + + return ourScope; +}; + +TraversalPath.prototype.setScope = function () { + this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope); +}; + +TraversalPath.prototype.remove = function () { + this.shouldRemove = true; + this.shouldSkip = true; +}; + +TraversalPath.prototype.skip = function () { + this.shouldSkip = true; +}; + +TraversalPath.prototype.stop = function () { + this.shouldStop = true; + this.shouldSkip = true; +}; + +TraversalPath.prototype.flatten = function () { + this.context.flatten(); +}; + +Object.defineProperty(TraversalPath.prototype, "node", { + get: function () { + return this.container[this.key]; + }, + + set: function (replacement) { + var isArray = Array.isArray(replacement); + + // inherit comments from original node to the first replacement node + var inheritTo = replacement; + if (isArray) inheritTo = replacement[0]; + if (inheritTo) t.inheritsComments(inheritTo, this.node); + + // replace the node + this.container[this.key] = replacement; + this.setScope(); + + var file = this.scope && this.scope.file; + if (file) { + if (isArray) { + for (var i = 0; i < replacement.length; i++) { + file.checkNode(replacement[i], this.scope); + } + } else { + file.checkNode(replacement, this.scope); + } + } + + // we're replacing a statement or block node with an array of statements so we better + // ensure that it's a block + if (isArray) { + if (includes(t.STATEMENT_OR_BLOCK_KEYS, this.key) && !t.isBlockStatement(this.container)) { + t.ensureBlock(this.container, this.key); + } + + this.flatten(); + } + } +}); + +TraversalPath.prototype.call = function (key) { + var node = this.node; + if (!node) return; + + var opts = this.opts; + var fn = opts[key] || opts; + if (opts[node.type]) fn = opts[node.type][key] || fn; + + var replacement = fn.call(this, node, this.parent, this.scope, this.state); + + if (replacement) { + this.node = replacement; + } + + if (this.shouldRemove) { + this.container[this.key] = null; + this.flatten(); + } +}; + +TraversalPath.prototype.visit = function () { + var opts = this.opts; + var node = this.node; + + // type is blacklisted + if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) { + return; + } + + this.call("enter"); + + if (this.shouldSkip) { + return this.shouldStop; + } + + node = this.node; + + if (Array.isArray(node)) { + // traverse over these replacement nodes we purposely don't call exitNode + // as the original node has been destroyed + for (var i = 0; i < node.length; i++) { + traverse.node(node[i], opts, this.scope, this.state, this); + } + } else { + traverse.node(node, opts, this.scope, this.state, this); + this.call("exit"); + } + + return this.shouldStop; +}; + +TraversalPath.prototype.isReferencedIdentifier = function () { + return t.isReferencedIdentifier(this.node); +}; + +},{"../types":119,"./index":114,"./scope":116,"lodash/collection/includes":200}],116:[function(require,module,exports){ +"use strict"; + +module.exports = Scope; + +var includes = require("lodash/collection/includes"); +var traverse = require("./index"); +var defaults = require("lodash/object/defaults"); +var messages = require("../messages"); +var globals = require("globals"); +var flatten = require("lodash/array/flatten"); +var extend = require("lodash/object/extend"); +var object = require("../helpers/object"); +var each = require("lodash/collection/each"); +var t = require("../types"); + +/** + * This searches the current "scope" and collects all references/bindings + * within. + * + * @param {Node} block + * @param {Node} parentBlock + * @param {Scope} [parent] + * @param {File} [file] + */ + +function Scope(block, parentBlock, parent, file) { + this.parent = parent; + this.file = parent ? parent.file : file; + + this.parentBlock = parentBlock; + this.block = block; + + this.crawl(); +} + +Scope.globals = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys)); + +/** + * Description + * + * @param {Object} node + * @param {Object} opts + * @param [state] + */ + +Scope.prototype.traverse = function (node, opts, state) { + traverse(node, opts, this, state); +}; + +/** + * Description + * + * @param {String} [name="temp"] + */ + +Scope.prototype.generateTemp = function (name) { + var id = this.generateUidIdentifier(name || "temp"); + this.push({ + key: id.name, + id: id + }); + return id; +}; + +/** + * Description + * + * @param {String} name + */ + +Scope.prototype.generateUidIdentifier = function (name) { + var id = t.identifier(this.generateUid(name)); + this.getFunctionParent().registerBinding("uid", id); + return id; +}; + +/** + * Description + * + * @param {String} name + */ + +Scope.prototype.generateUid = function (name) { + name = t.toIdentifier(name).replace(/^_+/, ""); + + var uid; + var i = 0; + do { + uid = this._generateUid(name, i); + i++; + } while (this.hasBinding(uid) || this.hasGlobal(uid)); + return uid; +}; + +Scope.prototype._generateUid = function (name, i) { + var id = name; + if (i > 1) id += i; + return "_" + id; +}; + +/* + * Description + * + * @param {Object} parent + * @returns {Object} + */ + +Scope.prototype.generateUidBasedOnNode = function (parent) { + var node = parent; + + if (t.isAssignmentExpression(parent)) { + node = parent.left; + } else if (t.isVariableDeclarator(parent)) { + node = parent.id; + } else if (t.isProperty(node)) { + node = node.key; + } + + var parts = []; + + var add = function (node) { + if (t.isMemberExpression(node)) { + add(node.object); + add(node.property); + } else if (t.isIdentifier(node)) { + parts.push(node.name); + } else if (t.isLiteral(node)) { + parts.push(node.value); + } else if (t.isCallExpression(node)) { + add(node.callee); + } + }; + + add(node); + + var id = parts.join("$"); + id = id.replace(/^_/, "") || "ref"; + + return this.generateUidIdentifier(id); +}; + +/** + * Description + * + * @param {Object} node + * @returns {Object} + */ + +Scope.prototype.generateTempBasedOnNode = function (node) { + if (t.isIdentifier(node) && this.hasBinding(node.name)) { + return null; + } + + var id = this.generateUidBasedOnNode(node); + this.push({ + key: id.name, + id: id + }); + return id; +}; + +Scope.prototype.checkBlockScopedCollisions = function (kind, name, id) { + var local = this.getOwnBindingInfo(name); + if (!local) return; + + if (kind === "param") return; + if (kind === "hoisted" && local.kind === "let") return; + + if (local.kind === "let" || local.kind === "const" || local.kind === "module") { + throw this.file.errorWithNode(id, messages.get("scopeDuplicateDeclaration", name), TypeError); + } +}; + +Scope.prototype.rename = function (oldName, newName) { + newName = newName || this.generateUidIdentifier(oldName).name; + + var info = this.getBindingInfo(oldName); + if (!info) return; + + var binding = info.identifier; + var scope = info.scope; + + scope.traverse(scope.block, { + enter: function (node, parent, scope) { + if (t.isReferencedIdentifier(node, parent) && node.name === oldName) { + node.name = newName; + } else if (t.isDeclaration(node)) { + var ids = t.getBindingIdentifiers(node); + for (var name in ids) { + if (name === oldName) ids[name].name = newName; + } + } else if (t.isScope(node, parent)) { + if (!scope.bindingIdentifierEquals(oldName, binding)) { + this.skip(); + } + } + } + }); + + this.clearOwnBinding(oldName); + scope.bindings[newName] = info; + + binding.name = newName; +}; + +Scope.prototype.inferType = function (node) { + var target; + + if (t.isVariableDeclarator(node)) { + target = node.init; + } + + if (t.isArrayExpression(target)) { + return t.genericTypeAnnotation(t.identifier("Array")); + } + + if (t.isObjectExpression(target)) { + return; + } + + if (t.isLiteral(target)) { + return; + } + + if (t.isCallExpression(target) && t.isIdentifier(target.callee)) { + var funcInfo = this.getBindingInfo(target.callee.name); + if (funcInfo) { + var funcNode = funcInfo.node; + return !funcInfo.reassigned && t.isFunction(funcNode) && node.returnType; + } + } + + if (t.isIdentifier(target)) { + return; + } +}; + +Scope.prototype.isTypeGeneric = function (name, genericName) { + var info = this.getBindingInfo(name); + if (!info) return false; + + var type = info.typeAnnotation; + return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName }); +}; + +Scope.prototype.assignTypeGeneric = function (name, type) { + this.assignType(name, t.genericTypeAnnotation(t.identifier(type))); +}; + +Scope.prototype.assignType = function (name, type) { + var info = this.getBindingInfo(name); + if (!info) return; + + info.identifier.typeAnnotation = info.typeAnnotation = type; +}; + +Scope.prototype.getTypeAnnotation = function (name, id, node) { + var info = { + annotation: null, + inferred: false + }; + + var type; + + if (id.typeAnnotation) { + type = id.typeAnnotation; + } + + if (!type) { + info.inferred = true; + type = this.inferType(node); + } + + if (type) { + if (t.isTypeAnnotation(type)) type = type.typeAnnotation; + info.annotation = type; + } + + return info; +}; + +Scope.prototype.toArray = function (node, i) { + var file = this.file; + + if (t.isIdentifier(node) && this.isTypeGeneric(node.name, "Array")) { + return node; + } + + if (t.isArrayExpression(node)) { + return node; + } + + if (t.isIdentifier(node, { name: "arguments" })) { + return t.callExpression(t.memberExpression(file.addHelper("slice"), t.identifier("call")), [node]); + } + + var helperName = "to-array"; + var args = [node]; + if (i === true) { + helperName = "to-consumable-array"; + } else if (i) { + args.push(t.literal(i)); + helperName = "sliced-to-array"; + } + return t.callExpression(file.addHelper(helperName), args); +}; + +Scope.prototype.clearOwnBinding = function (name) { + delete this.bindings[name]; +}; + +Scope.prototype.registerDeclaration = function (node) { + if (t.isFunctionDeclaration(node)) { + this.registerBinding("hoisted", node); + } else if (t.isVariableDeclaration(node)) { + for (var i = 0; i < node.declarations.length; i++) { + this.registerBinding(node.kind, node.declarations[i]); + } + } else if (t.isClassDeclaration(node)) { + this.registerBinding("let", node); + } else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) { + this.registerBinding("module", node); + } else { + this.registerBinding("unknown", node); + } +}; + +Scope.prototype.registerBindingReassignment = function (node) { + var ids = t.getBindingIdentifiers(node); + for (var name in ids) { + var info = this.getBindingInfo(name); + if (info) { + info.reassigned = true; + + if (info.typeAnnotationInferred) { + // destroy the inferred typeAnnotation + info.typeAnnotation = null; + } + } + } +}; + +Scope.prototype.registerBinding = function (kind, node) { + if (!kind) throw new ReferenceError("no `kind`"); + + var ids = t.getBindingIdentifiers(node); + + for (var name in ids) { + var id = ids[name]; + + this.checkBlockScopedCollisions(kind, name, id); + + var typeInfo = this.getTypeAnnotation(name, id, node); + + this.bindings[name] = { + typeAnnotationInferred: typeInfo.inferred, + typeAnnotation: typeInfo.annotation, + reassigned: false, + identifier: id, + scope: this, + node: node, + kind: kind + }; + } +}; + +Scope.prototype.registerVariableDeclaration = function (declar) { + var declars = declar.declarations; + for (var i = 0; i < declars.length; i++) { + this.registerBinding(declars[i], declar.kind); + } +}; + +var functionVariableVisitor = { + enter: function (node, parent, scope, state) { + if (t.isFor(node)) { + each(t.FOR_INIT_KEYS, function (key) { + var declar = node[key]; + if (t.isVar(declar)) state.scope.registerBinding("var", declar); + }); + } + + // this block is a function so we'll stop since none of the variables + // declared within are accessible + if (t.isFunction(node)) return this.skip(); + + // function identifier doesn't belong to this scope + if (state.blockId && node === state.blockId) return; + + // delegate block scope handling to the `blockVariableVisitor` + if (t.isBlockScoped(node)) return; + + // this will be hit again once we traverse into it after this iteration + if (t.isExportDeclaration(node) && t.isDeclaration(node.declaration)) return; + + // we've ran into a declaration! + if (t.isDeclaration(node)) state.scope.registerDeclaration(node); + } +}; + +Scope.prototype.addGlobal = function (node) { + this.globals[node.name] = node; +}; + +Scope.prototype.hasGlobal = function (name) { + var scope = this; + + do { + if (scope.globals[name]) return true; + } while (scope = scope.parent); + + return false; +}; + +var programReferenceVisitor = { + enter: function (node, parent, scope, state) { + if (t.isReferencedIdentifier(node, parent) && !scope.hasBinding(node.name)) { + state.addGlobal(node); + } else if (t.isLabeledStatement(node)) { + state.addGlobal(node); + } else if (t.isAssignmentExpression(node) || t.isUpdateExpression(node) || (t.isUnaryExpression(node) && node.operator === "delete")) { + scope.registerBindingReassignment(node); + } + } +}; + +var blockVariableVisitor = { + enter: function (node, parent, scope, state) { + if (t.isFunctionDeclaration(node) || t.isBlockScoped(node)) { + state.registerDeclaration(node); + } else if (t.isScope(node, parent)) { + this.skip(); + } + } +}; + +Scope.prototype.crawl = function () { + var block = this.block; + var i; + + // + + var info = block._scopeInfo; + if (info) { + extend(this, info); + return; + } + + info = block._scopeInfo = { + bindings: object(), + globals: object() + }; + + extend(this, info); + + // ForStatement - left, init + + if (t.isLoop(block)) { + for (i = 0; i < t.FOR_INIT_KEYS.length; i++) { + var node = block[t.FOR_INIT_KEYS[i]]; + if (t.isBlockScoped(node)) this.registerBinding("let", node); + } + + if (t.isBlockStatement(block.body)) { + block = block.body; + } + } + + // FunctionExpression - id + + if (t.isFunctionExpression(block) && block.id) { + if (!t.isProperty(this.parentBlock, { method: true })) { + this.registerBinding("var", block.id); + } + } + + // Function - params, rest + + if (t.isFunction(block)) { + for (i = 0; i < block.params.length; i++) { + this.registerBinding("param", block.params[i]); + } + this.traverse(block.body, blockVariableVisitor, this); + } + + // Program, BlockStatement, Function - let variables + + if (t.isBlockStatement(block) || t.isProgram(block)) { + this.traverse(block, blockVariableVisitor, this); + } + + // CatchClause - param + + if (t.isCatchClause(block)) { + this.registerBinding("let", block.param); + } + + // ComprehensionExpression - blocks + + if (t.isComprehensionExpression(block)) { + this.registerBinding("let", block); + } + + // Program, Function - var variables + + if (t.isProgram(block) || t.isFunction(block)) { + this.traverse(block, functionVariableVisitor, { + blockId: block.id, + scope: this + }); + } + + // Program + + if (t.isProgram(block)) { + this.traverse(block, programReferenceVisitor, this); + } +}; + +/** + * Description + * + * @param {Object} opts + */ + +Scope.prototype.push = function (opts) { + var block = this.block; + + if (t.isLoop(block) || t.isCatchClause(block) || t.isFunction(block)) { + t.ensureBlock(block); + block = block.body; + } + + if (t.isBlockStatement(block) || t.isProgram(block)) { + block._declarations = block._declarations || {}; + block._declarations[opts.key] = { + kind: opts.kind, + id: opts.id, + init: opts.init + }; + } else { + throw new TypeError("cannot add a declaration here in node type " + block.type); + } +}; + +/** + * Walk up the scope tree until we hit either a Function or reach the + * very top and hit Program. + */ + +Scope.prototype.getFunctionParent = function () { + var scope = this; + while (scope.parent && !t.isFunction(scope.block)) { + scope = scope.parent; + } + return scope; +}; + +/** + * Walks the scope tree and gathers **all** bindings. + * + * @returns {Object} + */ + +Scope.prototype.getAllBindings = function () { + var ids = object(); + + var scope = this; + do { + defaults(ids, scope.bindings); + scope = scope.parent; + } while (scope); + + return ids; +}; + +/** + * Walks the scope tree and gathers all declarations of `kind`. + * + * @param {String} kind + * @returns {Object} + */ + +Scope.prototype.getAllBindingsOfKind = function (kind) { + var ids = object(); + + var scope = this; + do { + for (var name in scope.bindings) { + var binding = scope.bindings[name]; + if (binding.kind === kind) ids[name] = binding; + } + scope = scope.parent; + } while (scope); + + return ids; +}; + +// misc + +Scope.prototype.bindingIdentifierEquals = function (name, node) { + return this.getBindingIdentifier(name) === node; +}; + +// get + +Scope.prototype.getBindingInfo = function (name) { + var scope = this; + + do { + var binding = scope.getOwnBindingInfo(name); + if (binding) return binding; + } while (scope = scope.parent); +}; + +Scope.prototype.getOwnBindingInfo = function (name) { + return this.bindings[name]; +}; + +Scope.prototype.getBindingIdentifier = function (name) { + var info = this.getBindingInfo(name); + return info && info.identifier; +}; + +Scope.prototype.getOwnBindingIdentifier = function (name) { + var binding = this.bindings[name]; + return binding && binding.identifier; +}; + +// has + +Scope.prototype.hasOwnBinding = function (name) { + return !!this.getOwnBindingInfo(name); +}; + +Scope.prototype.hasBinding = function (name) { + if (!name) return false; + if (this.hasOwnBinding(name)) return true; + if (this.parentHasBinding(name)) return true; + if (includes(Scope.globals, name)) return true; + return false; +}; + +Scope.prototype.parentHasBinding = function (name) { + return this.parent && this.parent.hasBinding(name); +}; + +},{"../helpers/object":24,"../messages":27,"../types":119,"./index":114,"globals":183,"lodash/array/flatten":192,"lodash/collection/each":197,"lodash/collection/includes":200,"lodash/object/defaults":294,"lodash/object/extend":295}],117:[function(require,module,exports){ +module.exports={ + "ExpressionStatement": ["Statement"], + "BreakStatement": ["Statement"], + "ContinueStatement": ["Statement"], + "DebuggerStatement": ["Statement"], + "DoWhileStatement": ["Statement", "Loop", "While", "Scopable"], + "IfStatement": ["Statement"], + "ReturnStatement": ["Statement"], + "SwitchStatement": ["Statement"], + "ThrowStatement": ["Statement"], + "TryStatement": ["Statement"], + "WhileStatement": ["Statement", "Loop", "While", "Scopable"], + "WithStatement": ["Statement"], + "EmptyStatement": ["Statement"], + "LabeledStatement": ["Statement"], + "VariableDeclaration": ["Statement", "Declaration"], + "ExportDeclaration": ["Statement", "Declaration"], + "ImportDeclaration": ["Statement", "Declaration"], + "PrivateDeclaration": ["Statement", "Declaration"], + + "ArrowFunctionExpression": ["Scopable", "Function", "Expression"], + "FunctionDeclaration": ["Scopable", "Function", "Statement", "Declaration"], + "FunctionExpression": ["Scopable", "Function", "Expression"], + + "ImportSpecifier": ["ModuleSpecifier"], + "ExportSpecifier": ["ModuleSpecifier"], + + "BlockStatement": ["Statement", "Scopable"], + "Program": ["Scopable"], + "CatchClause": ["Scopable"], + + "LogicalExpression": ["Binary", "Expression"], + "BinaryExpression": ["Binary", "Expression"], + + "UnaryExpression": ["UnaryLike", "Expression"], + "SpreadProperty": ["UnaryLike"], + "SpreadElement": ["UnaryLike"], + + "ClassDeclaration": ["Statement", "Declaration", "Class"], + "ClassExpression": ["Class", "Expression"], + + "ForOfStatement": ["Scopable", "Statement", "For", "Loop"], + "ForInStatement": ["Scopable", "Statement", "For", "Loop"], + "ForStatement": ["Scopable", "Statement", "For", "Loop"], + + "ObjectPattern": ["Pattern"], + "ArrayPattern": ["Pattern"], + "AssignmentPattern": ["Pattern"], + + "Property": ["UserWhitespacable"], + + "ArrayExpression": ["Expression"], + "AssignmentExpression": ["Expression"], + "AwaitExpression": ["Expression"], + "BindFunctionExpression": ["Expression"], + "BindMemberExpression": ["Expression"], + "CallExpression": ["Expression"], + "ComprehensionExpression": ["Expression", "Scopable"], + "ConditionalExpression": ["Expression"], + "Identifier": ["Expression"], + "Literal": ["Expression"], + "MemberExpression": ["Expression"], + "NewExpression": ["Expression"], + "ObjectExpression": ["Expression"], + "SequenceExpression": ["Expression"], + "TaggedTemplateExpression": ["Expression"], + "ThisExpression": ["Expression"], + "UpdateExpression": ["Expression"], + "VirtualPropertyExpression": ["Expression"], + "JSXEmptyExpression": ["Expression"], + "JSXMemberExpression": ["Expression"], + "YieldExpression": ["Expression"], + + "JSXAttribute": ["JSX"], + "JSXClosingElement": ["JSX"], + "JSXElement": ["JSX", "Expression"], + "JSXEmptyExpression": ["JSX"], + "JSXExpressionContainer": ["JSX"], + "JSXIdentifier": ["JSX"], + "JSXMemberExpression": ["JSX"], + "JSXNamespacedName": ["JSX"], + "JSXOpeningElement": ["JSX"], + "JSXSpreadAttribute": ["JSX"] +} + +},{}],118:[function(require,module,exports){ +module.exports={ + "ArrayExpression": { + "elements": null + }, + + "ArrowFunctionExpression": { + "params": null, + "body": null + }, + + "AssignmentExpression": { + "operator": null, + "left": null, + "right": null + }, + + "BinaryExpression": { + "operator": null, + "left": null, + "right": null + }, + + "BlockStatement": { + "body": null + }, + + "CallExpression": { + "callee": null, + "arguments": null + }, + + "ConditionalExpression": { + "test": null, + "consequent": null, + "alternate": null + }, + + "ExpressionStatement": { + "expression": null + }, + + "File": { + "program": null, + "comments": null, + "tokens": null + }, + + "FunctionExpression": { + "id": null, + "params": null, + "body": null, + "generator": false + }, + + "FunctionDeclaration": { + "id": null, + "params": null, + "body": null, + "generator": false + }, + + "GenericTypeAnnotation": { + "id": null, + "typeParameters": null + }, + + "Identifier": { + "name": null + }, + + "IfStatement": { + "test": null, + "consequent": null, + "alternate": null + }, + + "ImportDeclaration": { + "specifiers": null, + "source": null + }, + + "ImportSpecifier": { + "id": null, + "name": null + }, + + "Literal": { + "value": null + }, + + "LogicalExpression": { + "operator": null, + "left": null, + "right": null + }, + + "MemberExpression": { + "object": null, + "property": null, + "computed": false + }, + + "MethodDefinition": { + "key": null, + "value": null, + "computed": false, + "static": false, + "kind": null + }, + + "NewExpression": { + "callee": null, + "arguments": null + }, + + "ObjectExpression": { + "properties": null + }, + + "Program": { + "body": null + }, + + "Property": { + "kind": null, + "key": null, + "value": null, + "computed": false + }, + + "ReturnStatement": { + "argument": null + }, + + "SequenceExpression": { + "expressions": null + }, + + "ThrowExpression": { + "argument": null + }, + + "UnaryExpression": { + "operator": null, + "argument": null, + "prefix": null + }, + + "VariableDeclaration": { + "kind": null, + "declarations": null + }, + + "VariableDeclarator": { + "id": null, + "init": null + }, + + "WithStatement": { + "object": null, + "body": null + }, + + "YieldExpression": { + "argument": null, + "delegate": null + } +} + +},{}],119:[function(require,module,exports){ +"use strict"; + +var toFastProperties = require("../helpers/to-fast-properties"); +var isString = require("lodash/lang/isString"); +var compact = require("lodash/array/compact"); +var esutils = require("esutils"); +var object = require("../helpers/object"); +var each = require("lodash/collection/each"); +var uniq = require("lodash/array/uniq"); + +var t = exports; + +/** + * Registers `is[Type]` and `assert[Type]` generated functions for a given `type`. + * Pass `skipAliasCheck` to force it to directly compare `node.type` with `type`. + * + * @param {String} type + * @param {Boolean?} skipAliasCheck + */ + +function registerType(type, skipAliasCheck) { + var is = t["is" + type] = function (node, opts) { + return t.is(type, node, opts, skipAliasCheck); + }; + + t["assert" + type] = function (node, opts) { + opts = opts || {}; + if (!is(node, opts)) { + throw new Error("Expected type " + JSON.stringify(type) + " with option " + JSON.stringify(opts)); + } + }; +} + +t.STATEMENT_OR_BLOCK_KEYS = ["consequent", "body"]; +t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"]; +t.FOR_INIT_KEYS = ["left", "init"]; + +t.VISITOR_KEYS = require("./visitor-keys"); +t.ALIAS_KEYS = require("./alias-keys"); + +t.FLIPPED_ALIAS_KEYS = {}; + +each(t.VISITOR_KEYS, function (keys, type) { + registerType(type, true); +}); + +each(t.ALIAS_KEYS, function (aliases, type) { + each(aliases, function (alias) { + var types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || []; + types.push(type); + }); +}); + +each(t.FLIPPED_ALIAS_KEYS, function (types, type) { + t[type.toUpperCase() + "_TYPES"] = types; + registerType(type, false); +}); + +/** + * Returns whether `node` is of given `type`. + * + * For better performance, use this instead of `is[Type]` when `type` is unknown. + * Optionally, pass `skipAliasCheck` to directly compare `node.type` with `type`. + * + * @param {String} type + * @param {Node} node + * @param {Object?} opts + * @param {Boolean?} skipAliasCheck + * @returns {Boolean} isOfType + */ + +t.is = function (type, node, opts, skipAliasCheck) { + if (!node) return false; + + var typeMatches = type === node.type; + + if (!typeMatches && !skipAliasCheck) { + var aliases = t.FLIPPED_ALIAS_KEYS[type]; + + if (typeof aliases !== "undefined") { + typeMatches = aliases.indexOf(node.type) > -1; + } + } + + if (!typeMatches) { + return false; + } + + if (typeof opts !== "undefined") { + return t.shallowEqual(node, opts); + } + + return true; +}; + +// + +t.BUILDER_KEYS = require("./builder-keys"); + +each(t.VISITOR_KEYS, function (keys, type) { + if (t.BUILDER_KEYS[type]) return; + + var defs = {}; + each(keys, function (key) { + defs[key] = null; + }); + t.BUILDER_KEYS[type] = defs; +}); + +each(t.BUILDER_KEYS, function (keys, type) { + t[type[0].toLowerCase() + type.slice(1)] = function () { + var node = {}; + node.start = null; + node.type = type; + + var i = 0; + + for (var key in keys) { + var arg = arguments[i++]; + if (arg === undefined) arg = keys[key]; + node[key] = arg; + } + + return node; + }; +}); + +/** + * Description + * + * @param {Object} node + * @returns {Object} + */ + +t.toComputedKey = function (node, key) { + if (!node.computed) { + if (t.isIdentifier(key)) key = t.literal(key.name); + } + return key; +}; + +/* + * Shallowly checks to see if the passed `node` is falsy. + * + * @param {Object} node + * @returns {Boolean} + */ + +t.isFalsyExpression = function (node) { + if (t.isLiteral(node)) { + return !node.value; + } else if (t.isIdentifier(node)) { + return node.name === "undefined"; + } + return false; +}; + +/** + * Turn an array of statement `nodes` into a `SequenceExpression`. + * + * Variable declarations are turned into simple assignments and their + * declarations hoisted to the top of the current scope. + * + * Expression statements are just resolved to their standard expression. + * + * @param {Array} nodes + * @param {Scope} scope + */ + +t.toSequenceExpression = function (nodes, scope) { + var exprs = []; + + each(nodes, function (node) { + if (t.isExpression(node)) { + exprs.push(node); + } if (t.isExpressionStatement(node)) { + exprs.push(node.expression); + } else if (t.isVariableDeclaration(node)) { + each(node.declarations, function (declar) { + scope.push({ + kind: node.kind, + key: declar.id.name, + id: declar.id + }); + exprs.push(t.assignmentExpression("=", declar.id, declar.init)); + }); + } + }); + + if (exprs.length === 1) { + return exprs[0]; + } else { + return t.sequenceExpression(exprs); + } +}; + +/* + * Description + * + * @param {Object} actual + * @param {Object} expected + * @returns {Boolean} + */ + +t.shallowEqual = function (actual, expected) { + var keys = Object.keys(expected); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (actual[key] !== expected[key]) { + return false; + } + } + + return true; +}; + +/** + * Description + * + * @param {Object} member + * @param {Object} append + * @param {Boolean} [computed] + * @returns {Object} member + */ + +t.appendToMemberExpression = function (member, append, computed) { + member.object = t.memberExpression(member.object, member.property, member.computed); + member.property = append; + member.computed = !!computed; + return member; +}; + +/** + * Description + * + * @param {Object} member + * @param {Object} append + * @returns {Object} member + */ + +t.prependToMemberExpression = function (member, append) { + member.object = t.memberExpression(append, member.object); + return member; +}; + +/** + * Check if the input `node` is a reference to a bound variable. + * + * @param {Object} node + * @param {Object} parent + * @returns {Boolean} + */ + +t.isReferenced = function (node, parent) { + // yes: PARENT[NODE] + // yes: NODE.child + // no: parent.CHILD + if (t.isMemberExpression(parent)) { + if (parent.property === node && parent.computed) { + return true; + } else if (parent.object === node) { + return true; + } else { + return false; + } + } + + // yes: { [NODE]: "" } + // no: { NODE: "" } + if (t.isProperty(parent) && parent.key === node) { + return parent.computed; + } + + // no: var NODE = init; + // yes: var id = NODE; + if (t.isVariableDeclarator(parent)) { + return parent.id !== node; + } + + // no: function NODE() {} + // no: function foo(NODE) {} + if (t.isFunction(parent)) { + for (var i = 0; i < parent.params.length; i++) { + var param = parent.params[i]; + if (param === node) return false; + } + + return parent.id !== node; + } + + // no: class NODE {} + if (t.isClass(parent)) { + return parent.id !== node; + } + + // yes: class { [NODE](){} } + if (t.isMethodDefinition(parent)) { + return parent.key === node && parent.computed; + } + + // no: NODE: for (;;) {} + if (t.isLabeledStatement(parent)) { + return false; + } + + // no: try {} catch (NODE) {} + if (t.isCatchClause(parent)) { + return parent.param !== node; + } + + // no: function foo(...NODE) {} + if (t.isRestElement(parent)) { + return false; + } + + // no: [NODE = foo] = []; + // yes: [foo = NODE] = []; + if (t.isAssignmentPattern(parent)) { + return parent.right === node; + } + + // no: [NODE] = []; + // no: ({ NODE }) = []; + if (t.isPattern(parent)) { + return false; + } + + // no: import NODE from "bar"; + if (t.isImportSpecifier(parent)) { + return false; + } + + // no: import * as NODE from "foo"; + if (t.isImportBatchSpecifier(parent)) { + return false; + } + + // no: class Foo { private NODE; } + if (t.isPrivateDeclaration(parent)) { + return false; + } + + return true; +}; + +/** + * Check if the input `node` is an `Identifier` and `isReferenced`. + * + * @param {Node} node + * @parma {Node} parent + * @returns {Boolean} + */ + +t.isReferencedIdentifier = function (node, parent, opts) { + return t.isIdentifier(node, opts) && t.isReferenced(node, parent); +}; + +/** + * Check if the input `name` is a valid identifier name + * and isn't a reserved word. + * + * @param {String} name + * @returns {Boolean} + */ + +t.isValidIdentifier = function (name) { + return isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isReservedWordES6(name, true); +}; + +/* + * Description + * + * @param {String} name + * @returns {String} + */ + +t.toIdentifier = function (name) { + if (t.isIdentifier(name)) return name.name; + + name = name + ""; + + // replace all non-valid identifiers with dashes + name = name.replace(/[^a-zA-Z0-9$_]/g, "-"); + + // remove all dashes and numbers from start of name + name = name.replace(/^[-0-9]+/, ""); + + // camel case + name = name.replace(/[-\s]+(.)?/g, function (match, c) { + return c ? c.toUpperCase() : ""; + }); + + if (!t.isValidIdentifier(name)) { + name = "_" + name; + } + + return name || "_"; +}; + +/** + * Description + * + * @param {Object} node + * @param {String=} key + */ + +t.ensureBlock = function (node, key) { + key = key || "body"; + return node[key] = t.toBlock(node[key], node); +}; + +/** + * Build a function that when called will return whether or not the + * input `node` `MemberExpression` matches the input `match`. + * + * For example, given the match `React.createClass` it would match the + * parsed nodes of `React.createClass` and `React["createClass"]`. + * + * @param {String} match Dot-delimited string + * @param {Boolean} [allowPartial] Allow a partial match + * @returns {Function} + */ + +t.buildMatchMemberExpression = function (match, allowPartial) { + var parts = match.split("."); + + return function (member) { + // not a member expression + if (!t.isMemberExpression(member)) return false; + + var search = [member]; + var i = 0; + + while (search.length) { + var node = search.shift(); + + if (allowPartial && i === parts.length) { + return true; + } + + if (t.isIdentifier(node)) { + // this part doesn't match + if (parts[i] !== node.name) return false; + } else if (t.isLiteral(node)) { + // this part doesn't match + if (parts[i] !== node.value) return false; + } else if (t.isMemberExpression(node)) { + if (node.computed && !t.isLiteral(node.property)) { + // we can't deal with this + return false; + } else { + search.push(node.object); + search.push(node.property); + continue; + } + } else { + // we can't deal with this + return false; + } + + // too many parts + if (++i > parts.length) { + return false; + } + } + + return true; + }; +}; + +/** + * Description + * + * @param {Object} node + * @param {Boolean} [ignore] + * @returns {Object|Boolean} + */ + +t.toStatement = function (node, ignore) { + if (t.isStatement(node)) { + return node; + } + + var mustHaveId = false; + var newType; + + if (t.isClass(node)) { + mustHaveId = true; + newType = "ClassDeclaration"; + } else if (t.isFunction(node)) { + mustHaveId = true; + newType = "FunctionDeclaration"; + } else if (t.isAssignmentExpression(node)) { + return t.expressionStatement(node); + } + + if (mustHaveId && !node.id) { + newType = false; + } + + if (!newType) { + if (ignore) { + return false; + } else { + throw new Error("cannot turn " + node.type + " to a statement"); + } + } + + node.type = newType; + + return node; +}; + +/** + * Description + * + * @param {Object} node + * @returns {Object} + */ + +exports.toExpression = function (node) { + if (t.isExpressionStatement(node)) { + node = node.expression; + } + + if (t.isClass(node)) { + node.type = "ClassExpression"; + } else if (t.isFunction(node)) { + node.type = "FunctionExpression"; + } + + if (t.isExpression(node)) { + return node; + } else { + throw new Error("cannot turn " + node.type + " to an expression"); + } +}; + +/** + * Description + * + * @param {Object} node + * @param {Object} parent + * @returns {Object} + */ + +t.toBlock = function (node, parent) { + if (t.isBlockStatement(node)) { + return node; + } + + if (t.isEmptyStatement(node)) { + node = []; + } + + if (!Array.isArray(node)) { + if (!t.isStatement(node)) { + if (t.isFunction(parent)) { + node = t.returnStatement(node); + } else { + node = t.expressionStatement(node); + } + } + + node = [node]; + } + + return t.blockStatement(node); +}; + +/** + * Return a list of binding identifiers associated with + * the input `node`. + * + * @param {Object} node + * @returns {Array|Object} + */ + +t.getBindingIdentifiers = function (node) { + var search = [].concat(node); + var ids = object(); + + while (search.length) { + var id = search.shift(); + if (!id) continue; + + var keys = t.getBindingIdentifiers.keys[id.type]; + + if (t.isIdentifier(id)) { + ids[id.name] = id; + } else if (t.isImportSpecifier(id)) { + search.push(id.name || id.id); + } else if (t.isExportDeclaration(id)) { + if (t.isDeclaration(node.declaration)) { + search.push(node.declaration); + } + } else if (keys) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + search = search.concat(id[key] || []); + } + } + } + + return ids; +}; + +t.getBindingIdentifiers.keys = { + UnaryExpression: ["argument"], + AssignmentExpression: ["left"], + ImportBatchSpecifier: ["name"], + VariableDeclarator: ["id"], + FunctionDeclaration: ["id"], + ClassDeclaration: ["id"], + SpreadElement: ["argument"], + RestElement: ["argument"], + UpdateExpression: ["argument"], + SpreadProperty: ["argument"], + Property: ["value"], + ComprehensionBlock: ["left"], + AssignmentPattern: ["left"], + PrivateDeclaration: ["declarations"], + ComprehensionExpression: ["blocks"], + ImportDeclaration: ["specifiers"], + VariableDeclaration: ["declarations"], + ArrayPattern: ["elements"], + ObjectPattern: ["properties"] +}; + +/** + * Description + * + * @param {Object} node + * @returns {Boolean} + */ + +t.isLet = function (node) { + return t.isVariableDeclaration(node) && (node.kind !== "var" || node._let); +}; + +/** + * Description + * + * @param {Object} node + * @returns {Boolean} + */ + +t.isBlockScoped = function (node) { + return t.isFunctionDeclaration(node) || t.isClassDeclaration(node) || t.isLet(node); +}; + +/** + * Description + * + * @param {Object} node + * @returns {Boolean} + */ + +t.isVar = function (node) { + return t.isVariableDeclaration(node, { kind: "var" }) && !node._let; +}; + +// + +t.COMMENT_KEYS = ["leadingComments", "trailingComments"]; + +/** + * Description + * + * @param {Object} child + * @returns {Object} child + */ + +t.removeComments = function (child) { + each(t.COMMENT_KEYS, function (key) { + delete child[key]; + }); + return child; +}; + +/** + * Description + * + * @param {Object} child + * @param {Object} parent + * @returns {Object} child + */ + +t.inheritsComments = function (child, parent) { + each(t.COMMENT_KEYS, function (key) { + child[key] = uniq(compact([].concat(child[key], parent[key]))); + }); + return child; +}; + +/** + * Description + * + * @param {Object} child + * @param {Object} parent + * @returns {Object} child + */ + +t.inherits = function (child, parent) { + child._declarations = parent._declarations; + child._scopeInfo = parent._scopeInfo; + child.range = parent.range; + child.start = parent.start; + child.loc = parent.loc; + child.end = parent.end; + t.inheritsComments(child, parent); + return child; +}; + +/** + * Description + * + * @param {Object} node + * @returns {Array} + */ + +t.getLastStatements = function (node) { + var nodes = []; + + var add = function (node) { + nodes = nodes.concat(t.getLastStatements(node)); + }; + + if (t.isIfStatement(node)) { + add(node.consequent); + add(node.alternate); + } else if (t.isFor(node) || t.isWhile(node)) { + add(node.body); + } else if (t.isProgram(node) || t.isBlockStatement(node)) { + add(node.body[node.body.length - 1]); + } else if (node) { + nodes.push(node); + } + + return nodes; +}; + +/** + * Description + * + * @param {Object} specifier + * @returns {String} + */ + +t.getSpecifierName = function (specifier) { + return specifier.name || specifier.id; +}; + +/** + * Description + * + * @param {Object} specifier + * @returns {String} + */ + +t.getSpecifierId = function (specifier) { + if (specifier.default) { + return t.identifier("default"); + } else { + return specifier.id; + } +}; + +/** + * Description + * + * @param {Object} specifier + * @returns {Boolean} + */ + +t.isSpecifierDefault = function (specifier) { + return specifier.default || t.isIdentifier(specifier.id) && specifier.id.name === "default"; +}; + +/** + * Description + * + * @param {Node} node + * @param {Node} parent + * @returns {Boolean} + */ + +t.isScope = function (node, parent) { + if (t.isBlockStatement(node)) { + if (t.isLoop(parent.block, { body: node })) { + return false; + } + + if (t.isFunction(parent.block, { body: node })) { + return false; + } + } + + return t.isScopable(node); +}; + +toFastProperties(t); +toFastProperties(t.VISITOR_KEYS); + +},{"../helpers/object":24,"../helpers/to-fast-properties":26,"./alias-keys":117,"./builder-keys":118,"./visitor-keys":120,"esutils":181,"lodash/array/compact":191,"lodash/array/uniq":195,"lodash/collection/each":197,"lodash/lang/isString":291}],120:[function(require,module,exports){ +module.exports={ + "ArrayExpression": ["elements"], + "ArrayPattern": ["elements"], + "ArrowFunctionExpression": ["params", "defaults", "rest", "body"], + "AssignmentExpression": ["left", "right"], + "AssignmentPattern": ["left", "right"], + "AwaitExpression": ["argument"], + "BinaryExpression": ["left", "right"], + "BindFunctionExpression": ["callee", "arguments"], + "BindMemberExpression": ["object", "property", "arguments"], + "BlockStatement": ["body"], + "BreakStatement": ["label"], + "CallExpression": ["callee", "arguments"], + "CatchClause": ["param", "body"], + "ClassBody": ["body"], + "ClassDeclaration": ["id", "body", "superClass"], + "ClassExpression": ["id", "body", "superClass"], + "ComprehensionBlock": ["left", "right", "body"], + "ComprehensionExpression": ["filter", "blocks", "body"], + "ConditionalExpression": ["test", "consequent", "alternate"], + "ContinueStatement": ["label"], + "DebuggerStatement": [], + "DoWhileStatement": ["body", "test"], + "EmptyStatement": [], + "ExportBatchSpecifier": [], + "ExportDeclaration": ["declaration", "specifiers", "source"], + "ExportSpecifier": ["id", "name"], + "ExpressionStatement": ["expression"], + "File": ["program"], + "ForInStatement": ["left", "right", "body"], + "ForOfStatement": ["left", "right", "body"], + "ForStatement": ["init", "test", "update", "body"], + "FunctionDeclaration": ["id", "params", "defaults", "rest", "body"], + "FunctionExpression": ["id", "params", "defaults", "rest", "body"], + "Identifier": [], + "IfStatement": ["test", "consequent", "alternate"], + "ImportBatchSpecifier": ["id"], + "ImportDeclaration": ["specifiers", "source"], + "ImportSpecifier": ["id", "name"], + "LabeledStatement": ["label", "body"], + "Literal": [], + "LogicalExpression": ["left", "right"], + "MemberExpression": ["object", "property"], + "MethodDefinition": ["key", "value"], + "NewExpression": ["callee", "arguments"], + "ObjectExpression": ["properties"], + "ObjectPattern": ["properties"], + "PrivateDeclaration": ["declarations"], + "Program": ["body"], + "Property": ["key", "value"], + "RestElement": ["argument"], + "ReturnStatement": ["argument"], + "SequenceExpression": ["expressions"], + "SpreadElement": ["argument"], + "SpreadProperty": ["argument"], + "SwitchCase": ["test", "consequent"], + "SwitchStatement": ["discriminant", "cases"], + "TaggedTemplateExpression": ["tag", "quasi"], + "TemplateElement": [], + "TemplateLiteral": ["quasis", "expressions"], + "ThisExpression": [], + "ThrowStatement": ["argument"], + "TryStatement": ["block", "handlers", "handler", "guardedHandlers", "finalizer"], + "UnaryExpression": ["argument"], + "UpdateExpression": ["argument"], + "VariableDeclaration": ["declarations"], + "VariableDeclarator": ["id", "init"], + "VirtualPropertyExpression": ["object", "property"], + "WhileStatement": ["test", "body"], + "WithStatement": ["object", "body"], + "YieldExpression": ["argument"], + + "AnyTypeAnnotation": [], + "ArrayTypeAnnotation": [], + "BooleanTypeAnnotation": [], + "ClassProperty": ["key", "value"], + "DeclareClass": [], + "DeclareFunction": [], + "DeclareModule": [], + "DeclareVariable": [], + "FunctionTypeAnnotation": [], + "FunctionTypeParam": [], + "GenericTypeAnnotation": [], + "InterfaceExtends": [], + "InterfaceDeclaration": [], + "IntersectionTypeAnnotation": [], + "NullableTypeAnnotation": [], + "NumberTypeAnnotation": [], + "StringLiteralTypeAnnotation": [], + "StringTypeAnnotation": [], + "TupleTypeAnnotation": [], + "TypeofTypeAnnotation": [], + "TypeAlias": [], + "TypeAnnotation": [], + "TypeCastExpression": ["expression"], + "TypeParameterDeclaration": [], + "TypeParameterInstantiation": [], + "ObjectTypeAnnotation": [], + "ObjectTypeCallProperty": [], + "ObjectTypeIndexer": [], + "ObjectTypeProperty": [], + "QualifiedTypeIdentifier": [], + "UnionTypeAnnotation": [], + "VoidTypeAnnotation": [], + + "JSXAttribute": ["name", "value"], + "JSXClosingElement": ["name"], + "JSXElement": ["openingElement", "closingElement", "children"], + "JSXEmptyExpression": [], + "JSXExpressionContainer": ["expression"], + "JSXIdentifier": [], + "JSXMemberExpression": ["object", "property"], + "JSXNamespacedName": ["namespace", "name"], + "JSXOpeningElement": ["name", "attributes"], + "JSXSpreadAttribute": ["argument"] +} + +},{}],121:[function(require,module,exports){ +(function (__dirname){ +"use strict"; + +require("./patch"); + +var cloneDeep = require("lodash/lang/cloneDeep"); +var contains = require("lodash/collection/contains"); +var traverse = require("./traversal"); +var isString = require("lodash/lang/isString"); +var isRegExp = require("lodash/lang/isRegExp"); +var isEmpty = require("lodash/lang/isEmpty"); +var parse = require("./helpers/parse"); +var debug = require("debug/node"); +var path = require("path"); +var util = require("util"); +var each = require("lodash/collection/each"); +var has = require("lodash/object/has"); +var fs = require("fs"); +var t = require("./types"); + +exports.inherits = util.inherits; + +exports.debug = debug("babel"); + +exports.canCompile = function (filename, altExts) { + var exts = altExts || exports.canCompile.EXTENSIONS; + var ext = path.extname(filename); + return contains(exts, ext); +}; + +exports.canCompile.EXTENSIONS = [".js", ".jsx", ".es6", ".es"]; + +exports.resolve = function (loc) { + try { + return require.resolve(loc); + } catch (err) { + return null; + } +}; + +exports.list = function (val) { + return val ? val.split(",") : []; +}; + +exports.regexify = function (val) { + if (!val) return new RegExp(/.^/); + if (Array.isArray(val)) val = val.join("|"); + if (isString(val)) return new RegExp(val); + if (isRegExp(val)) return val; + throw new TypeError("illegal type for regexify"); +}; + +exports.arrayify = function (val) { + if (!val) return []; + if (isString(val)) return exports.list(val); + if (Array.isArray(val)) return val; + throw new TypeError("illegal type for arrayify"); +}; + +exports.booleanify = function (val) { + if (val === "true") return true; + if (val === "false") return false; + return val; +}; + +var templateVisitor = { + enter: function (node, parent, scope, nodes) { + if (t.isExpressionStatement(node)) { + node = node.expression; + } + if (t.isIdentifier(node) && has(nodes, node.name)) { + this.skip(); + return nodes[node.name]; + } + } +}; + +exports.template = function (name, nodes, keepExpression) { + var template = exports.templates[name]; + if (!template) throw new ReferenceError("unknown template " + name); + + if (nodes === true) { + keepExpression = true; + nodes = null; + } + + template = cloneDeep(template); + + if (!isEmpty(nodes)) { + traverse(template, templateVisitor, null, nodes); + } + + if (template.body.length > 1) return template.body; + + var node = template.body[0]; + + if (!keepExpression && t.isExpressionStatement(node)) { + return node.expression; + } else { + return node; + } +}; + +exports.parseTemplate = function (loc, code) { + var ast = parse({ filename: loc }, code).program; + return traverse.removeProperties(ast); +}; + +var loadTemplates = function () { + var templates = {}; + + var templatesLoc = __dirname + "/transformation/templates"; + if (!fs.existsSync(templatesLoc)) { + throw new Error("no templates directory - this is most likely the " + + "result of a broken `npm publish`. Please report to " + + "https://github.com/babel/babel/issues"); + } + + each(fs.readdirSync(templatesLoc), function (name) { + if (name[0] === ".") return; + + var key = path.basename(name, path.extname(name)); + var loc = templatesLoc + "/" + name; + var code = fs.readFileSync(loc, "utf8"); + + templates[key] = exports.parseTemplate(loc, code); + }); + + return templates; +}; + +try { + exports.templates = require("../../templates.json"); +} catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + + exports.templates = loadTemplates(); +} + +}).call(this,"/lib/babel") +},{"../../templates.json":339,"./helpers/parse":25,"./patch":28,"./traversal":114,"./types":119,"debug/node":174,"fs":137,"lodash/collection/contains":196,"lodash/collection/each":197,"lodash/lang/cloneDeep":281,"lodash/lang/isEmpty":285,"lodash/lang/isRegExp":290,"lodash/lang/isString":291,"lodash/object/has":296,"path":146,"util":163}],122:[function(require,module,exports){ +// Acorn is a tiny, fast JavaScript parser written in JavaScript. +// +// Acorn was written by Marijn Haverbeke and various contributors and +// released under an MIT license. The Unicode regexps (for identifiers +// and whitespace) were taken from [Esprima](http://esprima.org) by +// Ariya Hidayat. +// +// 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 + +(function(root, mod) { + if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS + if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD + mod(root.acorn || (root.acorn = {})); // Plain browser env +})(this, function(exports) { + "use strict"; + + exports.version = "0.11.1"; + + // 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], with the caveat that inline XML is not recognized. + // + // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API + + var options, input, inputLen, sourceFile; + + exports.parse = function(inpt, opts) { + input = String(inpt); inputLen = input.length; + setOptions(opts); + initTokenState(); + var startPos = options.locations ? [tokPos, curPosition()] : tokPos; + initParserState(); + if (options.strictMode) { + strict = true; + } + return parseTopLevel(options.program || startNodeAt(startPos)); + }; + + // A second optional argument can be given to further configure + // the parser process. These options are recognized: + + var defaultOptions = exports.defaultOptions = { + strictMode: false, + playground: false, + // `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, + // Turn on `strictSemicolons` to prevent the parser from doing + // automatic semicolon insertion. + strictSemicolons: false, + // When `allowTrailingCommas` is false, the parser will not allow + // trailing commas in array and object literals. + allowTrailingCommas: true, + // By default, reserved words are not enforced. Enable + // `forbidReserved` to enforce them. When this option has the + // value "everywhere", reserved words and keywords can also not be + // used as property names. + forbidReserved: false, + // 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 + }; + + // 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 = function(inpt, pos, opts) { + input = String(inpt); inputLen = input.length; + setOptions(opts); + initTokenState(pos); + initParserState(); + return parseExpression(); + }; + + var isArray = function (obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + + function setOptions(opts) { + options = {}; + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; + sourceFile = options.sourceFile || null; + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { + tokens.push(token); + }; + } + if (isArray(options.onComment)) { + var comments = options.onComment; + options.onComment = 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(); + comment.loc.start = startLoc; + comment.loc.end = endLoc; + } + if (options.ranges) + comment.range = [start, end]; + comments.push(comment); + }; + } + if (options.ecmaVersion >= 6) { + isKeyword = isEcma6Keyword; + } else { + isKeyword = isEcma5AndLessKeyword; + } + } + + // 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. + + var getLineInfo = exports.getLineInfo = function(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreak.lastIndex = cur; + var match = lineBreak.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else break; + } + return {line: line, column: offset - cur}; + }; + + function Token() { + this.type = tokType; + this.value = tokVal; + this.start = tokStart; + this.end = tokEnd; + if (options.locations) { + this.loc = new SourceLocation(); + this.loc.end = tokEndLoc; + } + if (options.ranges) + this.range = [tokStart, tokEnd]; + } + + exports.Token = Token; + + // 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. Performing another parse or call to `tokenize` will + // reset the internal state, and invalidate existing tokenizers. + + exports.tokenize = function(inpt, opts) { + input = String(inpt); inputLen = input.length; + setOptions(opts); + initTokenState(); + skipSpace(); + + function getToken() { + lastEnd = tokEnd; + readToken(); + return new Token(); + } + getToken.jumpTo = function(pos, exprAllowed) { + tokPos = pos; + if (options.locations) { + tokCurLine = 1; + tokLineStart = lineBreak.lastIndex = 0; + var match; + while ((match = lineBreak.exec(input)) && match.index < pos) { + ++tokCurLine; + tokLineStart = match.index + match[0].length; + } + } + tokExprAllowed = !!exprAllowed; + skipSpace(); + }; + getToken.current = function() { return new Token(); }; + if (typeof Symbol !== 'undefined') { + getToken[Symbol.iterator] = function () { + return { + next: function () { + var token = getToken(); + return { + done: token.type === _eof, + value: token + }; + } + }; + }; + } + getToken.options = options; + return getToken; + }; + + // State is kept in (closure-)global variables. We already saw the + // `options`, `input`, and `inputLen` variables above. + + // The current position of the tokenizer in the input. + + var tokPos; + + // The start and end offsets of the current token. + + var tokStart, tokEnd; + + // When `options.locations` is true, these hold objects + // containing the tokens start and end line/column pairs. + + var tokStartLoc, tokEndLoc; + + // The type and value of the current token. Token types are objects, + // named by variables against which they can be compared, and + // holding properties that describe them (indicating, for example, + // the precedence of an infix operator, and the original name of a + // keyword token). The kind of value that's held in `tokVal` depends + // on the type of the token. For literals, it is the literal value, + // for operators, the operator name, and so on. + + var tokType, tokVal; + + // Internal state for the tokenizer. To distinguish between division + // operators and regular expressions, it remembers whether the last + // token was one that is allowed to be followed by an expression. In + // some cases, notably after ')' or '}' tokens, the situation + // depends on the context before the matching opening bracket, so + // tokContext keeps a stack of information about current bracketed + // forms. + + var tokContext, tokExprAllowed; + + // When `options.locations` is true, these are used to keep + // track of the current line, and know when a new line has been + // entered. + + var tokCurLine, tokLineStart; + + // These store the position of the previous token, which is useful + // when finishing a node and assigning its `end` position. + + var lastStart, lastEnd, lastEndLoc; + + // This is the parser's state. `inFunction` is used to reject + // `return` statements outside of functions, `inGenerator` to + // reject `yield`s outside of generators, `labels` to verify + // that `break` and `continue` have somewhere to jump to, and + // `strict` indicates whether strict mode is on. + + var inFunction, inGenerator, inAsync, labels, strict, + inXJSChild, inXJSTag, inType; + + function initParserState() { + lastStart = lastEnd = tokPos; + if (options.locations) lastEndLoc = curPosition(); + inFunction = inGenerator = inAsync = false; + labels = []; + skipSpace(); + readToken(); + } + + // 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. + + function raise(pos, message) { + var loc = getLineInfo(input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = tokPos; + throw err; + } + + // Reused empty array added for node fields that are always empty. + + var empty = []; + + // ## 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. + + // These are the general types. The `type` property is only used to + // make them recognizeable when debugging. + + var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"}; + var _name = {type: "name"}, _eof = {type: "eof"}; + var _jsxName = {type: "jsxName"}; + + // These are JSX-specific token types + + var _xjsName = {type: "xjsName"}, _xjsText = {type: "xjsText"}; + + // Keyword tokens. The `keyword` property (also used in keyword-like + // operators) indicates that the token originated from an + // identifier-like word, which is used when parsing property names. + // + // 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 _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"}; + var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"}; + var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true}; + var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"}; + var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"}; + var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"}; + var _let = {keyword: "let"}, _const = {keyword: "const"}; + var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true}; + var _this = {keyword: "this"}; + var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true}; + var _export = {keyword: "export"}, _import = {keyword: "import"}; + var _yield = {keyword: "yield", beforeExpr: true}; + + // The keywords that denote values. + + var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true}; + var _false = {keyword: "false", atomValue: false}; + + // Some keywords are treated as regular operators. `in` sometimes + // (when parsing `for`) needs to be tested against specifically, so + // we assign a variable name to it for quick comparing. + + var _in = {keyword: "in", binop: 7, beforeExpr: true}; + + // Map keyword names to token types. + + var keywordTypes = {"break": _break, "case": _case, "catch": _catch, + "continue": _continue, "debugger": _debugger, "default": _default, + "do": _do, "else": _else, "finally": _finally, "for": _for, + "function": _function, "if": _if, "return": _return, "switch": _switch, + "throw": _throw, "try": _try, "var": _var, "let": _let, "const": _const, + "while": _while, "with": _with, + "null": _null, "true": _true, "false": _false, "new": _new, "in": _in, + "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this, + "typeof": {keyword: "typeof", prefix: true, beforeExpr: true}, + "void": {keyword: "void", prefix: true, beforeExpr: true}, + "delete": {keyword: "delete", prefix: true, beforeExpr: true}, + "class": _class, "extends": _extends, + "export": _export, "import": _import, "yield": _yield}; + + // Punctuation token types. Again, the `type` property is purely for debugging. + + var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true}; + var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"}; + var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true}; + var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true}; + var _arrow = {type: "=>", beforeExpr: true}, _template = {type: "template"}; + var _ellipsis = {type: "...", beforeExpr: true}; + var _backQuote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true}; + var _jsxText = {type: "jsxText"}; + var _paamayimNekudotayim = { type: "::", beforeExpr: true }; + var _hash = { type: '#' }; + + // 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. `isUpdate` specifies that the node produced by + // the operator should be of type UpdateExpression rather than + // simply UnaryExpression (`++` and `--`). + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true}; + var _assign = {isAssign: true, beforeExpr: true}; + var _incDec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true}; + var _logicalOR = {binop: 1, beforeExpr: true}; + var _logicalAND = {binop: 2, beforeExpr: true}; + var _bitwiseOR = {binop: 3, beforeExpr: true}; + var _bitwiseXOR = {binop: 4, beforeExpr: true}; + var _bitwiseAND = {binop: 5, beforeExpr: true}; + var _equality = {binop: 6, beforeExpr: true}; + var _relational = {binop: 7, beforeExpr: true}; + var _bitShift = {binop: 8, beforeExpr: true}; + var _plusMin = {binop: 9, prefix: true, beforeExpr: true}; + var _modulo = {binop: 10, beforeExpr: true}; + + // '*' may be multiply or have special meaning in ES6 + var _star = {binop: 10, beforeExpr: true}; + var _exponent = {binop: 11, beforeExpr: true, rightAssociative: true}; + + // JSX tag boundaries + var _jsxTagStart = {type: "jsxTagStart"}, _jsxTagEnd = {type: "jsxTagEnd"}; + + // Provide access to the token types for external users of the + // tokenizer. + + exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR, + parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon, + dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq, + name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string, + paamayimNekudotayim: _paamayimNekudotayim, exponent: _exponent, hash: _hash, + arrow: _arrow, template: _template, star: _star, assign: _assign, + backQuote: _backQuote, dollarBraceL: _dollarBraceL, jsxName: _jsxName, + jsxText: _jsxText, jsxTagStart: _jsxTagStart, jsxTagEnd: _jsxTagEnd}; + for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw]; + + // 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. + + // Removed to create an eval-free library + + // The ECMAScript 3 reserved word list. + + var isReservedWord3 = function anonymous(str) { +switch(str.length){case 6:switch(str){case "double":case "export":case "import":case "native":case "public":case "static":case "throws":return true}return false;case 4:switch(str){case "byte":case "char":case "enum":case "goto":case "long":return true}return false;case 5:switch(str){case "class":case "final":case "float":case "short":case "super":return true}return false;case 7:switch(str){case "boolean":case "extends":case "package":case "private":return true}return false;case 9:switch(str){case "interface":case "protected":case "transient":return true}return false;case 8:switch(str){case "abstract":case "volatile":return true}return false;case 10:return str === "implements";case 3:return str === "int";case 12:return str === "synchronized";} +}; + + // ECMAScript 5 reserved words. + + var isReservedWord5 = function anonymous(str) { +switch(str.length){case 5:switch(str){case "class":case "super":case "const":return true}return false;case 6:switch(str){case "export":case "import":return true}return false;case 4:return str === "enum";case 7:return str === "extends";} +}; + + // The additional reserved words in strict mode. + + var isStrictReservedWord = function anonymous(str) { +switch(str.length){case 9:switch(str){case "interface":case "protected":return true}return false;case 7:switch(str){case "package":case "private":return true}return false;case 6:switch(str){case "public":case "static":return true}return false;case 10:return str === "implements";case 3:return str === "let";case 5:return str === "yield";} +}; + + // The forbidden variable names in strict mode. + + var isStrictBadIdWord = function anonymous(str) { +switch(str){case "eval":case "arguments":return true}return false; +}; + + // 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 isEcma5AndLessKeyword = function anonymous(str) { +switch(str.length){case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 7:switch(str){case "default":case "finally":return true}return false;case 10:return str === "instanceof";} +}; + + var ecma6AndLessKeywords = ecma5AndLessKeywords + " let const class extends export import yield"; + + var isEcma6Keyword = function anonymous(str) { +switch(str.length){case 5:switch(str){case "break":case "catch":case "throw":case "while":case "false":case "const":case "class":case "yield":return true}return false;case 4:switch(str){case "case":case "else":case "with":case "null":case "true":case "void":case "this":return true}return false;case 6:switch(str){case "return":case "switch":case "typeof":case "delete":case "export":case "import":return true}return false;case 3:switch(str){case "for":case "try":case "var":case "new":case "let":return true}return false;case 8:switch(str){case "continue":case "debugger":case "function":return true}return false;case 7:switch(str){case "default":case "finally":case "extends":return true}return false;case 2:switch(str){case "do":case "if":case "in":return true}return false;case 10:return str === "instanceof";} +}; + + var isKeyword = isEcma5AndLessKeyword; + + // ## 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 nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC"; + var nonASCIIidentifierChars = "\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19B0-\u19C0\u19C8\u19C9\u19D0-\u19D9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F"; + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + + var decimalNumber = /^\d+$/; + var hexNumber = /^[\da-fA-F]+$/; + + // Whether a single character denotes a newline. + + var newline = /[\n\r\u2028\u2029]/; + + function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code == 0x2029; + } + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + var lineBreak = /\r\n|[\n\r\u2028\u2029]/g; + + // Test whether a given character code starts an identifier. + + var isIdentifierStart = exports.isIdentifierStart = function(code) { + if (code < 65) return code === 36; + if (code < 91) return true; + if (code < 97) return code === 95; + if (code < 123)return true; + return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); + }; + + // Test whether a given character is part of an identifier. + + var isIdentifierChar = exports.isIdentifierChar = function(code) { + 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; + return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); + }; + + // ## Tokenizer + + // These are used when `options.locations` is on, for the + // `tokStartLoc` and `tokEndLoc` properties. + + function Position(line, col) { + this.line = line; + this.column = col; + } + + Position.prototype.offset = function(n) { + return new Position(this.line, this.column + n); + }; + + function curPosition() { + return new Position(tokCurLine, tokPos - tokLineStart); + } + + // Reset the token state. Used at the start of a parse. + + function initTokenState(pos) { + if (pos) { + tokPos = pos; + tokLineStart = Math.max(0, input.lastIndexOf("\n", pos)); + tokCurLine = input.slice(0, tokLineStart).split(newline).length; + } else { + tokCurLine = 1; + tokPos = tokLineStart = 0; + } + tokType = _eof; + tokContext = [b_stat]; + tokExprAllowed = true; + inType = strict = false; + if (tokPos === 0 && options.allowHashBang && input.slice(0, 2) === '#!') { + skipLineComment(2); + } + } + + // 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 b_stat = {token: "{", isExpr: false}, b_expr = {token: "{", isExpr: true}, b_tmpl = {token: "${", isExpr: true}; + var p_stat = {token: "(", isExpr: false}, p_expr = {token: "(", isExpr: true}; + var q_tmpl = {token: "`", isExpr: true}, f_expr = {token: "function", isExpr: true}; + var j_oTag = {token: "...", isExpr: true}; + + function curTokContext() { + return tokContext[tokContext.length - 1]; + } + + function braceIsBlock(prevType) { + var parent; + if (prevType === _colon && (parent = curTokContext()).token == "{") + return !parent.isExpr; + if (prevType === _return) + return newline.test(input.slice(lastEnd, tokStart)); + if (prevType === _else || prevType === _semi || prevType === _eof) + return true; + if (prevType == _braceL) + return curTokContext() === b_stat; + return !tokExprAllowed; + } + + // Called at the end of every token. Sets `tokEnd`, `tokVal`, and + // maintains `tokContext` and `tokExprAllowed`, and skips the space + // after the token, so that the next one's `tokStart` will point at + // the right position. + + function finishToken(type, val) { + tokEnd = tokPos; + if (options.locations) tokEndLoc = curPosition(); + var prevType = tokType, preserveSpace = false; + tokType = type; + tokVal = val; + + // Update context info + if (type === _parenR || type === _braceR) { + var out = tokContext.pop(); + if (out === b_tmpl) { + preserveSpace = tokExprAllowed = true; + } else if (out === b_stat && curTokContext() === f_expr) { + tokContext.pop(); + tokExprAllowed = false; + } else { + tokExprAllowed = !(out && out.isExpr); + } + } else if (type === _braceL) { + switch (curTokContext()) { + case j_oTag: tokContext.push(b_expr); break; + case j_expr: tokContext.push(b_tmpl); break; + default: tokContext.push(braceIsBlock(prevType) ? b_stat : b_expr); + } + tokExprAllowed = true; + } else if (type === _dollarBraceL) { + tokContext.push(b_tmpl); + tokExprAllowed = true; + } else if (type == _parenL) { + var statementParens = prevType === _if || prevType === _for || prevType === _with || prevType === _while; + tokContext.push(statementParens ? p_stat : p_expr); + tokExprAllowed = true; + } else if (type == _incDec) { + // tokExprAllowed stays unchanged + } else if (type.keyword && prevType == _dot) { + tokExprAllowed = false; + } else if (type == _function) { + if (curTokContext() !== b_stat) { + tokContext.push(f_expr); + } + tokExprAllowed = false; + } else if (type === _backQuote) { + if (curTokContext() === q_tmpl) { + tokContext.pop(); + } else { + tokContext.push(q_tmpl); + preserveSpace = true; + } + tokExprAllowed = false; + } else if (type === _jsxTagStart) { + tokContext.push(j_expr); // treat as beginning of JSX expression + tokContext.push(j_oTag); // start opening tag context + tokExprAllowed = false; + } else if (type === _jsxTagEnd) { + var out = tokContext.pop(); + if (out === j_oTag && prevType === _slash || out === j_cTag) { + tokContext.pop(); + preserveSpace = tokExprAllowed = curTokContext() === j_expr; + } else { + preserveSpace = tokExprAllowed = true; + } + } else if (type === _jsxText) { + preserveSpace = tokExprAllowed = true; + } else if (type === _slash && prevType === _jsxTagStart) { + tokContext.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore + tokContext.push(j_cTag); // reconsider as closing tag context + tokExprAllowed = false; + } else { + tokExprAllowed = type.beforeExpr; + } + + if (!preserveSpace) skipSpace(); + } + + function skipBlockComment() { + var startLoc = options.onComment && options.locations && curPosition(); + var start = tokPos, end = input.indexOf("*/", tokPos += 2); + if (end === -1) raise(tokPos - 2, "Unterminated comment"); + tokPos = end + 2; + if (options.locations) { + lineBreak.lastIndex = start; + var match; + while ((match = lineBreak.exec(input)) && match.index < tokPos) { + ++tokCurLine; + tokLineStart = match.index + match[0].length; + } + } + if (options.onComment) + options.onComment(true, input.slice(start + 2, end), start, tokPos, + startLoc, options.locations && curPosition()); + } + + function skipLineComment(startSkip) { + var start = tokPos; + var startLoc = options.onComment && options.locations && curPosition(); + var ch = input.charCodeAt(tokPos+=startSkip); + while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++tokPos; + ch = input.charCodeAt(tokPos); + } + if (options.onComment) + options.onComment(false, input.slice(start + startSkip, tokPos), start, tokPos, + startLoc, options.locations && curPosition()); + } + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + function skipSpace() { + while (tokPos < inputLen) { + var ch = input.charCodeAt(tokPos); + if (ch === 32) { // ' ' + ++tokPos; + } else if (ch === 13) { + ++tokPos; + var next = input.charCodeAt(tokPos); + if (next === 10) { + ++tokPos; + } + if (options.locations) { + ++tokCurLine; + tokLineStart = tokPos; + } + } else if (ch === 10 || ch === 8232 || ch === 8233) { + ++tokPos; + if (options.locations) { + ++tokCurLine; + tokLineStart = tokPos; + } + } else if (ch > 8 && ch < 14) { + ++tokPos; + } else if (ch === 47) { // '/' + var next = input.charCodeAt(tokPos + 1); + if (next === 42) { // '*' + skipBlockComment(); + } else if (next === 47) { // '/' + skipLineComment(2); + } else break; + } else if (ch === 160) { // '\xa0' + ++tokPos; + } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++tokPos; + } else { + break; + } + } + } + + // ### 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. + // + function readToken_dot() { + var next = input.charCodeAt(tokPos + 1); + if (next >= 48 && next <= 57) return readNumber(true); + var next2 = input.charCodeAt(tokPos + 2); + if (options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + tokPos += 3; + return finishToken(_ellipsis); + } else { + ++tokPos; + return finishToken(_dot); + } + } + + function readToken_slash() { // '/' + var next = input.charCodeAt(tokPos + 1); + if (tokExprAllowed) {++tokPos; return readRegexp();} + if (next === 61) return finishOp(_assign, 2); + return finishOp(_slash, 1); + } + + function readToken_modulo() { // '%' + var next = input.charCodeAt(tokPos + 1); + if (next === 61) return finishOp(_assign, 2); + return finishOp(_modulo, 1); + } + + function readToken_mult() { // '*' + var type = _star; + var width = 1; + var next = input.charCodeAt(tokPos + 1); + + if (options.ecmaVersion >= 7 && next === 42) { // '*' + width++; + next = input.charCodeAt(tokPos + 2); + type = _exponent; + } + + if (next === 61) { // '=' + width++; + type = _assign; + } + + return finishOp(type, width); + } + + function readToken_pipe_amp(code) { // '|&' + var next = input.charCodeAt(tokPos + 1); + if (next === code) { + if (options.playground && input.charCodeAt(tokPos + 2) === 61) return finishOp(_assign, 3); + return finishOp(code === 124 ? _logicalOR : _logicalAND, 2); + } + if (next === 61) return finishOp(_assign, 2); + return finishOp(code === 124 ? _bitwiseOR : _bitwiseAND, 1); + } + + function readToken_caret() { // '^' + var next = input.charCodeAt(tokPos + 1); + if (next === 61) return finishOp(_assign, 2); + return finishOp(_bitwiseXOR, 1); + } + + function readToken_plus_min(code) { // '+-' + var next = input.charCodeAt(tokPos + 1); + if (next === code) { + if (next == 45 && input.charCodeAt(tokPos + 2) == 62 && + newline.test(input.slice(lastEnd, tokPos))) { + // A `-->` line comment + skipLineComment(3); + skipSpace(); + return readToken(); + } + return finishOp(_incDec, 2); + } + if (next === 61) return finishOp(_assign, 2); + return finishOp(_plusMin, 1); + } + + function readToken_lt_gt(code) { // '<>' + var next = input.charCodeAt(tokPos + 1); + var size = 1; + if (!inType && next === code) { + size = code === 62 && input.charCodeAt(tokPos + 2) === 62 ? 3 : 2; + if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1); + return finishOp(_bitShift, size); + } + if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 && + input.charCodeAt(tokPos + 3) == 45) { + // `0)next()}function looking_at(str){return S.text.substr(S.pos,str.length)==str}function find(what,signal_eof){var pos=S.text.indexOf(what,S.pos);if(signal_eof&&pos==-1)throw EX_EOF;return pos}function start_token(){S.tokline=S.line;S.tokcol=S.col;S.tokpos=S.pos}var prev_was_dot=false;function token(type,value,is_comment){S.regex_allowed=type=="operator"&&!UNARY_POSTFIX(value)||type=="keyword"&&KEYWORDS_BEFORE_EXPRESSION(value)||type=="punc"&&PUNC_BEFORE_EXPRESSION(value);prev_was_dot=type=="punc"&&value==".";var ret={type:type,value:value,line:S.tokline,col:S.tokcol,pos:S.tokpos,endpos:S.pos,nlb:S.newline_before,file:filename};if(!is_comment){ret.comments_before=S.comments_before;S.comments_before=[];for(var i=0,len=ret.comments_before.length;i0;--n){var digit=parseInt(next(true),16);if(isNaN(digit))parse_error("Invalid hex-character pattern in string");num=num<<4|digit}return num}var read_string=with_eof_error("Unterminated string constant",function(){var quote=next(),ret="";for(;;){var ch=next(true);if(ch=="\\"){var octal_len=0,first=null;ch=read_while(function(ch){if(ch>="0"&&ch<="7"){if(!first){first=ch;return++octal_len}else if(first<="3"&&octal_len<=2)return++octal_len;else if(first>="4"&&octal_len<=1)return++octal_len}return false});if(octal_len>0)ch=String.fromCharCode(parseInt(ch,8));else ch=read_escaped_char(true)}else if(ch==quote)break;ret+=ch}return token("string",ret)});function skip_line_comment(type){var regex_allowed=S.regex_allowed;var i=find("\n"),ret;if(i==-1){ret=S.text.substr(S.pos);S.pos=S.text.length}else{ret=S.text.substring(S.pos,i);S.pos=i}S.comments_before.push(token(type,ret,true));S.regex_allowed=regex_allowed;return next_token()}var skip_multiline_comment=with_eof_error("Unterminated multiline comment",function(){var regex_allowed=S.regex_allowed;var i=find("*/",true);var text=S.text.substring(S.pos,i);var a=text.split("\n"),n=a.length;S.pos=i+2;S.line+=n-1;if(n>1)S.col=a[n-1].length;else S.col+=a[n-1].length;S.col+=2;var nlb=S.newline_before=S.newline_before||text.indexOf("\n")>=0;S.comments_before.push(token("comment2",text,true));S.regex_allowed=regex_allowed;S.newline_before=nlb;return next_token()});function read_name(){var backslash=false,name="",ch,escaped=false,hex;while((ch=peek())!=null){if(!backslash){if(ch=="\\")escaped=backslash=true,next();else if(is_identifier_char(ch))name+=next();else break}else{if(ch!="u")parse_error("Expecting UnicodeEscapeSequence -- uXXXX");ch=read_escaped_char();if(!is_identifier_char(ch))parse_error("Unicode char: "+ch.charCodeAt(0)+" is not valid in identifier");name+=ch;backslash=false}}if(KEYWORDS(name)&&escaped){hex=name.charCodeAt(0).toString(16).toUpperCase();name="\\u"+"0000".substr(hex.length)+hex+name.slice(1)}return name}var read_regexp=with_eof_error("Unterminated regular expression",function(regexp){var prev_backslash=false,ch,in_class=false;while(ch=next(true))if(prev_backslash){regexp+="\\"+ch;prev_backslash=false}else if(ch=="["){in_class=true;regexp+=ch}else if(ch=="]"&&in_class){in_class=false;regexp+=ch}else if(ch=="/"&&!in_class){break}else if(ch=="\\"){prev_backslash=true}else{regexp+=ch}var mods=read_name();return token("regexp",new RegExp(regexp,mods))});function read_operator(prefix){function grow(op){if(!peek())return op;var bigger=op+peek();if(OPERATORS(bigger)){next();return grow(bigger)}else{return op}}return token("operator",grow(prefix||next()))}function handle_slash(){next();switch(peek()){case"/":next();return skip_line_comment("comment1");case"*":next();return skip_multiline_comment()}return S.regex_allowed?read_regexp(""):read_operator("/")}function handle_dot(){next();return is_digit(peek().charCodeAt(0))?read_num("."):token("punc",".")}function read_word(){var word=read_name();if(prev_was_dot)return token("name",word);return KEYWORDS_ATOM(word)?token("atom",word):!KEYWORDS(word)?token("name",word):OPERATORS(word)?token("operator",word):token("keyword",word)}function with_eof_error(eof_error,cont){return function(x){try{return cont(x)}catch(ex){if(ex===EX_EOF)parse_error(eof_error);else throw ex}}}function next_token(force_regexp){if(force_regexp!=null)return read_regexp(force_regexp);skip_whitespace();start_token();if(html5_comments){if(looking_at("")&&S.newline_before){forward(3);return skip_line_comment("comment4")}}var ch=peek();if(!ch)return token("eof");var code=ch.charCodeAt(0);switch(code){case 34:case 39:return read_string();case 46:return handle_dot();case 47:return handle_slash()}if(is_digit(code))return read_num();if(PUNC_CHARS(ch))return token("punc",next());if(OPERATOR_CHARS(ch))return read_operator();if(code==92||is_identifier_start(code))return read_word();parse_error("Unexpected character '"+ch+"'")}next_token.context=function(nc){if(nc)S=nc;return S};return next_token}var UNARY_PREFIX=makePredicate(["typeof","void","delete","--","++","!","~","-","+"]);var UNARY_POSTFIX=makePredicate(["--","++"]);var ASSIGNMENT=makePredicate(["=","+=","-=","/=","*=","%=",">>=","<<=",">>>=","|=","^=","&="]);var PRECEDENCE=function(a,ret){for(var i=0;i","<=",">=","in","instanceof"],[">>","<<",">>>"],["+","-"],["*","/","%"]],{});var STATEMENTS_WITH_LABELS=array_to_hash(["for","do","while","switch"]);var ATOMIC_START_TOKEN=array_to_hash(["atom","num","string","regexp","name"]);function parse($TEXT,options){options=defaults(options,{strict:false,filename:null,toplevel:null,expression:false,html5_comments:true,bare_returns:false});var S={input:typeof $TEXT=="string"?tokenizer($TEXT,options.filename,options.html5_comments):$TEXT,token:null,prev:null,peeked:null,in_function:0,in_directives:true,in_loop:0,labels:[]};S.token=next();function is(type,value){return is_token(S.token,type,value)}function peek(){return S.peeked||(S.peeked=S.input())}function next(){S.prev=S.token;if(S.peeked){S.token=S.peeked;S.peeked=null}else{S.token=S.input()}S.in_directives=S.in_directives&&(S.token.type=="string"||is("punc",";"));return S.token}function prev(){return S.prev}function croak(msg,line,col,pos){var ctx=S.input.context();js_error(msg,ctx.filename,line!=null?line:ctx.tokline,col!=null?col:ctx.tokcol,pos!=null?pos:ctx.tokpos)}function token_error(token,msg){croak(msg,token.line,token.col)}function unexpected(token){if(token==null)token=S.token;token_error(token,"Unexpected token: "+token.type+" ("+token.value+")")}function expect_token(type,val){if(is(type,val)){return next()}token_error(S.token,"Unexpected token "+S.token.type+" «"+S.token.value+"»"+", expected "+type+" «"+val+"»")}function expect(punc){return expect_token("punc",punc)}function can_insert_semicolon(){return!options.strict&&(S.token.nlb||is("eof")||is("punc","}"))}function semicolon(){if(is("punc",";"))next();else if(!can_insert_semicolon())unexpected()}function parenthesised(){expect("(");var exp=expression(true);expect(")");return exp}function embed_tokens(parser){return function(){var start=S.token;var expr=parser();var end=prev();expr.start=start;expr.end=end;return expr}}function handle_regexp(){if(is("operator","/")||is("operator","/=")){S.peeked=null;S.token=S.input(S.token.value.substr(1))}}var statement=embed_tokens(function(){var tmp;handle_regexp();switch(S.token.type){case"string":var dir=S.in_directives,stat=simple_statement();if(dir&&stat.body instanceof AST_String&&!is("punc",","))return new AST_Directive({value:stat.body.value});return stat;case"num":case"regexp":case"operator":case"atom":return simple_statement();case"name":return is_token(peek(),"punc",":")?labeled_statement():simple_statement();case"punc":switch(S.token.value){case"{":return new AST_BlockStatement({start:S.token,body:block_(),end:prev()});case"[":case"(":return simple_statement();case";":next();return new AST_EmptyStatement;default:unexpected()}case"keyword":switch(tmp=S.token.value,next(),tmp){case"break":return break_cont(AST_Break);case"continue":return break_cont(AST_Continue);case"debugger":semicolon();return new AST_Debugger;case"do":return new AST_Do({body:in_loop(statement),condition:(expect_token("keyword","while"),tmp=parenthesised(),semicolon(),tmp)});case"while":return new AST_While({condition:parenthesised(),body:in_loop(statement)});case"for":return for_();case"function":return function_(AST_Defun);case"if":return if_();case"return":if(S.in_function==0&&!options.bare_returns)croak("'return' outside of function");return new AST_Return({value:is("punc",";")?(next(),null):can_insert_semicolon()?null:(tmp=expression(true),semicolon(),tmp)});case"switch":return new AST_Switch({expression:parenthesised(),body:in_loop(switch_body_)});case"throw":if(S.token.nlb)croak("Illegal newline after 'throw'");return new AST_Throw({value:(tmp=expression(true),semicolon(),tmp)});case"try":return try_();case"var":return tmp=var_(),semicolon(),tmp;case"const":return tmp=const_(),semicolon(),tmp;case"with":return new AST_With({expression:parenthesised(),body:statement()});default:unexpected()}}});function labeled_statement(){var label=as_symbol(AST_Label);if(find_if(function(l){return l.name==label.name},S.labels)){croak("Label "+label.name+" defined twice")}expect(":");S.labels.push(label);var stat=statement();S.labels.pop();if(!(stat instanceof AST_IterationStatement)){label.references.forEach(function(ref){if(ref instanceof AST_Continue){ref=ref.label.start;croak("Continue label `"+label.name+"` refers to non-IterationStatement.",ref.line,ref.col,ref.pos)}})}return new AST_LabeledStatement({body:stat,label:label})}function simple_statement(tmp){return new AST_SimpleStatement({body:(tmp=expression(true),semicolon(),tmp)})}function break_cont(type){var label=null,ldef;if(!can_insert_semicolon()){label=as_symbol(AST_LabelRef,true)}if(label!=null){ldef=find_if(function(l){return l.name==label.name},S.labels);if(!ldef)croak("Undefined label "+label.name);label.thedef=ldef}else if(S.in_loop==0)croak(type.TYPE+" not inside a loop or switch");semicolon();var stat=new type({label:label});if(ldef)ldef.references.push(stat);return stat}function for_(){expect("(");var init=null;if(!is("punc",";")){init=is("keyword","var")?(next(),var_(true)):expression(true,true);if(is("operator","in")){if(init instanceof AST_Var&&init.definitions.length>1)croak("Only one variable declaration allowed in for..in loop");next();return for_in(init)}}return regular_for(init)}function regular_for(init){expect(";");var test=is("punc",";")?null:expression(true);expect(";");var step=is("punc",")")?null:expression(true);expect(")");return new AST_For({init:init,condition:test,step:step,body:in_loop(statement)})}function for_in(init){var lhs=init instanceof AST_Var?init.definitions[0].name:null;var obj=expression(true);expect(")");return new AST_ForIn({init:init,name:lhs,object:obj,body:in_loop(statement)})}var function_=function(ctor){var in_statement=ctor===AST_Defun;var name=is("name")?as_symbol(in_statement?AST_SymbolDefun:AST_SymbolLambda):null;if(in_statement&&!name)unexpected();expect("(");return new ctor({name:name,argnames:function(first,a){while(!is("punc",")")){if(first)first=false;else expect(",");a.push(as_symbol(AST_SymbolFunarg))}next();return a}(true,[]),body:function(loop,labels){++S.in_function;S.in_directives=true;S.in_loop=0;S.labels=[];var a=block_();--S.in_function;S.in_loop=loop;S.labels=labels;return a}(S.in_loop,S.labels)})};function if_(){var cond=parenthesised(),body=statement(),belse=null;if(is("keyword","else")){next();belse=statement()}return new AST_If({condition:cond,body:body,alternative:belse})}function block_(){expect("{");var a=[];while(!is("punc","}")){if(is("eof"))unexpected();a.push(statement())}next();return a}function switch_body_(){expect("{");var a=[],cur=null,branch=null,tmp;while(!is("punc","}")){if(is("eof"))unexpected();if(is("keyword","case")){if(branch)branch.end=prev();cur=[];branch=new AST_Case({start:(tmp=S.token,next(),tmp),expression:expression(true),body:cur});a.push(branch);expect(":")}else if(is("keyword","default")){if(branch)branch.end=prev();cur=[];branch=new AST_Default({start:(tmp=S.token,next(),expect(":"),tmp),body:cur});a.push(branch)}else{if(!cur)unexpected();cur.push(statement())}}if(branch)branch.end=prev();next();return a}function try_(){var body=block_(),bcatch=null,bfinally=null;if(is("keyword","catch")){var start=S.token;next();expect("(");var name=as_symbol(AST_SymbolCatch);expect(")");bcatch=new AST_Catch({start:start,argname:name,body:block_(),end:prev()})}if(is("keyword","finally")){var start=S.token;next();bfinally=new AST_Finally({start:start,body:block_(),end:prev()})}if(!bcatch&&!bfinally)croak("Missing catch/finally blocks");return new AST_Try({body:body,bcatch:bcatch,bfinally:bfinally})}function vardefs(no_in,in_const){var a=[];for(;;){a.push(new AST_VarDef({start:S.token,name:as_symbol(in_const?AST_SymbolConst:AST_SymbolVar),value:is("operator","=")?(next(),expression(false,no_in)):null,end:prev()}));if(!is("punc",","))break;next()}return a}var var_=function(no_in){return new AST_Var({start:prev(),definitions:vardefs(no_in,false),end:prev()})};var const_=function(){return new AST_Const({start:prev(),definitions:vardefs(false,true),end:prev()})};var new_=function(){var start=S.token;expect_token("operator","new");var newexp=expr_atom(false),args;if(is("punc","(")){next();args=expr_list(")")}else{args=[]}return subscripts(new AST_New({start:start,expression:newexp,args:args,end:prev()}),true)};function as_atom_node(){var tok=S.token,ret;switch(tok.type){case"name":case"keyword":ret=_make_symbol(AST_SymbolRef);break;case"num":ret=new AST_Number({start:tok,end:tok,value:tok.value});break;case"string":ret=new AST_String({start:tok,end:tok,value:tok.value});break;case"regexp":ret=new AST_RegExp({start:tok,end:tok,value:tok.value});break;case"atom":switch(tok.value){case"false":ret=new AST_False({start:tok,end:tok});break;case"true":ret=new AST_True({start:tok,end:tok});break;case"null":ret=new AST_Null({start:tok,end:tok});break}break}next();return ret}var expr_atom=function(allow_calls){if(is("operator","new")){return new_()}var start=S.token;if(is("punc")){switch(start.value){case"(":next();var ex=expression(true);ex.start=start;ex.end=S.token;expect(")");return subscripts(ex,allow_calls);case"[":return subscripts(array_(),allow_calls);case"{":return subscripts(object_(),allow_calls)}unexpected()}if(is("keyword","function")){next();var func=function_(AST_Function);func.start=start;func.end=prev();return subscripts(func,allow_calls)}if(ATOMIC_START_TOKEN[S.token.type]){return subscripts(as_atom_node(),allow_calls)}unexpected()};function expr_list(closing,allow_trailing_comma,allow_empty){var first=true,a=[];while(!is("punc",closing)){if(first)first=false;else expect(",");if(allow_trailing_comma&&is("punc",closing))break;if(is("punc",",")&&allow_empty){a.push(new AST_Hole({start:S.token,end:S.token}))}else{a.push(expression(false))}}next();return a}var array_=embed_tokens(function(){expect("[");return new AST_Array({elements:expr_list("]",!options.strict,true)})});var object_=embed_tokens(function(){expect("{");var first=true,a=[];while(!is("punc","}")){if(first)first=false;else expect(",");if(!options.strict&&is("punc","}"))break;var start=S.token;var type=start.type;var name=as_property_name();if(type=="name"&&!is("punc",":")){if(name=="get"){a.push(new AST_ObjectGetter({start:start,key:as_atom_node(),value:function_(AST_Accessor),end:prev()}));continue}if(name=="set"){a.push(new AST_ObjectSetter({start:start,key:as_atom_node(),value:function_(AST_Accessor),end:prev()}));continue}}expect(":");a.push(new AST_ObjectKeyVal({start:start,key:name,value:expression(false),end:prev()}))}next();return new AST_Object({properties:a})});function as_property_name(){var tmp=S.token;next();switch(tmp.type){case"num":case"string":case"name":case"operator":case"keyword":case"atom":return tmp.value;default:unexpected()}}function as_name(){var tmp=S.token;next();switch(tmp.type){case"name":case"operator":case"keyword":case"atom":return tmp.value;default:unexpected()}}function _make_symbol(type){var name=S.token.value;return new(name=="this"?AST_This:type)({name:String(name),start:S.token,end:S.token})}function as_symbol(type,noerror){if(!is("name")){if(!noerror)croak("Name expected");return null}var sym=_make_symbol(type);next();return sym}var subscripts=function(expr,allow_calls){var start=expr.start;if(is("punc",".")){next();return subscripts(new AST_Dot({start:start,expression:expr,property:as_name(),end:prev()}),allow_calls)}if(is("punc","[")){next();var prop=expression(true);expect("]");return subscripts(new AST_Sub({start:start,expression:expr,property:prop,end:prev()}),allow_calls)}if(allow_calls&&is("punc","(")){next();return subscripts(new AST_Call({start:start,expression:expr,args:expr_list(")"),end:prev()}),true)}return expr};var maybe_unary=function(allow_calls){var start=S.token;if(is("operator")&&UNARY_PREFIX(start.value)){next();handle_regexp();var ex=make_unary(AST_UnaryPrefix,start.value,maybe_unary(allow_calls));ex.start=start;ex.end=prev();return ex}var val=expr_atom(allow_calls);while(is("operator")&&UNARY_POSTFIX(S.token.value)&&!S.token.nlb){val=make_unary(AST_UnaryPostfix,S.token.value,val);val.start=start;val.end=S.token;next()}return val};function make_unary(ctor,op,expr){if((op=="++"||op=="--")&&!is_assignable(expr))croak("Invalid use of "+op+" operator");return new ctor({operator:op,expression:expr})}var expr_op=function(left,min_prec,no_in){var op=is("operator")?S.token.value:null;if(op=="in"&&no_in)op=null;var prec=op!=null?PRECEDENCE[op]:null;if(prec!=null&&prec>min_prec){next();var right=expr_op(maybe_unary(true),prec,no_in);return expr_op(new AST_Binary({start:left.start,left:left,operator:op,right:right,end:right.end}),min_prec,no_in)}return left};function expr_ops(no_in){return expr_op(maybe_unary(true),0,no_in)}var maybe_conditional=function(no_in){var start=S.token;var expr=expr_ops(no_in);if(is("operator","?")){next();var yes=expression(false);expect(":");return new AST_Conditional({start:start,condition:expr,consequent:yes,alternative:expression(false,no_in),end:prev()})}return expr};function is_assignable(expr){if(!options.strict)return true;if(expr instanceof AST_This)return false;return expr instanceof AST_PropAccess||expr instanceof AST_Symbol}var maybe_assign=function(no_in){var start=S.token;var left=maybe_conditional(no_in),val=S.token.value;if(is("operator")&&ASSIGNMENT(val)){if(is_assignable(left)){next();return new AST_Assign({start:start,left:left,operator:val,right:maybe_assign(no_in),end:prev()})}croak("Invalid assignment")}return left};var expression=function(commas,no_in){var start=S.token;var expr=maybe_assign(no_in);if(commas&&is("punc",",")){next();return new AST_Seq({start:start,car:expr,cdr:expression(true,no_in),end:peek()})}return expr};function in_loop(cont){++S.in_loop;var ret=cont();--S.in_loop;return ret}if(options.expression){return expression(true)}return function(){var start=S.token;var body=[];while(!is("eof"))body.push(statement());var end=prev();var toplevel=options.toplevel; +if(toplevel){toplevel.body=toplevel.body.concat(body);toplevel.end=end}else{toplevel=new AST_Toplevel({start:start,body:body,end:end})}return toplevel}()}/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";function TreeTransformer(before,after){TreeWalker.call(this);this.before=before;this.after=after}TreeTransformer.prototype=new TreeWalker;(function(undefined){function _(node,descend){node.DEFMETHOD("transform",function(tw,in_list){var x,y;tw.push(this);if(tw.before)x=tw.before(this,descend,in_list);if(x===undefined){if(!tw.after){x=this;descend(x,tw)}else{tw.stack[tw.stack.length-1]=x=this.clone();descend(x,tw);y=tw.after(x,in_list);if(y!==undefined)x=y}}tw.pop();return x})}function do_list(list,tw){return MAP(list,function(node){return node.transform(tw,true)})}_(AST_Node,noop);_(AST_LabeledStatement,function(self,tw){self.label=self.label.transform(tw);self.body=self.body.transform(tw)});_(AST_SimpleStatement,function(self,tw){self.body=self.body.transform(tw)});_(AST_Block,function(self,tw){self.body=do_list(self.body,tw)});_(AST_DWLoop,function(self,tw){self.condition=self.condition.transform(tw);self.body=self.body.transform(tw)});_(AST_For,function(self,tw){if(self.init)self.init=self.init.transform(tw);if(self.condition)self.condition=self.condition.transform(tw);if(self.step)self.step=self.step.transform(tw);self.body=self.body.transform(tw)});_(AST_ForIn,function(self,tw){self.init=self.init.transform(tw);self.object=self.object.transform(tw);self.body=self.body.transform(tw)});_(AST_With,function(self,tw){self.expression=self.expression.transform(tw);self.body=self.body.transform(tw)});_(AST_Exit,function(self,tw){if(self.value)self.value=self.value.transform(tw)});_(AST_LoopControl,function(self,tw){if(self.label)self.label=self.label.transform(tw)});_(AST_If,function(self,tw){self.condition=self.condition.transform(tw);self.body=self.body.transform(tw);if(self.alternative)self.alternative=self.alternative.transform(tw)});_(AST_Switch,function(self,tw){self.expression=self.expression.transform(tw);self.body=do_list(self.body,tw)});_(AST_Case,function(self,tw){self.expression=self.expression.transform(tw);self.body=do_list(self.body,tw)});_(AST_Try,function(self,tw){self.body=do_list(self.body,tw);if(self.bcatch)self.bcatch=self.bcatch.transform(tw);if(self.bfinally)self.bfinally=self.bfinally.transform(tw)});_(AST_Catch,function(self,tw){self.argname=self.argname.transform(tw);self.body=do_list(self.body,tw)});_(AST_Definitions,function(self,tw){self.definitions=do_list(self.definitions,tw)});_(AST_VarDef,function(self,tw){self.name=self.name.transform(tw);if(self.value)self.value=self.value.transform(tw)});_(AST_Lambda,function(self,tw){if(self.name)self.name=self.name.transform(tw);self.argnames=do_list(self.argnames,tw);self.body=do_list(self.body,tw)});_(AST_Call,function(self,tw){self.expression=self.expression.transform(tw);self.args=do_list(self.args,tw)});_(AST_Seq,function(self,tw){self.car=self.car.transform(tw);self.cdr=self.cdr.transform(tw)});_(AST_Dot,function(self,tw){self.expression=self.expression.transform(tw)});_(AST_Sub,function(self,tw){self.expression=self.expression.transform(tw);self.property=self.property.transform(tw)});_(AST_Unary,function(self,tw){self.expression=self.expression.transform(tw)});_(AST_Binary,function(self,tw){self.left=self.left.transform(tw);self.right=self.right.transform(tw)});_(AST_Conditional,function(self,tw){self.condition=self.condition.transform(tw);self.consequent=self.consequent.transform(tw);self.alternative=self.alternative.transform(tw)});_(AST_Array,function(self,tw){self.elements=do_list(self.elements,tw)});_(AST_Object,function(self,tw){self.properties=do_list(self.properties,tw)});_(AST_ObjectProperty,function(self,tw){self.value=self.value.transform(tw)})})();/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";function SymbolDef(scope,index,orig){this.name=orig.name;this.orig=[orig];this.scope=scope;this.references=[];this.global=false;this.mangled_name=null;this.undeclared=false;this.constant=false;this.index=index}SymbolDef.prototype={unmangleable:function(options){return this.global&&!(options&&options.toplevel)||this.undeclared||!(options&&options.eval)&&(this.scope.uses_eval||this.scope.uses_with)},mangle:function(options){if(!this.mangled_name&&!this.unmangleable(options)){var s=this.scope;if(!options.screw_ie8&&this.orig[0]instanceof AST_SymbolLambda)s=s.parent_scope;this.mangled_name=s.next_mangled(options,this)}}};AST_Toplevel.DEFMETHOD("figure_out_scope",function(options){options=defaults(options,{screw_ie8:false});var self=this;var scope=self.parent_scope=null;var defun=null;var nesting=0;var tw=new TreeWalker(function(node,descend){if(options.screw_ie8&&node instanceof AST_Catch){var save_scope=scope;scope=new AST_Scope(node);scope.init_scope_vars(nesting);scope.parent_scope=save_scope;descend();scope=save_scope;return true}if(node instanceof AST_Scope){node.init_scope_vars(nesting);var save_scope=node.parent_scope=scope;var save_defun=defun;defun=scope=node;++nesting;descend();--nesting;scope=save_scope;defun=save_defun;return true}if(node instanceof AST_Directive){node.scope=scope;push_uniq(scope.directives,node.value);return true}if(node instanceof AST_With){for(var s=scope;s;s=s.parent_scope)s.uses_with=true;return}if(node instanceof AST_Symbol){node.scope=scope}if(node instanceof AST_SymbolLambda){defun.def_function(node)}else if(node instanceof AST_SymbolDefun){(node.scope=defun.parent_scope).def_function(node)}else if(node instanceof AST_SymbolVar||node instanceof AST_SymbolConst){var def=defun.def_variable(node);def.constant=node instanceof AST_SymbolConst;def.init=tw.parent().value}else if(node instanceof AST_SymbolCatch){(options.screw_ie8?scope:defun).def_variable(node)}});self.walk(tw);var func=null;var globals=self.globals=new Dictionary;var tw=new TreeWalker(function(node,descend){if(node instanceof AST_Lambda){var prev_func=func;func=node;descend();func=prev_func;return true}if(node instanceof AST_SymbolRef){var name=node.name;var sym=node.scope.find_variable(name);if(!sym){var g;if(globals.has(name)){g=globals.get(name)}else{g=new SymbolDef(self,globals.size(),node);g.undeclared=true;g.global=true;globals.set(name,g)}node.thedef=g;if(name=="eval"&&tw.parent()instanceof AST_Call){for(var s=node.scope;s&&!s.uses_eval;s=s.parent_scope)s.uses_eval=true}if(func&&name=="arguments"){func.uses_arguments=true}}else{node.thedef=sym}node.reference();return true}});self.walk(tw)});AST_Scope.DEFMETHOD("init_scope_vars",function(nesting){this.directives=[];this.variables=new Dictionary;this.functions=new Dictionary;this.uses_with=false;this.uses_eval=false;this.parent_scope=null;this.enclosed=[];this.cname=-1;this.nesting=nesting});AST_Scope.DEFMETHOD("strict",function(){return this.has_directive("use strict")});AST_Lambda.DEFMETHOD("init_scope_vars",function(){AST_Scope.prototype.init_scope_vars.apply(this,arguments);this.uses_arguments=false});AST_SymbolRef.DEFMETHOD("reference",function(){var def=this.definition();def.references.push(this);var s=this.scope;while(s){push_uniq(s.enclosed,def);if(s===def.scope)break;s=s.parent_scope}this.frame=this.scope.nesting-def.scope.nesting});AST_Scope.DEFMETHOD("find_variable",function(name){if(name instanceof AST_Symbol)name=name.name;return this.variables.get(name)||this.parent_scope&&this.parent_scope.find_variable(name)});AST_Scope.DEFMETHOD("has_directive",function(value){return this.parent_scope&&this.parent_scope.has_directive(value)||(this.directives.indexOf(value)>=0?this:null)});AST_Scope.DEFMETHOD("def_function",function(symbol){this.functions.set(symbol.name,this.def_variable(symbol))});AST_Scope.DEFMETHOD("def_variable",function(symbol){var def;if(!this.variables.has(symbol.name)){def=new SymbolDef(this,this.variables.size(),symbol);this.variables.set(symbol.name,def);def.global=!this.parent_scope}else{def=this.variables.get(symbol.name);def.orig.push(symbol)}return symbol.thedef=def});AST_Scope.DEFMETHOD("next_mangled",function(options){var ext=this.enclosed;out:while(true){var m=base54(++this.cname);if(!is_identifier(m))continue;if(options.except.indexOf(m)>=0)continue;for(var i=ext.length;--i>=0;){var sym=ext[i];var name=sym.mangled_name||sym.unmangleable(options)&&sym.name;if(m==name)continue out}return m}});AST_Function.DEFMETHOD("next_mangled",function(options,def){var tricky_def=def.orig[0]instanceof AST_SymbolFunarg&&this.name&&this.name.definition();while(true){var name=AST_Lambda.prototype.next_mangled.call(this,options,def);if(!(tricky_def&&tricky_def.mangled_name==name))return name}});AST_Scope.DEFMETHOD("references",function(sym){if(sym instanceof AST_Symbol)sym=sym.definition();return this.enclosed.indexOf(sym)<0?null:sym});AST_Symbol.DEFMETHOD("unmangleable",function(options){return this.definition().unmangleable(options)});AST_SymbolAccessor.DEFMETHOD("unmangleable",function(){return true});AST_Label.DEFMETHOD("unmangleable",function(){return false});AST_Symbol.DEFMETHOD("unreferenced",function(){return this.definition().references.length==0&&!(this.scope.uses_eval||this.scope.uses_with)});AST_Symbol.DEFMETHOD("undeclared",function(){return this.definition().undeclared});AST_LabelRef.DEFMETHOD("undeclared",function(){return false});AST_Label.DEFMETHOD("undeclared",function(){return false});AST_Symbol.DEFMETHOD("definition",function(){return this.thedef});AST_Symbol.DEFMETHOD("global",function(){return this.definition().global});AST_Toplevel.DEFMETHOD("_default_mangler_options",function(options){return defaults(options,{except:[],eval:false,sort:false,toplevel:false,screw_ie8:false})});AST_Toplevel.DEFMETHOD("mangle_names",function(options){options=this._default_mangler_options(options);var lname=-1;var to_mangle=[];var tw=new TreeWalker(function(node,descend){if(node instanceof AST_LabeledStatement){var save_nesting=lname;descend();lname=save_nesting;return true}if(node instanceof AST_Scope){var p=tw.parent(),a=[];node.variables.each(function(symbol){if(options.except.indexOf(symbol.name)<0){a.push(symbol)}});if(options.sort)a.sort(function(a,b){return b.references.length-a.references.length});to_mangle.push.apply(to_mangle,a);return}if(node instanceof AST_Label){var name;do name=base54(++lname);while(!is_identifier(name));node.mangled_name=name;return true}if(options.screw_ie8&&node instanceof AST_SymbolCatch){to_mangle.push(node.definition());return}});this.walk(tw);to_mangle.forEach(function(def){def.mangle(options)})});AST_Toplevel.DEFMETHOD("compute_char_frequency",function(options){options=this._default_mangler_options(options);var tw=new TreeWalker(function(node){if(node instanceof AST_Constant)base54.consider(node.print_to_string());else if(node instanceof AST_Return)base54.consider("return");else if(node instanceof AST_Throw)base54.consider("throw");else if(node instanceof AST_Continue)base54.consider("continue");else if(node instanceof AST_Break)base54.consider("break");else if(node instanceof AST_Debugger)base54.consider("debugger");else if(node instanceof AST_Directive)base54.consider(node.value);else if(node instanceof AST_While)base54.consider("while");else if(node instanceof AST_Do)base54.consider("do while");else if(node instanceof AST_If){base54.consider("if");if(node.alternative)base54.consider("else")}else if(node instanceof AST_Var)base54.consider("var");else if(node instanceof AST_Const)base54.consider("const");else if(node instanceof AST_Lambda)base54.consider("function");else if(node instanceof AST_For)base54.consider("for");else if(node instanceof AST_ForIn)base54.consider("for in");else if(node instanceof AST_Switch)base54.consider("switch");else if(node instanceof AST_Case)base54.consider("case");else if(node instanceof AST_Default)base54.consider("default");else if(node instanceof AST_With)base54.consider("with");else if(node instanceof AST_ObjectSetter)base54.consider("set"+node.key);else if(node instanceof AST_ObjectGetter)base54.consider("get"+node.key);else if(node instanceof AST_ObjectKeyVal)base54.consider(node.key);else if(node instanceof AST_New)base54.consider("new");else if(node instanceof AST_This)base54.consider("this");else if(node instanceof AST_Try)base54.consider("try");else if(node instanceof AST_Catch)base54.consider("catch");else if(node instanceof AST_Finally)base54.consider("finally");else if(node instanceof AST_Symbol&&node.unmangleable(options))base54.consider(node.name);else if(node instanceof AST_Unary||node instanceof AST_Binary)base54.consider(node.operator);else if(node instanceof AST_Dot)base54.consider(node.property)});this.walk(tw);base54.sort()});var base54=function(){var string="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";var chars,frequency;function reset(){frequency=Object.create(null);chars=string.split("").map(function(ch){return ch.charCodeAt(0)});chars.forEach(function(ch){frequency[ch]=0})}base54.consider=function(str){for(var i=str.length;--i>=0;){var code=str.charCodeAt(i);if(code in frequency)++frequency[code]}};base54.sort=function(){chars=mergeSort(chars,function(a,b){if(is_digit(a)&&!is_digit(b))return 1;if(is_digit(b)&&!is_digit(a))return-1;return frequency[b]-frequency[a]})};base54.reset=reset;reset();base54.get=function(){return chars};base54.freq=function(){return frequency};function base54(num){var ret="",base=54;do{ret+=String.fromCharCode(chars[num%base]);num=Math.floor(num/base);base=64}while(num>0);return ret}return base54}();AST_Toplevel.DEFMETHOD("scope_warnings",function(options){options=defaults(options,{undeclared:false,unreferenced:true,assign_to_global:true,func_arguments:true,nested_defuns:true,eval:true});var tw=new TreeWalker(function(node){if(options.undeclared&&node instanceof AST_SymbolRef&&node.undeclared()){AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]",{name:node.name,file:node.start.file,line:node.start.line,col:node.start.col})}if(options.assign_to_global){var sym=null;if(node instanceof AST_Assign&&node.left instanceof AST_SymbolRef)sym=node.left;else if(node instanceof AST_ForIn&&node.init instanceof AST_SymbolRef)sym=node.init;if(sym&&(sym.undeclared()||sym.global()&&sym.scope!==sym.definition().scope)){AST_Node.warn("{msg}: {name} [{file}:{line},{col}]",{msg:sym.undeclared()?"Accidental global?":"Assignment to global",name:sym.name,file:sym.start.file,line:sym.start.line,col:sym.start.col})}}if(options.eval&&node instanceof AST_SymbolRef&&node.undeclared()&&node.name=="eval"){AST_Node.warn("Eval is used [{file}:{line},{col}]",node.start)}if(options.unreferenced&&(node instanceof AST_SymbolDeclaration||node instanceof AST_Label)&&!(node instanceof AST_SymbolCatch)&&node.unreferenced()){AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]",{type:node instanceof AST_Label?"Label":"Symbol",name:node.name,file:node.start.file,line:node.start.line,col:node.start.col})}if(options.func_arguments&&node instanceof AST_Lambda&&node.uses_arguments){AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]",{name:node.name?node.name.name:"anonymous",file:node.start.file,line:node.start.line,col:node.start.col})}if(options.nested_defuns&&node instanceof AST_Defun&&!(tw.parent()instanceof AST_Scope)){AST_Node.warn('Function {name} declared in nested statement "{type}" [{file}:{line},{col}]',{name:node.name.name,type:tw.parent().TYPE,file:node.start.file,line:node.start.line,col:node.start.col})}});this.walk(tw)});/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";function OutputStream(options){options=defaults(options,{indent_start:0,indent_level:4,quote_keys:false,space_colon:true,ascii_only:false,unescape_regexps:false,inline_script:false,width:80,max_line_len:32e3,beautify:false,source_map:null,bracketize:false,semicolons:true,comments:false,preserve_line:false,screw_ie8:false,preamble:null},true);var indentation=0;var current_col=0;var current_line=1;var current_pos=0;var OUTPUT="";function to_ascii(str,identifier){return str.replace(/[\u0080-\uffff]/g,function(ch){var code=ch.charCodeAt(0).toString(16);if(code.length<=2&&!identifier){while(code.length<2)code="0"+code;return"\\x"+code}else{while(code.length<4)code="0"+code;return"\\u"+code}})}function make_string(str){var dq=0,sq=0;str=str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g,function(s){switch(s){case"\\":return"\\\\";case"\b":return"\\b";case"\f":return"\\f";case"\n":return"\\n";case"\r":return"\\r";case"\u2028":return"\\u2028";case"\u2029":return"\\u2029";case'"':++dq;return'"';case"'":++sq;return"'";case"\x00":return"\\x00"}return s});if(options.ascii_only)str=to_ascii(str);if(dq>sq)return"'"+str.replace(/\x27/g,"\\'")+"'";else return'"'+str.replace(/\x22/g,'\\"')+'"'}function encode_string(str){var ret=make_string(str);if(options.inline_script)ret=ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi,"<\\/script$1");return ret}function make_name(name){name=name.toString();if(options.ascii_only)name=to_ascii(name,true);return name}function make_indent(back){return repeat_string(" ",options.indent_start+indentation-back*options.indent_level)}var might_need_space=false;var might_need_semicolon=false;var last=null;function last_char(){return last.charAt(last.length-1)}function maybe_newline(){if(options.max_line_len&¤t_col>options.max_line_len)print("\n")}var requireSemicolonChars=makePredicate("( [ + * / - , .");function print(str){str=String(str);var ch=str.charAt(0);if(might_need_semicolon){if((!ch||";}".indexOf(ch)<0)&&!/[;]$/.test(last)){if(options.semicolons||requireSemicolonChars(ch)){OUTPUT+=";";current_col++;current_pos++}else{OUTPUT+="\n";current_pos++;current_line++;current_col=0}if(!options.beautify)might_need_space=false}might_need_semicolon=false;maybe_newline()}if(!options.beautify&&options.preserve_line&&stack[stack.length-1]){var target_line=stack[stack.length-1].start.line;while(current_line=options.width},newline:newline,print:print,space:space,comma:comma,colon:colon,last:function(){return last},semicolon:semicolon,force_semicolon:force_semicolon,to_ascii:to_ascii,print_name:function(name){print(make_name(name))},print_string:function(str){print(encode_string(str))},next_indent:next_indent,with_indent:with_indent,with_block:with_block,with_parens:with_parens,with_square:with_square,add_mapping:add_mapping,option:function(opt){return options[opt]},line:function(){return current_line},col:function(){return current_col},pos:function(){return current_pos},push_node:function(node){stack.push(node)},pop_node:function(){return stack.pop()},stack:function(){return stack},parent:function(n){return stack[stack.length-2-(n||0)]}}}(function(){function DEFPRINT(nodetype,generator){nodetype.DEFMETHOD("_codegen",generator)}AST_Node.DEFMETHOD("print",function(stream,force_parens){var self=this,generator=self._codegen;function doit(){self.add_comments(stream);self.add_source_map(stream);generator(self,stream)}stream.push_node(self);if(force_parens||self.needs_parens(stream)){stream.with_parens(doit)}else{doit()}stream.pop_node()});AST_Node.DEFMETHOD("print_to_string",function(options){var s=OutputStream(options);this.print(s);return s.get()});AST_Node.DEFMETHOD("add_comments",function(output){var c=output.option("comments"),self=this;if(c){var start=self.start;if(start&&!start._comments_dumped){start._comments_dumped=true;var comments=start.comments_before||[];if(self instanceof AST_Exit&&self.value){self.value.walk(new TreeWalker(function(node){if(node.start&&node.start.comments_before){comments=comments.concat(node.start.comments_before);node.start.comments_before=[]}if(node instanceof AST_Function||node instanceof AST_Array||node instanceof AST_Object){return true}}))}if(c.test){comments=comments.filter(function(comment){return c.test(comment.value)})}else if(typeof c=="function"){comments=comments.filter(function(comment){return c(self,comment)})}comments.forEach(function(c){if(/comment[134]/.test(c.type)){output.print("//"+c.value+"\n");output.indent()}else if(c.type=="comment2"){output.print("/*"+c.value+"*/");if(start.nlb){output.print("\n");output.indent()}else{output.space()}}})}}});function PARENS(nodetype,func){if(Array.isArray(nodetype)){nodetype.forEach(function(nodetype){PARENS(nodetype,func)})}else{nodetype.DEFMETHOD("needs_parens",func)}}PARENS(AST_Node,function(){return false});PARENS(AST_Function,function(output){return first_in_statement(output)});PARENS(AST_Object,function(output){return first_in_statement(output)});PARENS([AST_Unary,AST_Undefined],function(output){var p=output.parent();return p instanceof AST_PropAccess&&p.expression===this});PARENS(AST_Seq,function(output){var p=output.parent();return p instanceof AST_Call||p instanceof AST_Unary||p instanceof AST_Binary||p instanceof AST_VarDef||p instanceof AST_PropAccess||p instanceof AST_Array||p instanceof AST_ObjectProperty||p instanceof AST_Conditional});PARENS(AST_Binary,function(output){var p=output.parent();if(p instanceof AST_Call&&p.expression===this)return true;if(p instanceof AST_Unary)return true;if(p instanceof AST_PropAccess&&p.expression===this)return true;if(p instanceof AST_Binary){var po=p.operator,pp=PRECEDENCE[po];var so=this.operator,sp=PRECEDENCE[so];if(pp>sp||pp==sp&&this===p.right){return true}}});PARENS(AST_PropAccess,function(output){var p=output.parent();if(p instanceof AST_New&&p.expression===this){try{this.walk(new TreeWalker(function(node){if(node instanceof AST_Call)throw p}))}catch(ex){if(ex!==p)throw ex;return true}}});PARENS(AST_Call,function(output){var p=output.parent(),p1;if(p instanceof AST_New&&p.expression===this)return true;return this.expression instanceof AST_Function&&p instanceof AST_PropAccess&&p.expression===this&&(p1=output.parent(1))instanceof AST_Assign&&p1.left===p});PARENS(AST_New,function(output){var p=output.parent();if(no_constructor_parens(this,output)&&(p instanceof AST_PropAccess||p instanceof AST_Call&&p.expression===this))return true});PARENS(AST_Number,function(output){var p=output.parent();if(this.getValue()<0&&p instanceof AST_PropAccess&&p.expression===this)return true});PARENS(AST_NaN,function(output){var p=output.parent();if(p instanceof AST_PropAccess&&p.expression===this)return true});PARENS([AST_Assign,AST_Conditional],function(output){var p=output.parent();if(p instanceof AST_Unary)return true;if(p instanceof AST_Binary&&!(p instanceof AST_Assign))return true;if(p instanceof AST_Call&&p.expression===this)return true;if(p instanceof AST_Conditional&&p.condition===this)return true;if(p instanceof AST_PropAccess&&p.expression===this)return true});DEFPRINT(AST_Directive,function(self,output){output.print_string(self.value);output.semicolon()});DEFPRINT(AST_Debugger,function(self,output){output.print("debugger");output.semicolon()});function display_body(body,is_toplevel,output){var last=body.length-1;body.forEach(function(stmt,i){if(!(stmt instanceof AST_EmptyStatement)){output.indent();stmt.print(output);if(!(i==last&&is_toplevel)){output.newline();if(is_toplevel)output.newline()}}})}AST_StatementWithBody.DEFMETHOD("_do_print_body",function(output){force_statement(this.body,output)});DEFPRINT(AST_Statement,function(self,output){self.body.print(output);output.semicolon()});DEFPRINT(AST_Toplevel,function(self,output){display_body(self.body,true,output);output.print("")});DEFPRINT(AST_LabeledStatement,function(self,output){self.label.print(output);output.colon();self.body.print(output)});DEFPRINT(AST_SimpleStatement,function(self,output){self.body.print(output);output.semicolon()});function print_bracketed(body,output){if(body.length>0)output.with_block(function(){display_body(body,false,output)});else output.print("{}")}DEFPRINT(AST_BlockStatement,function(self,output){print_bracketed(self.body,output)});DEFPRINT(AST_EmptyStatement,function(self,output){output.semicolon()});DEFPRINT(AST_Do,function(self,output){output.print("do");output.space();self._do_print_body(output);output.space();output.print("while");output.space();output.with_parens(function(){self.condition.print(output)});output.semicolon()});DEFPRINT(AST_While,function(self,output){output.print("while");output.space();output.with_parens(function(){self.condition.print(output)});output.space();self._do_print_body(output)});DEFPRINT(AST_For,function(self,output){output.print("for");output.space();output.with_parens(function(){if(self.init&&!(self.init instanceof AST_EmptyStatement)){if(self.init instanceof AST_Definitions){self.init.print(output)}else{parenthesize_for_noin(self.init,output,true)}output.print(";");output.space()}else{output.print(";")}if(self.condition){self.condition.print(output);output.print(";");output.space()}else{output.print(";")}if(self.step){self.step.print(output)}});output.space();self._do_print_body(output)});DEFPRINT(AST_ForIn,function(self,output){output.print("for");output.space();output.with_parens(function(){self.init.print(output);output.space();output.print("in");output.space();self.object.print(output)});output.space();self._do_print_body(output)});DEFPRINT(AST_With,function(self,output){output.print("with");output.space();output.with_parens(function(){self.expression.print(output)});output.space();self._do_print_body(output)});AST_Lambda.DEFMETHOD("_do_print",function(output,nokeyword){var self=this;if(!nokeyword){output.print("function")}if(self.name){output.space();self.name.print(output)}output.with_parens(function(){self.argnames.forEach(function(arg,i){if(i)output.comma();arg.print(output)})});output.space();print_bracketed(self.body,output)});DEFPRINT(AST_Lambda,function(self,output){self._do_print(output)});AST_Exit.DEFMETHOD("_do_print",function(output,kind){output.print(kind);if(this.value){output.space();this.value.print(output)}output.semicolon()});DEFPRINT(AST_Return,function(self,output){self._do_print(output,"return")});DEFPRINT(AST_Throw,function(self,output){self._do_print(output,"throw")});AST_LoopControl.DEFMETHOD("_do_print",function(output,kind){output.print(kind);if(this.label){output.space();this.label.print(output)}output.semicolon()});DEFPRINT(AST_Break,function(self,output){self._do_print(output,"break")});DEFPRINT(AST_Continue,function(self,output){self._do_print(output,"continue")});function make_then(self,output){if(output.option("bracketize")){make_block(self.body,output);return}if(!self.body)return output.force_semicolon();if(self.body instanceof AST_Do&&!output.option("screw_ie8")){make_block(self.body,output);return}var b=self.body;while(true){if(b instanceof AST_If){if(!b.alternative){make_block(self.body,output);return}b=b.alternative}else if(b instanceof AST_StatementWithBody){b=b.body}else break}force_statement(self.body,output)}DEFPRINT(AST_If,function(self,output){output.print("if");output.space();output.with_parens(function(){self.condition.print(output)});output.space();if(self.alternative){make_then(self,output);output.space();output.print("else");output.space();force_statement(self.alternative,output)}else{self._do_print_body(output)}});DEFPRINT(AST_Switch,function(self,output){output.print("switch");output.space();output.with_parens(function(){self.expression.print(output)});output.space();if(self.body.length>0)output.with_block(function(){self.body.forEach(function(stmt,i){if(i)output.newline();output.indent(true);stmt.print(output)})});else output.print("{}")});AST_SwitchBranch.DEFMETHOD("_do_print_body",function(output){if(this.body.length>0){output.newline();this.body.forEach(function(stmt){output.indent();stmt.print(output);output.newline()})}});DEFPRINT(AST_Default,function(self,output){output.print("default:");self._do_print_body(output)});DEFPRINT(AST_Case,function(self,output){output.print("case");output.space();self.expression.print(output);output.print(":");self._do_print_body(output)});DEFPRINT(AST_Try,function(self,output){output.print("try");output.space();print_bracketed(self.body,output);if(self.bcatch){output.space();self.bcatch.print(output)}if(self.bfinally){output.space();self.bfinally.print(output)}});DEFPRINT(AST_Catch,function(self,output){output.print("catch");output.space();output.with_parens(function(){self.argname.print(output)});output.space();print_bracketed(self.body,output)});DEFPRINT(AST_Finally,function(self,output){output.print("finally");output.space();print_bracketed(self.body,output)});AST_Definitions.DEFMETHOD("_do_print",function(output,kind){output.print(kind);output.space();this.definitions.forEach(function(def,i){if(i)output.comma();def.print(output)});var p=output.parent();var in_for=p instanceof AST_For||p instanceof AST_ForIn;var avoid_semicolon=in_for&&p.init===this;if(!avoid_semicolon)output.semicolon()});DEFPRINT(AST_Var,function(self,output){self._do_print(output,"var")});DEFPRINT(AST_Const,function(self,output){self._do_print(output,"const")});function parenthesize_for_noin(node,output,noin){if(!noin)node.print(output);else try{node.walk(new TreeWalker(function(node){if(node instanceof AST_Binary&&node.operator=="in")throw output}));node.print(output)}catch(ex){if(ex!==output)throw ex;node.print(output,true)}}DEFPRINT(AST_VarDef,function(self,output){self.name.print(output);if(self.value){output.space();output.print("=");output.space();var p=output.parent(1);var noin=p instanceof AST_For||p instanceof AST_ForIn;parenthesize_for_noin(self.value,output,noin)}});DEFPRINT(AST_Call,function(self,output){self.expression.print(output);if(self instanceof AST_New&&no_constructor_parens(self,output))return;output.with_parens(function(){self.args.forEach(function(expr,i){if(i)output.comma();expr.print(output)})})});DEFPRINT(AST_New,function(self,output){output.print("new");output.space();AST_Call.prototype._codegen(self,output)});AST_Seq.DEFMETHOD("_do_print",function(output){this.car.print(output);if(this.cdr){output.comma();if(output.should_break()){output.newline();output.indent()}this.cdr.print(output)}});DEFPRINT(AST_Seq,function(self,output){self._do_print(output)});DEFPRINT(AST_Dot,function(self,output){var expr=self.expression;expr.print(output);if(expr instanceof AST_Number&&expr.getValue()>=0){if(!/[xa-f.]/i.test(output.last())){output.print(".")}}output.print(".");output.add_mapping(self.end);output.print_name(self.property)});DEFPRINT(AST_Sub,function(self,output){self.expression.print(output);output.print("[");self.property.print(output);output.print("]")});DEFPRINT(AST_UnaryPrefix,function(self,output){var op=self.operator;output.print(op);if(/^[a-z]/i.test(op)||/[+-]$/.test(op)&&self.expression instanceof AST_UnaryPrefix&&/^[+-]/.test(self.expression.operator)){output.space()}self.expression.print(output)});DEFPRINT(AST_UnaryPostfix,function(self,output){self.expression.print(output);output.print(self.operator)});DEFPRINT(AST_Binary,function(self,output){self.left.print(output);output.space();output.print(self.operator);if(self.operator=="<"&&self.right instanceof AST_UnaryPrefix&&self.right.operator=="!"&&self.right.expression instanceof AST_UnaryPrefix&&self.right.expression.operator=="--"){output.print(" ")}else{output.space()}self.right.print(output)});DEFPRINT(AST_Conditional,function(self,output){self.condition.print(output);output.space();output.print("?");output.space();self.consequent.print(output);output.space();output.colon();self.alternative.print(output)});DEFPRINT(AST_Array,function(self,output){output.with_square(function(){var a=self.elements,len=a.length;if(len>0)output.space();a.forEach(function(exp,i){if(i)output.comma();exp.print(output);if(i===len-1&&exp instanceof AST_Hole)output.comma()});if(len>0)output.space()})});DEFPRINT(AST_Object,function(self,output){if(self.properties.length>0)output.with_block(function(){self.properties.forEach(function(prop,i){if(i){output.print(",");output.newline()}output.indent();prop.print(output)});output.newline()});else output.print("{}")});DEFPRINT(AST_ObjectKeyVal,function(self,output){var key=self.key;if(output.option("quote_keys")){output.print_string(key+"")}else if((typeof key=="number"||!output.option("beautify")&&+key+""==key)&&parseFloat(key)>=0){output.print(make_num(key))}else if(RESERVED_WORDS(key)?output.option("screw_ie8"):is_identifier_string(key)){output.print_name(key)}else{output.print_string(key)}output.colon();self.value.print(output)});DEFPRINT(AST_ObjectSetter,function(self,output){output.print("set");output.space();self.key.print(output);self.value._do_print(output,true)});DEFPRINT(AST_ObjectGetter,function(self,output){output.print("get");output.space();self.key.print(output);self.value._do_print(output,true)});DEFPRINT(AST_Symbol,function(self,output){var def=self.definition();output.print_name(def?def.mangled_name||def.name:self.name)});DEFPRINT(AST_Undefined,function(self,output){output.print("void 0")});DEFPRINT(AST_Hole,noop);DEFPRINT(AST_Infinity,function(self,output){output.print("1/0")});DEFPRINT(AST_NaN,function(self,output){output.print("0/0")});DEFPRINT(AST_This,function(self,output){output.print("this")});DEFPRINT(AST_Constant,function(self,output){output.print(self.getValue())});DEFPRINT(AST_String,function(self,output){output.print_string(self.getValue())});DEFPRINT(AST_Number,function(self,output){output.print(make_num(self.getValue()))});function regexp_safe_literal(code){return[92,47,46,43,42,63,40,41,91,93,123,125,36,94,58,124,33,10,13,0,65279,8232,8233].indexOf(code)<0}DEFPRINT(AST_RegExp,function(self,output){var str=self.getValue().toString();if(output.option("ascii_only")){str=output.to_ascii(str)}else if(output.option("unescape_regexps")){str=str.split("\\\\").map(function(str){return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g,function(s){var code=parseInt(s.substr(2),16);return regexp_safe_literal(code)?String.fromCharCode(code):s})}).join("\\\\")}output.print(str);var p=output.parent();if(p instanceof AST_Binary&&/^in/.test(p.operator)&&p.left===self)output.print(" ")});function force_statement(stat,output){if(output.option("bracketize")){if(!stat||stat instanceof AST_EmptyStatement)output.print("{}");else if(stat instanceof AST_BlockStatement)stat.print(output);else output.with_block(function(){output.indent();stat.print(output);output.newline()})}else{if(!stat||stat instanceof AST_EmptyStatement)output.force_semicolon();else stat.print(output)}}function first_in_statement(output){var a=output.stack(),i=a.length,node=a[--i],p=a[--i];while(i>0){if(p instanceof AST_Statement&&p.body===node)return true;if(p instanceof AST_Seq&&p.car===node||p instanceof AST_Call&&p.expression===node&&!(p instanceof AST_New)||p instanceof AST_Dot&&p.expression===node||p instanceof AST_Sub&&p.expression===node||p instanceof AST_Conditional&&p.condition===node||p instanceof AST_Binary&&p.left===node||p instanceof AST_UnaryPostfix&&p.expression===node){node=p;p=a[--i]}else{return false}}}function no_constructor_parens(self,output){return self.args.length==0&&!output.option("beautify")}function best_of(a){var best=a[0],len=best.length;for(var i=1;i=0){a.push("0x"+num.toString(16).toLowerCase(),"0"+num.toString(8))}else{a.push("-0x"+(-num).toString(16).toLowerCase(),"-0"+(-num).toString(8))}if(m=/^(.*?)(0+)$/.exec(num)){a.push(m[1]+"e"+m[2].length)}}else if(m=/^0?\.(0+)(.*)$/.exec(num)){a.push(m[2]+"e-"+(m[1].length+m[2].length),str.substr(str.indexOf(".")))}return best_of(a)}function make_block(stmt,output){if(stmt instanceof AST_BlockStatement){stmt.print(output);return}output.with_block(function(){output.indent();stmt.print(output);output.newline()})}function DEFMAP(nodetype,generator){nodetype.DEFMETHOD("add_source_map",function(stream){generator(this,stream)})}DEFMAP(AST_Node,noop);function basic_sourcemap_gen(self,output){output.add_mapping(self.start)}DEFMAP(AST_Directive,basic_sourcemap_gen);DEFMAP(AST_Debugger,basic_sourcemap_gen);DEFMAP(AST_Symbol,basic_sourcemap_gen);DEFMAP(AST_Jump,basic_sourcemap_gen);DEFMAP(AST_StatementWithBody,basic_sourcemap_gen);DEFMAP(AST_LabeledStatement,noop);DEFMAP(AST_Lambda,basic_sourcemap_gen);DEFMAP(AST_Switch,basic_sourcemap_gen);DEFMAP(AST_SwitchBranch,basic_sourcemap_gen);DEFMAP(AST_BlockStatement,basic_sourcemap_gen);DEFMAP(AST_Toplevel,noop);DEFMAP(AST_New,basic_sourcemap_gen);DEFMAP(AST_Try,basic_sourcemap_gen);DEFMAP(AST_Catch,basic_sourcemap_gen);DEFMAP(AST_Finally,basic_sourcemap_gen);DEFMAP(AST_Definitions,basic_sourcemap_gen);DEFMAP(AST_Constant,basic_sourcemap_gen);DEFMAP(AST_ObjectProperty,function(self,output){output.add_mapping(self.start,self.key)})})();/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";function Compressor(options,false_by_default){if(!(this instanceof Compressor))return new Compressor(options,false_by_default);TreeTransformer.call(this,this.before,this.after);this.options=defaults(options,{sequences:!false_by_default,properties:!false_by_default,dead_code:!false_by_default,drop_debugger:!false_by_default,unsafe:false,unsafe_comps:false,conditionals:!false_by_default,comparisons:!false_by_default,evaluate:!false_by_default,booleans:!false_by_default,loops:!false_by_default,unused:!false_by_default,hoist_funs:!false_by_default,keep_fargs:false,hoist_vars:false,if_return:!false_by_default,join_vars:!false_by_default,cascade:!false_by_default,side_effects:!false_by_default,pure_getters:false,pure_funcs:null,negate_iife:!false_by_default,screw_ie8:false,drop_console:false,angular:false,warnings:true,global_defs:{}},true)}Compressor.prototype=new TreeTransformer;merge(Compressor.prototype,{option:function(key){return this.options[key]},warn:function(){if(this.options.warnings)AST_Node.warn.apply(AST_Node,arguments)},before:function(node,descend,in_list){if(node._squeezed)return node;var was_scope=false;if(node instanceof AST_Scope){node=node.hoist_declarations(this);was_scope=true}descend(node,this);node=node.optimize(this);if(was_scope&&node instanceof AST_Scope){node.drop_unused(this);descend(node,this)}node._squeezed=true;return node}});(function(){function OPT(node,optimizer){node.DEFMETHOD("optimize",function(compressor){var self=this;if(self._optimized)return self;var opt=optimizer(self,compressor);opt._optimized=true;if(opt===self)return opt;return opt.transform(compressor)})}OPT(AST_Node,function(self,compressor){return self});AST_Node.DEFMETHOD("equivalent_to",function(node){return this.print_to_string()==node.print_to_string()});function make_node(ctor,orig,props){if(!props)props={};if(orig){if(!props.start)props.start=orig.start;if(!props.end)props.end=orig.end}return new ctor(props)}function make_node_from_constant(compressor,val,orig){if(val instanceof AST_Node)return val.transform(compressor);switch(typeof val){case"string":return make_node(AST_String,orig,{value:val}).optimize(compressor);case"number":return make_node(isNaN(val)?AST_NaN:AST_Number,orig,{value:val}).optimize(compressor);case"boolean":return make_node(val?AST_True:AST_False,orig).optimize(compressor);case"undefined":return make_node(AST_Undefined,orig).optimize(compressor);default:if(val===null){return make_node(AST_Null,orig).optimize(compressor)}if(val instanceof RegExp){return make_node(AST_RegExp,orig).optimize(compressor)}throw new Error(string_template("Can't handle constant of type: {type}",{type:typeof val}))}}function as_statement_array(thing){if(thing===null)return[];if(thing instanceof AST_BlockStatement)return thing.body;if(thing instanceof AST_EmptyStatement)return[];if(thing instanceof AST_Statement)return[thing];throw new Error("Can't convert thing to statement array")}function is_empty(thing){if(thing===null)return true;if(thing instanceof AST_EmptyStatement)return true;if(thing instanceof AST_BlockStatement)return thing.body.length==0;return false}function loop_body(x){if(x instanceof AST_Switch)return x;if(x instanceof AST_For||x instanceof AST_ForIn||x instanceof AST_DWLoop){return x.body instanceof AST_BlockStatement?x.body:x}return x}function tighten_body(statements,compressor){var CHANGED;do{CHANGED=false;if(compressor.option("angular")){statements=process_for_angular(statements)}statements=eliminate_spurious_blocks(statements);if(compressor.option("dead_code")){statements=eliminate_dead_code(statements,compressor)}if(compressor.option("if_return")){statements=handle_if_return(statements,compressor)}if(compressor.option("sequences")){statements=sequencesize(statements,compressor)}if(compressor.option("join_vars")){statements=join_consecutive_vars(statements,compressor)}}while(CHANGED);if(compressor.option("negate_iife")){negate_iifes(statements,compressor)}return statements;function process_for_angular(statements){function make_injector(func,name){return make_node(AST_SimpleStatement,func,{body:make_node(AST_Assign,func,{operator:"=",left:make_node(AST_Dot,name,{expression:make_node(AST_SymbolRef,name,name),property:"$inject"}),right:make_node(AST_Array,func,{elements:func.argnames.map(function(sym){return make_node(AST_String,sym,{value:sym.name})})})})})}return statements.reduce(function(a,stat){a.push(stat);var token=stat.start;var comments=token.comments_before;if(comments&&comments.length>0){var last=comments.pop();if(/@ngInject/.test(last.value)){if(stat instanceof AST_Defun){a.push(make_injector(stat,stat.name))}else if(stat instanceof AST_Definitions){stat.definitions.forEach(function(def){if(def.value&&def.value instanceof AST_Lambda){a.push(make_injector(def.value,def.name))}})}else{compressor.warn("Unknown statement marked with @ngInject [{file}:{line},{col}]",token)}}}return a},[])}function eliminate_spurious_blocks(statements){var seen_dirs=[];return statements.reduce(function(a,stat){if(stat instanceof AST_BlockStatement){CHANGED=true;a.push.apply(a,eliminate_spurious_blocks(stat.body))}else if(stat instanceof AST_EmptyStatement){CHANGED=true}else if(stat instanceof AST_Directive){if(seen_dirs.indexOf(stat.value)<0){a.push(stat);seen_dirs.push(stat.value)}else{CHANGED=true}}else{a.push(stat)}return a},[])}function handle_if_return(statements,compressor){var self=compressor.self();var in_lambda=self instanceof AST_Lambda;var ret=[];loop:for(var i=statements.length;--i>=0;){var stat=statements[i];switch(true){case in_lambda&&stat instanceof AST_Return&&!stat.value&&ret.length==0:CHANGED=true;continue loop;case stat instanceof AST_If:if(stat.body instanceof AST_Return){if((in_lambda&&ret.length==0||ret[0]instanceof AST_Return&&!ret[0].value)&&!stat.body.value&&!stat.alternative){CHANGED=true;var cond=make_node(AST_SimpleStatement,stat.condition,{body:stat.condition});ret.unshift(cond);continue loop}if(ret[0]instanceof AST_Return&&stat.body.value&&ret[0].value&&!stat.alternative){CHANGED=true;stat=stat.clone();stat.alternative=ret[0];ret[0]=stat.transform(compressor);continue loop}if((ret.length==0||ret[0]instanceof AST_Return)&&stat.body.value&&!stat.alternative&&in_lambda){CHANGED=true;stat=stat.clone();stat.alternative=ret[0]||make_node(AST_Return,stat,{value:make_node(AST_Undefined,stat)});ret[0]=stat.transform(compressor);continue loop}if(!stat.body.value&&in_lambda){CHANGED=true;stat=stat.clone();stat.condition=stat.condition.negate(compressor);stat.body=make_node(AST_BlockStatement,stat,{body:as_statement_array(stat.alternative).concat(ret)});stat.alternative=null;ret=[stat.transform(compressor)];continue loop}if(ret.length==1&&in_lambda&&ret[0]instanceof AST_SimpleStatement&&(!stat.alternative||stat.alternative instanceof AST_SimpleStatement)){CHANGED=true;ret.push(make_node(AST_Return,ret[0],{value:make_node(AST_Undefined,ret[0])}).transform(compressor));ret=as_statement_array(stat.alternative).concat(ret);ret.unshift(stat);continue loop}}var ab=aborts(stat.body);var lct=ab instanceof AST_LoopControl?compressor.loopcontrol_target(ab.label):null;if(ab&&(ab instanceof AST_Return&&!ab.value&&in_lambda||ab instanceof AST_Continue&&self===loop_body(lct)||ab instanceof AST_Break&&lct instanceof AST_BlockStatement&&self===lct)){if(ab.label){remove(ab.label.thedef.references,ab)}CHANGED=true;var body=as_statement_array(stat.body).slice(0,-1);stat=stat.clone();stat.condition=stat.condition.negate(compressor);stat.body=make_node(AST_BlockStatement,stat,{body:as_statement_array(stat.alternative).concat(ret)});stat.alternative=make_node(AST_BlockStatement,stat,{body:body});ret=[stat.transform(compressor)];continue loop}var ab=aborts(stat.alternative);var lct=ab instanceof AST_LoopControl?compressor.loopcontrol_target(ab.label):null;if(ab&&(ab instanceof AST_Return&&!ab.value&&in_lambda||ab instanceof AST_Continue&&self===loop_body(lct)||ab instanceof AST_Break&&lct instanceof AST_BlockStatement&&self===lct)){if(ab.label){remove(ab.label.thedef.references,ab)}CHANGED=true;stat=stat.clone();stat.body=make_node(AST_BlockStatement,stat.body,{body:as_statement_array(stat.body).concat(ret)});stat.alternative=make_node(AST_BlockStatement,stat.alternative,{body:as_statement_array(stat.alternative).slice(0,-1)});ret=[stat.transform(compressor)];continue loop}ret.unshift(stat);break;default:ret.unshift(stat);break}}return ret}function eliminate_dead_code(statements,compressor){var has_quit=false;var orig=statements.length;var self=compressor.self();statements=statements.reduce(function(a,stat){if(has_quit){extract_declarations_from_unreachable_code(compressor,stat,a)}else{if(stat instanceof AST_LoopControl){var lct=compressor.loopcontrol_target(stat.label);if(stat instanceof AST_Break&&lct instanceof AST_BlockStatement&&loop_body(lct)===self||stat instanceof AST_Continue&&loop_body(lct)===self){if(stat.label){remove(stat.label.thedef.references,stat)}}else{a.push(stat)}}else{a.push(stat)}if(aborts(stat))has_quit=true}return a},[]);CHANGED=statements.length!=orig;return statements}function sequencesize(statements,compressor){if(statements.length<2)return statements;var seq=[],ret=[];function push_seq(){seq=AST_Seq.from_array(seq);if(seq)ret.push(make_node(AST_SimpleStatement,seq,{body:seq}));seq=[]}statements.forEach(function(stat){if(stat instanceof AST_SimpleStatement)seq.push(stat.body);else push_seq(),ret.push(stat)});push_seq();ret=sequencesize_2(ret,compressor);CHANGED=ret.length!=statements.length;return ret}function sequencesize_2(statements,compressor){function cons_seq(right){ret.pop();var left=prev.body;if(left instanceof AST_Seq){left.add(right)}else{left=AST_Seq.cons(left,right)}return left.transform(compressor)}var ret=[],prev=null;statements.forEach(function(stat){if(prev){if(stat instanceof AST_For){var opera={};try{prev.body.walk(new TreeWalker(function(node){if(node instanceof AST_Binary&&node.operator=="in")throw opera}));if(stat.init&&!(stat.init instanceof AST_Definitions)){stat.init=cons_seq(stat.init)}else if(!stat.init){stat.init=prev.body;ret.pop()}}catch(ex){if(ex!==opera)throw ex}}else if(stat instanceof AST_If){stat.condition=cons_seq(stat.condition)}else if(stat instanceof AST_With){stat.expression=cons_seq(stat.expression)}else if(stat instanceof AST_Exit&&stat.value){stat.value=cons_seq(stat.value)}else if(stat instanceof AST_Exit){stat.value=cons_seq(make_node(AST_Undefined,stat))}else if(stat instanceof AST_Switch){stat.expression=cons_seq(stat.expression)}}ret.push(stat);prev=stat instanceof AST_SimpleStatement?stat:null});return ret}function join_consecutive_vars(statements,compressor){var prev=null;return statements.reduce(function(a,stat){if(stat instanceof AST_Definitions&&prev&&prev.TYPE==stat.TYPE){prev.definitions=prev.definitions.concat(stat.definitions);CHANGED=true}else if(stat instanceof AST_For&&prev instanceof AST_Definitions&&(!stat.init||stat.init.TYPE==prev.TYPE)){CHANGED=true;a.pop();if(stat.init){stat.init.definitions=prev.definitions.concat(stat.init.definitions)}else{stat.init=prev}a.push(stat);prev=stat}else{prev=stat;a.push(stat)}return a},[])}function negate_iifes(statements,compressor){statements.forEach(function(stat){if(stat instanceof AST_SimpleStatement){stat.body=function transform(thing){return thing.transform(new TreeTransformer(function(node){if(node instanceof AST_Call&&node.expression instanceof AST_Function){return make_node(AST_UnaryPrefix,node,{operator:"!",expression:node})}else if(node instanceof AST_Call){node.expression=transform(node.expression)}else if(node instanceof AST_Seq){node.car=transform(node.car)}else if(node instanceof AST_Conditional){var expr=transform(node.condition);if(expr!==node.condition){node.condition=expr;var tmp=node.consequent;node.consequent=node.alternative;node.alternative=tmp}}return node}))}(stat.body)}})}}function extract_declarations_from_unreachable_code(compressor,stat,target){compressor.warn("Dropping unreachable code [{file}:{line},{col}]",stat.start);stat.walk(new TreeWalker(function(node){if(node instanceof AST_Definitions){compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]",node.start);node.remove_initializers();target.push(node);return true}if(node instanceof AST_Defun){target.push(node);return true}if(node instanceof AST_Scope){return true}}))}(function(def){var unary_bool=["!","delete"];var binary_bool=["in","instanceof","==","!=","===","!==","<","<=",">=",">"];def(AST_Node,function(){return false});def(AST_UnaryPrefix,function(){return member(this.operator,unary_bool)});def(AST_Binary,function(){return member(this.operator,binary_bool)||(this.operator=="&&"||this.operator=="||")&&this.left.is_boolean()&&this.right.is_boolean()});def(AST_Conditional,function(){return this.consequent.is_boolean()&&this.alternative.is_boolean()});def(AST_Assign,function(){return this.operator=="="&&this.right.is_boolean()});def(AST_Seq,function(){return this.cdr.is_boolean()});def(AST_True,function(){return true});def(AST_False,function(){return true})})(function(node,func){node.DEFMETHOD("is_boolean",func)});(function(def){def(AST_Node,function(){return false});def(AST_String,function(){return true});def(AST_UnaryPrefix,function(){return this.operator=="typeof"});def(AST_Binary,function(compressor){return this.operator=="+"&&(this.left.is_string(compressor)||this.right.is_string(compressor))});def(AST_Assign,function(compressor){return(this.operator=="="||this.operator=="+=")&&this.right.is_string(compressor)});def(AST_Seq,function(compressor){return this.cdr.is_string(compressor)});def(AST_Conditional,function(compressor){return this.consequent.is_string(compressor)&&this.alternative.is_string(compressor)});def(AST_Call,function(compressor){return compressor.option("unsafe")&&this.expression instanceof AST_SymbolRef&&this.expression.name=="String"&&this.expression.undeclared()})})(function(node,func){node.DEFMETHOD("is_string",func)});function best_of(ast1,ast2){return ast1.print_to_string().length>ast2.print_to_string().length?ast2:ast1}(function(def){AST_Node.DEFMETHOD("evaluate",function(compressor){if(!compressor.option("evaluate"))return[this];try{var val=this._eval(compressor);return[best_of(make_node_from_constant(compressor,val,this),this),val]}catch(ex){if(ex!==def)throw ex;return[this]}});def(AST_Statement,function(){throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]",this.start))});def(AST_Function,function(){throw def});function ev(node,compressor){if(!compressor)throw new Error("Compressor must be passed");return node._eval(compressor)}def(AST_Node,function(){throw def});def(AST_Constant,function(){return this.getValue()});def(AST_UnaryPrefix,function(compressor){var e=this.expression;switch(this.operator){case"!":return!ev(e,compressor);case"typeof":if(e instanceof AST_Function)return typeof function(){};e=ev(e,compressor);if(e instanceof RegExp)throw def;return typeof e;case"void":return void ev(e,compressor);case"~":return~ev(e,compressor);case"-":e=ev(e,compressor);if(e===0)throw def;return-e;case"+":return+ev(e,compressor)}throw def});def(AST_Binary,function(c){var left=this.left,right=this.right;switch(this.operator){case"&&":return ev(left,c)&&ev(right,c);case"||":return ev(left,c)||ev(right,c);case"|":return ev(left,c)|ev(right,c);case"&":return ev(left,c)&ev(right,c);case"^":return ev(left,c)^ev(right,c);case"+":return ev(left,c)+ev(right,c);case"*":return ev(left,c)*ev(right,c);case"/":return ev(left,c)/ev(right,c);case"%":return ev(left,c)%ev(right,c);case"-":return ev(left,c)-ev(right,c);case"<<":return ev(left,c)<>":return ev(left,c)>>ev(right,c);case">>>":return ev(left,c)>>>ev(right,c);case"==":return ev(left,c)==ev(right,c);case"===":return ev(left,c)===ev(right,c);case"!=":return ev(left,c)!=ev(right,c);case"!==":return ev(left,c)!==ev(right,c);case"<":return ev(left,c)":return ev(left,c)>ev(right,c);case">=":return ev(left,c)>=ev(right,c);case"in":return ev(left,c)in ev(right,c);case"instanceof":return ev(left,c)instanceof ev(right,c)}throw def});def(AST_Conditional,function(compressor){return ev(this.condition,compressor)?ev(this.consequent,compressor):ev(this.alternative,compressor)});def(AST_SymbolRef,function(compressor){var d=this.definition();if(d&&d.constant&&d.init)return ev(d.init,compressor);throw def});def(AST_Dot,function(compressor){if(compressor.option("unsafe")&&this.property=="length"){var str=ev(this.expression,compressor);if(typeof str=="string")return str.length}throw def})})(function(node,func){node.DEFMETHOD("_eval",func)});(function(def){function basic_negation(exp){return make_node(AST_UnaryPrefix,exp,{operator:"!",expression:exp})}def(AST_Node,function(){return basic_negation(this)});def(AST_Statement,function(){throw new Error("Cannot negate a statement")});def(AST_Function,function(){return basic_negation(this)});def(AST_UnaryPrefix,function(){if(this.operator=="!")return this.expression;return basic_negation(this)});def(AST_Seq,function(compressor){var self=this.clone();self.cdr=self.cdr.negate(compressor);return self});def(AST_Conditional,function(compressor){var self=this.clone();self.consequent=self.consequent.negate(compressor);self.alternative=self.alternative.negate(compressor);return best_of(basic_negation(this),self)});def(AST_Binary,function(compressor){var self=this.clone(),op=this.operator;if(compressor.option("unsafe_comps")){switch(op){case"<=":self.operator=">";return self;case"<":self.operator=">=";return self;case">=":self.operator="<";return self;case">":self.operator="<=";return self}}switch(op){case"==":self.operator="!=";return self;case"!=":self.operator="==";return self;case"===":self.operator="!==";return self;case"!==":self.operator="===";return self;case"&&":self.operator="||";self.left=self.left.negate(compressor);self.right=self.right.negate(compressor);return best_of(basic_negation(this),self);case"||":self.operator="&&";self.left=self.left.negate(compressor);self.right=self.right.negate(compressor);return best_of(basic_negation(this),self)}return basic_negation(this)})})(function(node,func){node.DEFMETHOD("negate",function(compressor){return func.call(this,compressor)})});(function(def){def(AST_Node,function(compressor){return true});def(AST_EmptyStatement,function(compressor){return false});def(AST_Constant,function(compressor){return false});def(AST_This,function(compressor){return false});def(AST_Call,function(compressor){var pure=compressor.option("pure_funcs");if(!pure)return true;return pure.indexOf(this.expression.print_to_string())<0});def(AST_Block,function(compressor){for(var i=this.body.length;--i>=0;){if(this.body[i].has_side_effects(compressor))return true}return false});def(AST_SimpleStatement,function(compressor){return this.body.has_side_effects(compressor)});def(AST_Defun,function(compressor){return true});def(AST_Function,function(compressor){return false});def(AST_Binary,function(compressor){return this.left.has_side_effects(compressor)||this.right.has_side_effects(compressor)});def(AST_Assign,function(compressor){return true});def(AST_Conditional,function(compressor){return this.condition.has_side_effects(compressor)||this.consequent.has_side_effects(compressor)||this.alternative.has_side_effects(compressor)});def(AST_Unary,function(compressor){return this.operator=="delete"||this.operator=="++"||this.operator=="--"||this.expression.has_side_effects(compressor)});def(AST_SymbolRef,function(compressor){return this.global()&&this.undeclared()});def(AST_Object,function(compressor){for(var i=this.properties.length;--i>=0;)if(this.properties[i].has_side_effects(compressor))return true;return false});def(AST_ObjectProperty,function(compressor){return this.value.has_side_effects(compressor)});def(AST_Array,function(compressor){for(var i=this.elements.length;--i>=0;)if(this.elements[i].has_side_effects(compressor))return true;return false});def(AST_Dot,function(compressor){if(!compressor.option("pure_getters"))return true;return this.expression.has_side_effects(compressor)});def(AST_Sub,function(compressor){if(!compressor.option("pure_getters"))return true;return this.expression.has_side_effects(compressor)||this.property.has_side_effects(compressor)});def(AST_PropAccess,function(compressor){return!compressor.option("pure_getters")});def(AST_Seq,function(compressor){return this.car.has_side_effects(compressor)||this.cdr.has_side_effects(compressor)})})(function(node,func){node.DEFMETHOD("has_side_effects",func)});function aborts(thing){return thing&&thing.aborts()}(function(def){def(AST_Statement,function(){return null});def(AST_Jump,function(){return this});function block_aborts(){var n=this.body.length;return n>0&&aborts(this.body[n-1])}def(AST_BlockStatement,block_aborts);def(AST_SwitchBranch,block_aborts);def(AST_If,function(){return this.alternative&&aborts(this.body)&&aborts(this.alternative)})})(function(node,func){node.DEFMETHOD("aborts",func)});OPT(AST_Directive,function(self,compressor){if(self.scope.has_directive(self.value)!==self.scope){return make_node(AST_EmptyStatement,self)}return self});OPT(AST_Debugger,function(self,compressor){if(compressor.option("drop_debugger"))return make_node(AST_EmptyStatement,self);return self});OPT(AST_LabeledStatement,function(self,compressor){if(self.body instanceof AST_Break&&compressor.loopcontrol_target(self.body.label)===self.body){return make_node(AST_EmptyStatement,self)}return self.label.references.length==0?self.body:self});OPT(AST_Block,function(self,compressor){self.body=tighten_body(self.body,compressor);return self});OPT(AST_BlockStatement,function(self,compressor){self.body=tighten_body(self.body,compressor);switch(self.body.length){case 1:return self.body[0];case 0:return make_node(AST_EmptyStatement,self)}return self});AST_Scope.DEFMETHOD("drop_unused",function(compressor){var self=this;if(compressor.option("unused")&&!(self instanceof AST_Toplevel)&&!self.uses_eval){var in_use=[];var initializations=new Dictionary;var scope=this;var tw=new TreeWalker(function(node,descend){if(node!==self){if(node instanceof AST_Defun){initializations.add(node.name.name,node);return true}if(node instanceof AST_Definitions&&scope===self){node.definitions.forEach(function(def){if(def.value){initializations.add(def.name.name,def.value);if(def.value.has_side_effects(compressor)){def.value.walk(tw)}}});return true}if(node instanceof AST_SymbolRef){push_uniq(in_use,node.definition());return true}if(node instanceof AST_Scope){var save_scope=scope;scope=node;descend();scope=save_scope;return true}}});self.walk(tw);for(var i=0;i=0;){var sym=a[i];if(sym.unreferenced()){a.pop();compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]",{name:sym.name,file:sym.start.file,line:sym.start.line,col:sym.start.col})}else break}}}if(node instanceof AST_Defun&&node!==self){if(!member(node.name.definition(),in_use)){compressor.warn("Dropping unused function {name} [{file}:{line},{col}]",{name:node.name.name,file:node.name.start.file,line:node.name.start.line,col:node.name.start.col});return make_node(AST_EmptyStatement,node)}return node}if(node instanceof AST_Definitions&&!(tt.parent()instanceof AST_ForIn)){var def=node.definitions.filter(function(def){if(member(def.name.definition(),in_use))return true;var w={name:def.name.name,file:def.name.start.file,line:def.name.start.line,col:def.name.start.col};if(def.value&&def.value.has_side_effects(compressor)){def._unused_side_effects=true;compressor.warn("Side effects in initialization of unused variable {name} [{file}:{line},{col}]",w);return true}compressor.warn("Dropping unused variable {name} [{file}:{line},{col}]",w);return false});def=mergeSort(def,function(a,b){if(!a.value&&b.value)return-1;if(!b.value&&a.value)return 1;return 0});var side_effects=[];for(var i=0;i0){side_effects.push(x.value);x.value=AST_Seq.from_array(side_effects);side_effects=[]}++i}}if(side_effects.length>0){side_effects=make_node(AST_BlockStatement,node,{body:[make_node(AST_SimpleStatement,node,{body:AST_Seq.from_array(side_effects)})]})}else{side_effects=null}if(def.length==0&&!side_effects){return make_node(AST_EmptyStatement,node)}if(def.length==0){return side_effects}node.definitions=def;if(side_effects){side_effects.body.unshift(node);node=side_effects}return node}if(node instanceof AST_For){descend(node,this);if(node.init instanceof AST_BlockStatement){var body=node.init.body.slice(0,-1);node.init=node.init.body.slice(-1)[0].body;body.push(node);return in_list?MAP.splice(body):make_node(AST_BlockStatement,node,{body:body})}}if(node instanceof AST_Scope&&node!==self)return node});self.transform(tt)}});AST_Scope.DEFMETHOD("hoist_declarations",function(compressor){var hoist_funs=compressor.option("hoist_funs");var hoist_vars=compressor.option("hoist_vars");var self=this;if(hoist_funs||hoist_vars){var dirs=[];var hoisted=[];var vars=new Dictionary,vars_found=0,var_decl=0;self.walk(new TreeWalker(function(node){if(node instanceof AST_Scope&&node!==self)return true;if(node instanceof AST_Var){++var_decl;return true}}));hoist_vars=hoist_vars&&var_decl>1;var tt=new TreeTransformer(function before(node){if(node!==self){if(node instanceof AST_Directive){dirs.push(node);return make_node(AST_EmptyStatement,node)}if(node instanceof AST_Defun&&hoist_funs){hoisted.push(node);return make_node(AST_EmptyStatement,node)}if(node instanceof AST_Var&&hoist_vars){node.definitions.forEach(function(def){vars.set(def.name.name,def);++vars_found});var seq=node.to_assignments();var p=tt.parent();if(p instanceof AST_ForIn&&p.init===node){if(seq==null)return node.definitions[0].name;return seq}if(p instanceof AST_For&&p.init===node){return seq}if(!seq)return make_node(AST_EmptyStatement,node);return make_node(AST_SimpleStatement,node,{body:seq})}if(node instanceof AST_Scope)return node}});self=self.transform(tt);if(vars_found>0){var defs=[];vars.each(function(def,name){if(self instanceof AST_Lambda&&find_if(function(x){return x.name==def.name.name},self.argnames)){vars.del(name)}else{def=def.clone();def.value=null;defs.push(def);vars.set(name,def)}});if(defs.length>0){for(var i=0;i1){if(cond[1]){return make_node(AST_For,self,{body:self.body})}else if(self instanceof AST_While){if(compressor.option("dead_code")){var a=[];extract_declarations_from_unreachable_code(compressor,self.body,a);return make_node(AST_BlockStatement,self,{body:a})}}}return self});function if_break_in_loop(self,compressor){function drop_it(rest){rest=as_statement_array(rest);if(self.body instanceof AST_BlockStatement){self.body=self.body.clone();self.body.body=rest.concat(self.body.body.slice(1));self.body=self.body.transform(compressor)}else{self.body=make_node(AST_BlockStatement,self.body,{body:rest}).transform(compressor)}if_break_in_loop(self,compressor)}var first=self.body instanceof AST_BlockStatement?self.body.body[0]:self.body;if(first instanceof AST_If){if(first.body instanceof AST_Break&&compressor.loopcontrol_target(first.body.label)===self){if(self.condition){self.condition=make_node(AST_Binary,self.condition,{left:self.condition,operator:"&&",right:first.condition.negate(compressor)})}else{self.condition=first.condition.negate(compressor)}drop_it(first.alternative)}else if(first.alternative instanceof AST_Break&&compressor.loopcontrol_target(first.alternative.label)===self){if(self.condition){self.condition=make_node(AST_Binary,self.condition,{left:self.condition,operator:"&&",right:first.condition})}else{self.condition=first.condition}drop_it(first.body)}}}OPT(AST_While,function(self,compressor){if(!compressor.option("loops"))return self;self=AST_DWLoop.prototype.optimize.call(self,compressor);if(self instanceof AST_While){if_break_in_loop(self,compressor);self=make_node(AST_For,self,self).transform(compressor)}return self});OPT(AST_For,function(self,compressor){var cond=self.condition;if(cond){cond=cond.evaluate(compressor);self.condition=cond[0]}if(!compressor.option("loops"))return self;if(cond){if(cond.length>1&&!cond[1]){if(compressor.option("dead_code")){var a=[];if(self.init instanceof AST_Statement){a.push(self.init)}else if(self.init){a.push(make_node(AST_SimpleStatement,self.init,{body:self.init}))}extract_declarations_from_unreachable_code(compressor,self.body,a);return make_node(AST_BlockStatement,self,{body:a})}}}if_break_in_loop(self,compressor);return self});OPT(AST_If,function(self,compressor){if(!compressor.option("conditionals"))return self;var cond=self.condition.evaluate(compressor);self.condition=cond[0];if(cond.length>1){if(cond[1]){compressor.warn("Condition always true [{file}:{line},{col}]",self.condition.start);if(compressor.option("dead_code")){var a=[];if(self.alternative){extract_declarations_from_unreachable_code(compressor,self.alternative,a)}a.push(self.body);return make_node(AST_BlockStatement,self,{body:a}).transform(compressor)}}else{compressor.warn("Condition always false [{file}:{line},{col}]",self.condition.start);if(compressor.option("dead_code")){var a=[];extract_declarations_from_unreachable_code(compressor,self.body,a);if(self.alternative)a.push(self.alternative);return make_node(AST_BlockStatement,self,{body:a}).transform(compressor)}}}if(is_empty(self.alternative))self.alternative=null;var negated=self.condition.negate(compressor);var negated_is_best=best_of(self.condition,negated)===negated;if(self.alternative&&negated_is_best){negated_is_best=false;self.condition=negated;var tmp=self.body;self.body=self.alternative||make_node(AST_EmptyStatement);self.alternative=tmp}if(is_empty(self.body)&&is_empty(self.alternative)){return make_node(AST_SimpleStatement,self.condition,{body:self.condition}).transform(compressor)}if(self.body instanceof AST_SimpleStatement&&self.alternative instanceof AST_SimpleStatement){return make_node(AST_SimpleStatement,self,{body:make_node(AST_Conditional,self,{condition:self.condition,consequent:self.body.body,alternative:self.alternative.body})}).transform(compressor) +}if(is_empty(self.alternative)&&self.body instanceof AST_SimpleStatement){if(negated_is_best)return make_node(AST_SimpleStatement,self,{body:make_node(AST_Binary,self,{operator:"||",left:negated,right:self.body.body})}).transform(compressor);return make_node(AST_SimpleStatement,self,{body:make_node(AST_Binary,self,{operator:"&&",left:self.condition,right:self.body.body})}).transform(compressor)}if(self.body instanceof AST_EmptyStatement&&self.alternative&&self.alternative instanceof AST_SimpleStatement){return make_node(AST_SimpleStatement,self,{body:make_node(AST_Binary,self,{operator:"||",left:self.condition,right:self.alternative.body})}).transform(compressor)}if(self.body instanceof AST_Exit&&self.alternative instanceof AST_Exit&&self.body.TYPE==self.alternative.TYPE){return make_node(self.body.CTOR,self,{value:make_node(AST_Conditional,self,{condition:self.condition,consequent:self.body.value||make_node(AST_Undefined,self.body).optimize(compressor),alternative:self.alternative.value||make_node(AST_Undefined,self.alternative).optimize(compressor)})}).transform(compressor)}if(self.body instanceof AST_If&&!self.body.alternative&&!self.alternative){self.condition=make_node(AST_Binary,self.condition,{operator:"&&",left:self.condition,right:self.body.condition}).transform(compressor);self.body=self.body.body}if(aborts(self.body)){if(self.alternative){var alt=self.alternative;self.alternative=null;return make_node(AST_BlockStatement,self,{body:[self,alt]}).transform(compressor)}}if(aborts(self.alternative)){var body=self.body;self.body=self.alternative;self.condition=negated_is_best?negated:self.condition.negate(compressor);self.alternative=null;return make_node(AST_BlockStatement,self,{body:[self,body]}).transform(compressor)}return self});OPT(AST_Switch,function(self,compressor){if(self.body.length==0&&compressor.option("conditionals")){return make_node(AST_SimpleStatement,self,{body:self.expression}).transform(compressor)}for(;;){var last_branch=self.body[self.body.length-1];if(last_branch){var stat=last_branch.body[last_branch.body.length-1];if(stat instanceof AST_Break&&loop_body(compressor.loopcontrol_target(stat.label))===self)last_branch.body.pop();if(last_branch instanceof AST_Default&&last_branch.body.length==0){self.body.pop();continue}}break}var exp=self.expression.evaluate(compressor);out:if(exp.length==2)try{self.expression=exp[0];if(!compressor.option("dead_code"))break out;var value=exp[1];var in_if=false;var in_block=false;var started=false;var stopped=false;var ruined=false;var tt=new TreeTransformer(function(node,descend,in_list){if(node instanceof AST_Lambda||node instanceof AST_SimpleStatement){return node}else if(node instanceof AST_Switch&&node===self){node=node.clone();descend(node,this);return ruined?node:make_node(AST_BlockStatement,node,{body:node.body.reduce(function(a,branch){return a.concat(branch.body)},[])}).transform(compressor)}else if(node instanceof AST_If||node instanceof AST_Try){var save=in_if;in_if=!in_block;descend(node,this);in_if=save;return node}else if(node instanceof AST_StatementWithBody||node instanceof AST_Switch){var save=in_block;in_block=true;descend(node,this);in_block=save;return node}else if(node instanceof AST_Break&&this.loopcontrol_target(node.label)===self){if(in_if){ruined=true;return node}if(in_block)return node;stopped=true;return in_list?MAP.skip:make_node(AST_EmptyStatement,node)}else if(node instanceof AST_SwitchBranch&&this.parent()===self){if(stopped)return MAP.skip;if(node instanceof AST_Case){var exp=node.expression.evaluate(compressor);if(exp.length<2){throw self}if(exp[1]===value||started){started=true;if(aborts(node))stopped=true;descend(node,this);return node}return MAP.skip}descend(node,this);return node}});tt.stack=compressor.stack.slice();self=self.transform(tt)}catch(ex){if(ex!==self)throw ex}return self});OPT(AST_Case,function(self,compressor){self.body=tighten_body(self.body,compressor);return self});OPT(AST_Try,function(self,compressor){self.body=tighten_body(self.body,compressor);return self});AST_Definitions.DEFMETHOD("remove_initializers",function(){this.definitions.forEach(function(def){def.value=null})});AST_Definitions.DEFMETHOD("to_assignments",function(){var assignments=this.definitions.reduce(function(a,def){if(def.value){var name=make_node(AST_SymbolRef,def.name,def.name);a.push(make_node(AST_Assign,def,{operator:"=",left:name,right:def.value}))}return a},[]);if(assignments.length==0)return null;return AST_Seq.from_array(assignments)});OPT(AST_Definitions,function(self,compressor){if(self.definitions.length==0)return make_node(AST_EmptyStatement,self);return self});OPT(AST_Function,function(self,compressor){self=AST_Lambda.prototype.optimize.call(self,compressor);if(compressor.option("unused")){if(self.name&&self.name.unreferenced()){self.name=null}}return self});OPT(AST_Call,function(self,compressor){if(compressor.option("unsafe")){var exp=self.expression;if(exp instanceof AST_SymbolRef&&exp.undeclared()){switch(exp.name){case"Array":if(self.args.length!=1){return make_node(AST_Array,self,{elements:self.args}).transform(compressor)}break;case"Object":if(self.args.length==0){return make_node(AST_Object,self,{properties:[]})}break;case"String":if(self.args.length==0)return make_node(AST_String,self,{value:""});if(self.args.length<=1)return make_node(AST_Binary,self,{left:self.args[0],operator:"+",right:make_node(AST_String,self,{value:""})}).transform(compressor);break;case"Number":if(self.args.length==0)return make_node(AST_Number,self,{value:0});if(self.args.length==1)return make_node(AST_UnaryPrefix,self,{expression:self.args[0],operator:"+"}).transform(compressor);case"Boolean":if(self.args.length==0)return make_node(AST_False,self);if(self.args.length==1)return make_node(AST_UnaryPrefix,self,{expression:make_node(AST_UnaryPrefix,null,{expression:self.args[0],operator:"!"}),operator:"!"}).transform(compressor);break;case"Function":if(all(self.args,function(x){return x instanceof AST_String})){try{var code="(function("+self.args.slice(0,-1).map(function(arg){return arg.value}).join(",")+"){"+self.args[self.args.length-1].value+"})()";var ast=parse(code);ast.figure_out_scope({screw_ie8:compressor.option("screw_ie8")});var comp=new Compressor(compressor.options);ast=ast.transform(comp);ast.figure_out_scope({screw_ie8:compressor.option("screw_ie8")});ast.mangle_names();var fun;try{ast.walk(new TreeWalker(function(node){if(node instanceof AST_Lambda){fun=node;throw ast}}))}catch(ex){if(ex!==ast)throw ex}if(!fun)return self;var args=fun.argnames.map(function(arg,i){return make_node(AST_String,self.args[i],{value:arg.print_to_string()})});var code=OutputStream();AST_BlockStatement.prototype._codegen.call(fun,fun,code);code=code.toString().replace(/^\{|\}$/g,"");args.push(make_node(AST_String,self.args[self.args.length-1],{value:code}));self.args=args;return self}catch(ex){if(ex instanceof JS_Parse_Error){compressor.warn("Error parsing code passed to new Function [{file}:{line},{col}]",self.args[self.args.length-1].start);compressor.warn(ex.toString())}else{console.log(ex);throw ex}}}break}}else if(exp instanceof AST_Dot&&exp.property=="toString"&&self.args.length==0){return make_node(AST_Binary,self,{left:make_node(AST_String,self,{value:""}),operator:"+",right:exp.expression}).transform(compressor)}else if(exp instanceof AST_Dot&&exp.expression instanceof AST_Array&&exp.property=="join")EXIT:{var separator=self.args.length==0?",":self.args[0].evaluate(compressor)[1];if(separator==null)break EXIT;var elements=exp.expression.elements.reduce(function(a,el){el=el.evaluate(compressor);if(a.length==0||el.length==1){a.push(el)}else{var last=a[a.length-1];if(last.length==2){var val=""+last[1]+separator+el[1];a[a.length-1]=[make_node_from_constant(compressor,val,last[0]),val]}else{a.push(el)}}return a},[]);if(elements.length==0)return make_node(AST_String,self,{value:""});if(elements.length==1)return elements[0][0];if(separator==""){var first;if(elements[0][0]instanceof AST_String||elements[1][0]instanceof AST_String){first=elements.shift()[0]}else{first=make_node(AST_String,self,{value:""})}return elements.reduce(function(prev,el){return make_node(AST_Binary,el[0],{operator:"+",left:prev,right:el[0]})},first).transform(compressor)}var node=self.clone();node.expression=node.expression.clone();node.expression.expression=node.expression.expression.clone();node.expression.expression.elements=elements.map(function(el){return el[0]});return best_of(self,node)}}if(compressor.option("side_effects")){if(self.expression instanceof AST_Function&&self.args.length==0&&!AST_Block.prototype.has_side_effects.call(self.expression,compressor)){return make_node(AST_Undefined,self).transform(compressor)}}if(compressor.option("drop_console")){if(self.expression instanceof AST_PropAccess&&self.expression.expression instanceof AST_SymbolRef&&self.expression.expression.name=="console"&&self.expression.expression.undeclared()){return make_node(AST_Undefined,self).transform(compressor)}}return self.evaluate(compressor)[0]});OPT(AST_New,function(self,compressor){if(compressor.option("unsafe")){var exp=self.expression;if(exp instanceof AST_SymbolRef&&exp.undeclared()){switch(exp.name){case"Object":case"RegExp":case"Function":case"Error":case"Array":return make_node(AST_Call,self,self).transform(compressor)}}}return self});OPT(AST_Seq,function(self,compressor){if(!compressor.option("side_effects"))return self;if(!self.car.has_side_effects(compressor)){var p;if(!(self.cdr instanceof AST_SymbolRef&&self.cdr.name=="eval"&&self.cdr.undeclared()&&(p=compressor.parent())instanceof AST_Call&&p.expression===self)){return self.cdr}}if(compressor.option("cascade")){if(self.car instanceof AST_Assign&&!self.car.left.has_side_effects(compressor)){if(self.car.left.equivalent_to(self.cdr)){return self.car}if(self.cdr instanceof AST_Call&&self.cdr.expression.equivalent_to(self.car.left)){self.cdr.expression=self.car;return self.cdr}}if(!self.car.has_side_effects(compressor)&&!self.cdr.has_side_effects(compressor)&&self.car.equivalent_to(self.cdr)){return self.car}}if(self.cdr instanceof AST_UnaryPrefix&&self.cdr.operator=="void"&&!self.cdr.expression.has_side_effects(compressor)){self.cdr.operator=self.car;return self.cdr}if(self.cdr instanceof AST_Undefined){return make_node(AST_UnaryPrefix,self,{operator:"void",expression:self.car})}return self});AST_Unary.DEFMETHOD("lift_sequences",function(compressor){if(compressor.option("sequences")){if(this.expression instanceof AST_Seq){var seq=this.expression;var x=seq.to_array();this.expression=x.pop();x.push(this);seq=AST_Seq.from_array(x).transform(compressor);return seq}}return this});OPT(AST_UnaryPostfix,function(self,compressor){return self.lift_sequences(compressor)});OPT(AST_UnaryPrefix,function(self,compressor){self=self.lift_sequences(compressor);var e=self.expression;if(compressor.option("booleans")&&compressor.in_boolean_context()){switch(self.operator){case"!":if(e instanceof AST_UnaryPrefix&&e.operator=="!"){return e.expression}break;case"typeof":compressor.warn("Boolean expression always true [{file}:{line},{col}]",self.start);return make_node(AST_True,self)}if(e instanceof AST_Binary&&self.operator=="!"){self=best_of(self,e.negate(compressor))}}return self.evaluate(compressor)[0]});function has_side_effects_or_prop_access(node,compressor){var save_pure_getters=compressor.option("pure_getters");compressor.options.pure_getters=false;var ret=node.has_side_effects(compressor);compressor.options.pure_getters=save_pure_getters;return ret}AST_Binary.DEFMETHOD("lift_sequences",function(compressor){if(compressor.option("sequences")){if(this.left instanceof AST_Seq){var seq=this.left;var x=seq.to_array();this.left=x.pop();x.push(this);seq=AST_Seq.from_array(x).transform(compressor);return seq}if(this.right instanceof AST_Seq&&this instanceof AST_Assign&&!has_side_effects_or_prop_access(this.left,compressor)){var seq=this.right;var x=seq.to_array();this.right=x.pop();x.push(this);seq=AST_Seq.from_array(x).transform(compressor);return seq}}return this});var commutativeOperators=makePredicate("== === != !== * & | ^");OPT(AST_Binary,function(self,compressor){var reverse=compressor.has_directive("use asm")?noop:function(op,force){if(force||!(self.left.has_side_effects(compressor)||self.right.has_side_effects(compressor))){if(op)self.operator=op;var tmp=self.left;self.left=self.right;self.right=tmp}};if(commutativeOperators(self.operator)){if(self.right instanceof AST_Constant&&!(self.left instanceof AST_Constant)){if(!(self.left instanceof AST_Binary&&PRECEDENCE[self.left.operator]>=PRECEDENCE[self.operator])){reverse(null,true)}}if(/^[!=]==?$/.test(self.operator)){if(self.left instanceof AST_SymbolRef&&self.right instanceof AST_Conditional){if(self.right.consequent instanceof AST_SymbolRef&&self.right.consequent.definition()===self.left.definition()){if(/^==/.test(self.operator))return self.right.condition;if(/^!=/.test(self.operator))return self.right.condition.negate(compressor)}if(self.right.alternative instanceof AST_SymbolRef&&self.right.alternative.definition()===self.left.definition()){if(/^==/.test(self.operator))return self.right.condition.negate(compressor);if(/^!=/.test(self.operator))return self.right.condition}}if(self.right instanceof AST_SymbolRef&&self.left instanceof AST_Conditional){if(self.left.consequent instanceof AST_SymbolRef&&self.left.consequent.definition()===self.right.definition()){if(/^==/.test(self.operator))return self.left.condition;if(/^!=/.test(self.operator))return self.left.condition.negate(compressor)}if(self.left.alternative instanceof AST_SymbolRef&&self.left.alternative.definition()===self.right.definition()){if(/^==/.test(self.operator))return self.left.condition.negate(compressor);if(/^!=/.test(self.operator))return self.left.condition}}}}self=self.lift_sequences(compressor);if(compressor.option("comparisons"))switch(self.operator){case"===":case"!==":if(self.left.is_string(compressor)&&self.right.is_string(compressor)||self.left.is_boolean()&&self.right.is_boolean()){self.operator=self.operator.substr(0,2)}case"==":case"!=":if(self.left instanceof AST_String&&self.left.value=="undefined"&&self.right instanceof AST_UnaryPrefix&&self.right.operator=="typeof"&&compressor.option("unsafe")){if(!(self.right.expression instanceof AST_SymbolRef)||!self.right.expression.undeclared()){self.right=self.right.expression;self.left=make_node(AST_Undefined,self.left).optimize(compressor);if(self.operator.length==2)self.operator+="="}}break}if(compressor.option("booleans")&&compressor.in_boolean_context())switch(self.operator){case"&&":var ll=self.left.evaluate(compressor);var rr=self.right.evaluate(compressor);if(ll.length>1&&!ll[1]||rr.length>1&&!rr[1]){compressor.warn("Boolean && always false [{file}:{line},{col}]",self.start);return make_node(AST_False,self)}if(ll.length>1&&ll[1]){return rr[0]}if(rr.length>1&&rr[1]){return ll[0]}break;case"||":var ll=self.left.evaluate(compressor);var rr=self.right.evaluate(compressor);if(ll.length>1&&ll[1]||rr.length>1&&rr[1]){compressor.warn("Boolean || always true [{file}:{line},{col}]",self.start);return make_node(AST_True,self)}if(ll.length>1&&!ll[1]){return rr[0]}if(rr.length>1&&!rr[1]){return ll[0]}break;case"+":var ll=self.left.evaluate(compressor);var rr=self.right.evaluate(compressor);if(ll.length>1&&ll[0]instanceof AST_String&&ll[1]||rr.length>1&&rr[0]instanceof AST_String&&rr[1]){compressor.warn("+ in boolean context always true [{file}:{line},{col}]",self.start);return make_node(AST_True,self)}break}if(compressor.option("comparisons")){if(!(compressor.parent()instanceof AST_Binary)||compressor.parent()instanceof AST_Assign){var negated=make_node(AST_UnaryPrefix,self,{operator:"!",expression:self.negate(compressor)});self=best_of(self,negated)}switch(self.operator){case"<":reverse(">");break;case"<=":reverse(">=");break}}if(self.operator=="+"&&self.right instanceof AST_String&&self.right.getValue()===""&&self.left instanceof AST_Binary&&self.left.operator=="+"&&self.left.is_string(compressor)){return self.left}if(compressor.option("evaluate")){if(self.operator=="+"){if(self.left instanceof AST_Constant&&self.right instanceof AST_Binary&&self.right.operator=="+"&&self.right.left instanceof AST_Constant&&self.right.is_string(compressor)){self=make_node(AST_Binary,self,{operator:"+",left:make_node(AST_String,null,{value:""+self.left.getValue()+self.right.left.getValue(),start:self.left.start,end:self.right.left.end}),right:self.right.right})}if(self.right instanceof AST_Constant&&self.left instanceof AST_Binary&&self.left.operator=="+"&&self.left.right instanceof AST_Constant&&self.left.is_string(compressor)){self=make_node(AST_Binary,self,{operator:"+",left:self.left.left,right:make_node(AST_String,null,{value:""+self.left.right.getValue()+self.right.getValue(),start:self.left.right.start,end:self.right.end})})}if(self.left instanceof AST_Binary&&self.left.operator=="+"&&self.left.is_string(compressor)&&self.left.right instanceof AST_Constant&&self.right instanceof AST_Binary&&self.right.operator=="+"&&self.right.left instanceof AST_Constant&&self.right.is_string(compressor)){self=make_node(AST_Binary,self,{operator:"+",left:make_node(AST_Binary,self.left,{operator:"+",left:self.left.left,right:make_node(AST_String,null,{value:""+self.left.right.getValue()+self.right.left.getValue(),start:self.left.right.start,end:self.right.left.end})}),right:self.right.right})}}}if(self.right instanceof AST_Binary&&self.right.operator==self.operator&&(self.operator=="*"||self.operator=="&&"||self.operator=="||")){self.left=make_node(AST_Binary,self.left,{operator:self.operator,left:self.left,right:self.right.left});self.right=self.right.right;return self.transform(compressor)}return self.evaluate(compressor)[0]});OPT(AST_SymbolRef,function(self,compressor){if(self.undeclared()){var defines=compressor.option("global_defs");if(defines&&defines.hasOwnProperty(self.name)){return make_node_from_constant(compressor,defines[self.name],self)}switch(self.name){case"undefined":return make_node(AST_Undefined,self);case"NaN":return make_node(AST_NaN,self);case"Infinity":return make_node(AST_Infinity,self)}}return self});OPT(AST_Undefined,function(self,compressor){if(compressor.option("unsafe")){var scope=compressor.find_parent(AST_Scope);var undef=scope.find_variable("undefined");if(undef){var ref=make_node(AST_SymbolRef,self,{name:"undefined",scope:scope,thedef:undef});ref.reference();return ref}}return self});var ASSIGN_OPS=["+","-","/","*","%",">>","<<",">>>","|","^","&"];OPT(AST_Assign,function(self,compressor){self=self.lift_sequences(compressor);if(self.operator=="="&&self.left instanceof AST_SymbolRef&&self.right instanceof AST_Binary&&self.right.left instanceof AST_SymbolRef&&self.right.left.name==self.left.name&&member(self.right.operator,ASSIGN_OPS)){self.operator=self.right.operator+"=";self.right=self.right.right}return self});OPT(AST_Conditional,function(self,compressor){if(!compressor.option("conditionals"))return self;if(self.condition instanceof AST_Seq){var car=self.condition.car;self.condition=self.condition.cdr;return AST_Seq.cons(car,self)}var cond=self.condition.evaluate(compressor);if(cond.length>1){if(cond[1]){compressor.warn("Condition always true [{file}:{line},{col}]",self.start);return self.consequent}else{compressor.warn("Condition always false [{file}:{line},{col}]",self.start);return self.alternative}}var negated=cond[0].negate(compressor);if(best_of(cond[0],negated)===negated){self=make_node(AST_Conditional,self,{condition:negated,consequent:self.alternative,alternative:self.consequent})}var consequent=self.consequent;var alternative=self.alternative;if(consequent instanceof AST_Assign&&alternative instanceof AST_Assign&&consequent.operator==alternative.operator&&consequent.left.equivalent_to(alternative.left)){return make_node(AST_Assign,self,{operator:consequent.operator,left:consequent.left,right:make_node(AST_Conditional,self,{condition:self.condition,consequent:consequent.right,alternative:alternative.right})})}if(consequent instanceof AST_Call&&alternative.TYPE===consequent.TYPE&&consequent.args.length==alternative.args.length&&consequent.expression.equivalent_to(alternative.expression)){if(consequent.args.length==0){return make_node(AST_Seq,self,{car:self.condition,cdr:consequent})}if(consequent.args.length==1){consequent.args[0]=make_node(AST_Conditional,self,{condition:self.condition,consequent:consequent.args[0],alternative:alternative.args[0]});return consequent}}if(consequent instanceof AST_Conditional&&consequent.alternative.equivalent_to(alternative)){return make_node(AST_Conditional,self,{condition:make_node(AST_Binary,self,{left:self.condition,operator:"&&",right:consequent.condition}),consequent:consequent.consequent,alternative:alternative})}if(consequent instanceof AST_Constant&&alternative instanceof AST_Constant&&consequent.equivalent_to(alternative)){if(self.condition.has_side_effects(compressor)){return AST_Seq.from_array([self.condition,make_node_from_constant(compressor,consequent.value,self)])}else{return make_node_from_constant(compressor,consequent.value,self)}}return self});OPT(AST_Boolean,function(self,compressor){if(compressor.option("booleans")){var p=compressor.parent();if(p instanceof AST_Binary&&(p.operator=="=="||p.operator=="!=")){compressor.warn("Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]",{operator:p.operator,value:self.value,file:p.start.file,line:p.start.line,col:p.start.col});return make_node(AST_Number,self,{value:+self.value})}return make_node(AST_UnaryPrefix,self,{operator:"!",expression:make_node(AST_Number,self,{value:1-self.value})})}return self});OPT(AST_Sub,function(self,compressor){var prop=self.property;if(prop instanceof AST_String&&compressor.option("properties")){prop=prop.getValue();if(RESERVED_WORDS(prop)?compressor.option("screw_ie8"):is_identifier_string(prop)){return make_node(AST_Dot,self,{expression:self.expression,property:prop}).optimize(compressor)}var v=parseFloat(prop);if(!isNaN(v)&&v.toString()==prop){self.property=make_node(AST_Number,self.property,{value:v})}}return self});OPT(AST_Dot,function(self,compressor){var prop=self.property;if(RESERVED_WORDS(prop)&&!compressor.option("screw_ie8")){return make_node(AST_Sub,self,{expression:self.expression,property:make_node(AST_String,self,{value:prop})}).optimize(compressor)}return self.evaluate(compressor)[0]});function literals_in_boolean_context(self,compressor){if(compressor.option("booleans")&&compressor.in_boolean_context()){return make_node(AST_True,self)}return self}OPT(AST_Array,literals_in_boolean_context);OPT(AST_Object,literals_in_boolean_context);OPT(AST_RegExp,literals_in_boolean_context)})();/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";function SourceMap(options){options=defaults(options,{file:null,root:null,orig:null,orig_line_diff:0,dest_line_diff:0});var generator=new MOZ_SourceMap.SourceMapGenerator({file:options.file,sourceRoot:options.root});var orig_map=options.orig&&new MOZ_SourceMap.SourceMapConsumer(options.orig);function add(source,gen_line,gen_col,orig_line,orig_col,name){if(orig_map){var info=orig_map.originalPositionFor({line:orig_line,column:orig_col});if(info.source===null){return}source=info.source;orig_line=info.line;orig_col=info.column;name=info.name||name}generator.addMapping({generated:{line:gen_line+options.dest_line_diff,column:gen_col},original:{line:orig_line+options.orig_line_diff,column:orig_col},source:source,name:name})}return{add:add,get:function(){return generator},toString:function(){return generator.toString()}}}/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + ***********************************************************************/ +"use strict";(function(){var MOZ_TO_ME={ExpressionStatement:function(M){var expr=M.expression;if(expr.type==="Literal"&&typeof expr.value==="string"){return new AST_Directive({start:my_start_token(M),end:my_end_token(M),value:expr.value})}return new AST_SimpleStatement({start:my_start_token(M),end:my_end_token(M),body:from_moz(expr)})},TryStatement:function(M){var handlers=M.handlers||[M.handler];if(handlers.length>1||M.guardedHandlers&&M.guardedHandlers.length){throw new Error("Multiple catch clauses are not supported.")}return new AST_Try({start:my_start_token(M),end:my_end_token(M),body:from_moz(M.block).body,bcatch:from_moz(handlers[0]),bfinally:M.finalizer?new AST_Finally(from_moz(M.finalizer)):null})},Property:function(M){var key=M.key;var name=key.type=="Identifier"?key.name:key.value;var args={start:my_start_token(key),end:my_end_token(M.value),key:name,value:from_moz(M.value)};switch(M.kind){case"init":return new AST_ObjectKeyVal(args);case"set":args.value.name=from_moz(key);return new AST_ObjectSetter(args);case"get":args.value.name=from_moz(key);return new AST_ObjectGetter(args)}},ObjectExpression:function(M){return new AST_Object({start:my_start_token(M),end:my_end_token(M),properties:M.properties.map(function(prop){prop.type="Property";return from_moz(prop)})})},SequenceExpression:function(M){return AST_Seq.from_array(M.expressions.map(from_moz))},MemberExpression:function(M){return new(M.computed?AST_Sub:AST_Dot)({start:my_start_token(M),end:my_end_token(M),property:M.computed?from_moz(M.property):M.property.name,expression:from_moz(M.object)})},SwitchCase:function(M){return new(M.test?AST_Case:AST_Default)({start:my_start_token(M),end:my_end_token(M),expression:from_moz(M.test),body:M.consequent.map(from_moz)})},VariableDeclaration:function(M){return new(M.kind==="const"?AST_Const:AST_Var)({start:my_start_token(M),end:my_end_token(M),definitions:M.declarations.map(from_moz)})},Literal:function(M){var val=M.value,args={start:my_start_token(M),end:my_end_token(M)};if(val===null)return new AST_Null(args);switch(typeof val){case"string":args.value=val;return new AST_String(args);case"number":args.value=val;return new AST_Number(args);case"boolean":return new(val?AST_True:AST_False)(args);default:args.value=val;return new AST_RegExp(args)}},Identifier:function(M){var p=FROM_MOZ_STACK[FROM_MOZ_STACK.length-2];return new(p.type=="LabeledStatement"?AST_Label:p.type=="VariableDeclarator"&&p.id===M?p.kind=="const"?AST_SymbolConst:AST_SymbolVar:p.type=="FunctionExpression"?p.id===M?AST_SymbolLambda:AST_SymbolFunarg:p.type=="FunctionDeclaration"?p.id===M?AST_SymbolDefun:AST_SymbolFunarg:p.type=="CatchClause"?AST_SymbolCatch:p.type=="BreakStatement"||p.type=="ContinueStatement"?AST_LabelRef:AST_SymbolRef)({start:my_start_token(M),end:my_end_token(M),name:M.name})}};MOZ_TO_ME.UpdateExpression=MOZ_TO_ME.UnaryExpression=function To_Moz_Unary(M){var prefix="prefix"in M?M.prefix:M.type=="UnaryExpression"?true:false;return new(prefix?AST_UnaryPrefix:AST_UnaryPostfix)({start:my_start_token(M),end:my_end_token(M),operator:M.operator,expression:from_moz(M.argument)})};map("Program",AST_Toplevel,"body@body");map("EmptyStatement",AST_EmptyStatement);map("BlockStatement",AST_BlockStatement,"body@body");map("IfStatement",AST_If,"test>condition, consequent>body, alternate>alternative");map("LabeledStatement",AST_LabeledStatement,"label>label, body>body");map("BreakStatement",AST_Break,"label>label");map("ContinueStatement",AST_Continue,"label>label");map("WithStatement",AST_With,"object>expression, body>body");map("SwitchStatement",AST_Switch,"discriminant>expression, cases@body");map("ReturnStatement",AST_Return,"argument>value");map("ThrowStatement",AST_Throw,"argument>value");map("WhileStatement",AST_While,"test>condition, body>body");map("DoWhileStatement",AST_Do,"test>condition, body>body");map("ForStatement",AST_For,"init>init, test>condition, update>step, body>body");map("ForInStatement",AST_ForIn,"left>init, right>object, body>body");map("DebuggerStatement",AST_Debugger);map("FunctionDeclaration",AST_Defun,"id>name, params@argnames, body%body");map("VariableDeclarator",AST_VarDef,"id>name, init>value");map("CatchClause",AST_Catch,"param>argname, body%body");map("ThisExpression",AST_This);map("ArrayExpression",AST_Array,"elements@elements");map("FunctionExpression",AST_Function,"id>name, params@argnames, body%body");map("BinaryExpression",AST_Binary,"operator=operator, left>left, right>right");map("LogicalExpression",AST_Binary,"operator=operator, left>left, right>right");map("AssignmentExpression",AST_Assign,"operator=operator, left>left, right>right");map("ConditionalExpression",AST_Conditional,"test>condition, consequent>consequent, alternate>alternative");map("NewExpression",AST_New,"callee>expression, arguments@args");map("CallExpression",AST_Call,"callee>expression, arguments@args");def_to_moz(AST_Directive,function To_Moz_Directive(M){return{type:"ExpressionStatement",expression:{type:"Literal",value:M.value}}});def_to_moz(AST_SimpleStatement,function To_Moz_ExpressionStatement(M){return{type:"ExpressionStatement",expression:to_moz(M.body)}});def_to_moz(AST_SwitchBranch,function To_Moz_SwitchCase(M){return{type:"SwitchCase",test:to_moz(M.expression),consequent:M.body.map(to_moz)}});def_to_moz(AST_Try,function To_Moz_TryStatement(M){return{type:"TryStatement",block:to_moz_block(M),handler:to_moz(M.bcatch),guardedHandlers:[],finalizer:to_moz(M.bfinally)}});def_to_moz(AST_Catch,function To_Moz_CatchClause(M){return{type:"CatchClause",param:to_moz(M.argname),guard:null,body:to_moz_block(M)}});def_to_moz(AST_Definitions,function To_Moz_VariableDeclaration(M){return{type:"VariableDeclaration",kind:M instanceof AST_Const?"const":"var",declarations:M.definitions.map(to_moz)}});def_to_moz(AST_Seq,function To_Moz_SequenceExpression(M){return{type:"SequenceExpression",expressions:M.to_array().map(to_moz)}});def_to_moz(AST_PropAccess,function To_Moz_MemberExpression(M){var isComputed=M instanceof AST_Sub;return{type:"MemberExpression",object:to_moz(M.expression),computed:isComputed,property:isComputed?to_moz(M.property):{type:"Identifier",name:M.property}}});def_to_moz(AST_Unary,function To_Moz_Unary(M){return{type:M.operator=="++"||M.operator=="--"?"UpdateExpression":"UnaryExpression",operator:M.operator,prefix:M instanceof AST_UnaryPrefix,argument:to_moz(M.expression)}});def_to_moz(AST_Binary,function To_Moz_BinaryExpression(M){return{type:M.operator=="&&"||M.operator=="||"?"LogicalExpression":"BinaryExpression",left:to_moz(M.left),operator:M.operator,right:to_moz(M.right)}});def_to_moz(AST_Object,function To_Moz_ObjectExpression(M){return{type:"ObjectExpression",properties:M.properties.map(to_moz)}});def_to_moz(AST_ObjectProperty,function To_Moz_Property(M){var key=is_identifier(M.key)?{type:"Identifier",name:M.key}:{type:"Literal",value:M.key};var kind;if(M instanceof AST_ObjectKeyVal){kind="init"}else if(M instanceof AST_ObjectGetter){kind="get"}else if(M instanceof AST_ObjectSetter){kind="set"}return{type:"Property",kind:kind,key:key,value:to_moz(M.value)}});def_to_moz(AST_Symbol,function To_Moz_Identifier(M){var def=M.definition();return{type:"Identifier",name:def?def.mangled_name||def.name:M.name}});def_to_moz(AST_Constant,function To_Moz_Literal(M){var value=M.value;if(typeof value==="number"&&(value<0||value===0&&1/value<0)){return{type:"UnaryExpression",operator:"-",prefix:true,argument:{type:"Literal",value:-value}}}return{type:"Literal",value:value}});def_to_moz(AST_Atom,function To_Moz_Atom(M){return{type:"Identifier",name:String(M.value)}});AST_Boolean.DEFMETHOD("to_mozilla_ast",AST_Constant.prototype.to_mozilla_ast);AST_Null.DEFMETHOD("to_mozilla_ast",AST_Constant.prototype.to_mozilla_ast);AST_Hole.DEFMETHOD("to_mozilla_ast",function To_Moz_ArrayHole(){return null});AST_Block.DEFMETHOD("to_mozilla_ast",AST_BlockStatement.prototype.to_mozilla_ast);AST_Lambda.DEFMETHOD("to_mozilla_ast",AST_Function.prototype.to_mozilla_ast);function my_start_token(moznode){var loc=moznode.loc;var range=moznode.range;return new AST_Token({file:loc&&loc.source,line:loc&&loc.start.line,col:loc&&loc.start.column,pos:range?range[0]:moznode.start,endpos:range?range[0]:moznode.start})}function my_end_token(moznode){var loc=moznode.loc;var range=moznode.range;return new AST_Token({file:loc&&loc.source,line:loc&&loc.end.line,col:loc&&loc.end.column,pos:range?range[1]:moznode.end,endpos:range?range[1]:moznode.end})}function map(moztype,mytype,propmap){var moz_to_me="function From_Moz_"+moztype+"(M){\n";moz_to_me+="return new "+mytype.name+"({\n"+"start: my_start_token(M),\n"+"end: my_end_token(M)";var me_to_moz="function To_Moz_"+moztype+"(M){\n";me_to_moz+="return {\n"+"type: "+JSON.stringify(moztype);if(propmap)propmap.split(/\s*,\s*/).forEach(function(prop){var m=/([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);if(!m)throw new Error("Can't understand property map: "+prop);var moz=m[1],how=m[2],my=m[3];moz_to_me+=",\n"+my+": ";me_to_moz+=",\n"+moz+": ";switch(how){case"@":moz_to_me+="M."+moz+".map(from_moz)";me_to_moz+="M."+my+".map(to_moz)";break;case">":moz_to_me+="from_moz(M."+moz+")";me_to_moz+="to_moz(M."+my+")";break;case"=":moz_to_me+="M."+moz;me_to_moz+="M."+my;break;case"%":moz_to_me+="from_moz(M."+moz+").body";me_to_moz+="to_moz_block(M)";break;default:throw new Error("Can't understand operator in propmap: "+prop)}});moz_to_me+="\n})\n}";me_to_moz+="\n}\n}";moz_to_me=new Function("my_start_token","my_end_token","from_moz","return("+moz_to_me+")")(my_start_token,my_end_token,from_moz);me_to_moz=new Function("to_moz","to_moz_block","return("+me_to_moz+")")(to_moz,to_moz_block);MOZ_TO_ME[moztype]=moz_to_me;def_to_moz(mytype,me_to_moz)}var FROM_MOZ_STACK=null;function from_moz(node){FROM_MOZ_STACK.push(node);var ret=node!=null?MOZ_TO_ME[node.type](node):null;FROM_MOZ_STACK.pop();return ret}AST_Node.from_mozilla_ast=function(node){var save_stack=FROM_MOZ_STACK;FROM_MOZ_STACK=[];var ast=from_moz(node);FROM_MOZ_STACK=save_stack;return ast};function moz_sub_loc(token){return token.line?{line:token.line,column:token.col}:null}function set_moz_loc(mynode,moznode){var start=mynode.start;var end=mynode.end;if(start.pos!=null&&end.pos!=null){moznode.range=[start.pos,end.pos]}if(start.line){moznode.loc={start:moz_sub_loc(start),end:moz_sub_loc(end)};if(start.file){moznode.loc.source=start.file}}return moznode}function def_to_moz(mytype,handler){mytype.DEFMETHOD("to_mozilla_ast",function(){return set_moz_loc(this,handler(this))})}function to_moz(node){return node!=null?node.to_mozilla_ast():null}function to_moz_block(node){return{type:"BlockStatement",body:node.body.map(to_moz)}}})();exports["array_to_hash"]=array_to_hash;exports["slice"]=slice;exports["characters"]=characters;exports["member"]=member;exports["find_if"]=find_if;exports["repeat_string"]=repeat_string;exports["DefaultsError"]=DefaultsError;exports["defaults"]=defaults;exports["merge"]=merge;exports["noop"]=noop;exports["MAP"]=MAP;exports["push_uniq"]=push_uniq;exports["string_template"]=string_template;exports["remove"]=remove;exports["mergeSort"]=mergeSort;exports["set_difference"]=set_difference;exports["set_intersection"]=set_intersection;exports["makePredicate"]=makePredicate;exports["all"]=all;exports["Dictionary"]=Dictionary;exports["DEFNODE"]=DEFNODE;exports["AST_Token"]=AST_Token;exports["AST_Node"]=AST_Node;exports["AST_Statement"]=AST_Statement;exports["AST_Debugger"]=AST_Debugger;exports["AST_Directive"]=AST_Directive;exports["AST_SimpleStatement"]=AST_SimpleStatement;exports["walk_body"]=walk_body;exports["AST_Block"]=AST_Block;exports["AST_BlockStatement"]=AST_BlockStatement;exports["AST_EmptyStatement"]=AST_EmptyStatement;exports["AST_StatementWithBody"]=AST_StatementWithBody;exports["AST_LabeledStatement"]=AST_LabeledStatement;exports["AST_IterationStatement"]=AST_IterationStatement;exports["AST_DWLoop"]=AST_DWLoop;exports["AST_Do"]=AST_Do;exports["AST_While"]=AST_While;exports["AST_For"]=AST_For;exports["AST_ForIn"]=AST_ForIn;exports["AST_With"]=AST_With;exports["AST_Scope"]=AST_Scope;exports["AST_Toplevel"]=AST_Toplevel;exports["AST_Lambda"]=AST_Lambda;exports["AST_Accessor"]=AST_Accessor;exports["AST_Function"]=AST_Function;exports["AST_Defun"]=AST_Defun;exports["AST_Jump"]=AST_Jump;exports["AST_Exit"]=AST_Exit;exports["AST_Return"]=AST_Return;exports["AST_Throw"]=AST_Throw;exports["AST_LoopControl"]=AST_LoopControl;exports["AST_Break"]=AST_Break;exports["AST_Continue"]=AST_Continue;exports["AST_If"]=AST_If;exports["AST_Switch"]=AST_Switch;exports["AST_SwitchBranch"]=AST_SwitchBranch;exports["AST_Default"]=AST_Default;exports["AST_Case"]=AST_Case;exports["AST_Try"]=AST_Try;exports["AST_Catch"]=AST_Catch;exports["AST_Finally"]=AST_Finally;exports["AST_Definitions"]=AST_Definitions;exports["AST_Var"]=AST_Var;exports["AST_Const"]=AST_Const;exports["AST_VarDef"]=AST_VarDef;exports["AST_Call"]=AST_Call;exports["AST_New"]=AST_New;exports["AST_Seq"]=AST_Seq;exports["AST_PropAccess"]=AST_PropAccess;exports["AST_Dot"]=AST_Dot;exports["AST_Sub"]=AST_Sub;exports["AST_Unary"]=AST_Unary;exports["AST_UnaryPrefix"]=AST_UnaryPrefix;exports["AST_UnaryPostfix"]=AST_UnaryPostfix;exports["AST_Binary"]=AST_Binary;exports["AST_Conditional"]=AST_Conditional;exports["AST_Assign"]=AST_Assign;exports["AST_Array"]=AST_Array;exports["AST_Object"]=AST_Object;exports["AST_ObjectProperty"]=AST_ObjectProperty;exports["AST_ObjectKeyVal"]=AST_ObjectKeyVal;exports["AST_ObjectSetter"]=AST_ObjectSetter;exports["AST_ObjectGetter"]=AST_ObjectGetter;exports["AST_Symbol"]=AST_Symbol;exports["AST_SymbolAccessor"]=AST_SymbolAccessor;exports["AST_SymbolDeclaration"]=AST_SymbolDeclaration;exports["AST_SymbolVar"]=AST_SymbolVar;exports["AST_SymbolConst"]=AST_SymbolConst;exports["AST_SymbolFunarg"]=AST_SymbolFunarg;exports["AST_SymbolDefun"]=AST_SymbolDefun;exports["AST_SymbolLambda"]=AST_SymbolLambda;exports["AST_SymbolCatch"]=AST_SymbolCatch;exports["AST_Label"]=AST_Label;exports["AST_SymbolRef"]=AST_SymbolRef;exports["AST_LabelRef"]=AST_LabelRef;exports["AST_This"]=AST_This;exports["AST_Constant"]=AST_Constant;exports["AST_String"]=AST_String;exports["AST_Number"]=AST_Number;exports["AST_RegExp"]=AST_RegExp;exports["AST_Atom"]=AST_Atom;exports["AST_Null"]=AST_Null;exports["AST_NaN"]=AST_NaN;exports["AST_Undefined"]=AST_Undefined;exports["AST_Hole"]=AST_Hole;exports["AST_Infinity"]=AST_Infinity;exports["AST_Boolean"]=AST_Boolean;exports["AST_False"]=AST_False;exports["AST_True"]=AST_True;exports["TreeWalker"]=TreeWalker;exports["KEYWORDS"]=KEYWORDS;exports["KEYWORDS_ATOM"]=KEYWORDS_ATOM;exports["RESERVED_WORDS"]=RESERVED_WORDS;exports["KEYWORDS_BEFORE_EXPRESSION"]=KEYWORDS_BEFORE_EXPRESSION;exports["OPERATOR_CHARS"]=OPERATOR_CHARS;exports["RE_HEX_NUMBER"]=RE_HEX_NUMBER;exports["RE_OCT_NUMBER"]=RE_OCT_NUMBER;exports["RE_DEC_NUMBER"]=RE_DEC_NUMBER;exports["OPERATORS"]=OPERATORS;exports["WHITESPACE_CHARS"]=WHITESPACE_CHARS;exports["PUNC_BEFORE_EXPRESSION"]=PUNC_BEFORE_EXPRESSION;exports["PUNC_CHARS"]=PUNC_CHARS;exports["REGEXP_MODIFIERS"]=REGEXP_MODIFIERS;exports["UNICODE"]=UNICODE;exports["is_letter"]=is_letter;exports["is_digit"]=is_digit;exports["is_alphanumeric_char"]=is_alphanumeric_char;exports["is_unicode_combining_mark"]=is_unicode_combining_mark;exports["is_unicode_connector_punctuation"]=is_unicode_connector_punctuation;exports["is_identifier"]=is_identifier;exports["is_identifier_start"]=is_identifier_start;exports["is_identifier_char"]=is_identifier_char;exports["is_identifier_string"]=is_identifier_string;exports["parse_js_number"]=parse_js_number;exports["JS_Parse_Error"]=JS_Parse_Error;exports["js_error"]=js_error;exports["is_token"]=is_token;exports["EX_EOF"]=EX_EOF;exports["tokenizer"]=tokenizer;exports["UNARY_PREFIX"]=UNARY_PREFIX;exports["UNARY_POSTFIX"]=UNARY_POSTFIX;exports["ASSIGNMENT"]=ASSIGNMENT;exports["PRECEDENCE"]=PRECEDENCE;exports["STATEMENTS_WITH_LABELS"]=STATEMENTS_WITH_LABELS;exports["ATOMIC_START_TOKEN"]=ATOMIC_START_TOKEN;exports["parse"]=parse;exports["TreeTransformer"]=TreeTransformer;exports["SymbolDef"]=SymbolDef;exports["base54"]=base54;exports["OutputStream"]=OutputStream;exports["Compressor"]=Compressor;exports["SourceMap"]=SourceMap})({},function(){return this}()); diff --git a/test/test_execjs.rb b/test/test_execjs.rb index 09ee585..91ef6cb 100644 --- a/test/test_execjs.rb +++ b/test/test_execjs.rb @@ -253,41 +253,98 @@ class TestExecJS < Test end def test_exec_syntax_error - assert_raises ExecJS::RuntimeError do + begin ExecJS.exec(")") + flunk + rescue ExecJS::RuntimeError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") end end def test_eval_syntax_error - assert_raises ExecJS::RuntimeError do + begin ExecJS.eval(")") + flunk + rescue ExecJS::RuntimeError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") end end def test_compile_syntax_error - assert_raises ExecJS::RuntimeError do + begin ExecJS.compile(")") + flunk + rescue ExecJS::RuntimeError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") end end - def test_exec_thrown_exception + def test_exec_thrown_error + begin + ExecJS.exec("throw new Error('hello')") + flunk + rescue ExecJS::ProgramError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + end + end + + def test_eval_thrown_error + begin + ExecJS.eval("(function(){ throw new Error('hello') })()") + flunk + rescue ExecJS::ProgramError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + end + end + + def test_compile_thrown_error + begin + ExecJS.compile("throw new Error('hello')") + flunk + rescue ExecJS::ProgramError => e + assert e + assert e.backtrace[0].include?("(execjs):1"), e.backtrace.join("\n") + end + end + + def test_exec_thrown_string assert_raises ExecJS::ProgramError do ExecJS.exec("throw 'hello'") end end - def test_eval_thrown_exception + def test_eval_thrown_string assert_raises ExecJS::ProgramError do - ExecJS.exec("throw 'hello'") + ExecJS.eval("(function(){ throw 'hello' })()") end end - def test_compile_thrown_exception + def test_compile_thrown_string assert_raises ExecJS::ProgramError do - ExecJS.exec("throw 'hello'") + ExecJS.compile("throw 'hello'") end end + def test_babel + skip if ExecJS.runtime.is_a?(ExecJS::RubyRhinoRuntime) + + assert source = File.read(File.expand_path("../fixtures/babel.js", __FILE__)) + source = <<-JS + var self = this; + #{source} + babel.eval = function(code) { + return eval(babel.transform(code)["code"]); + } + JS + context = ExecJS.compile(source) + assert_equal 64, context.call("babel.eval", "((x) => x * x)(8)") + end + def test_coffeescript # Skip coffeescript on Duktape for now skip if ExecJS.runtime.is_a?(ExecJS::DuktapeRuntime) @@ -296,4 +353,21 @@ class TestExecJS < Test context = ExecJS.compile(source) assert_equal 64, context.call("CoffeeScript.eval", "((x) -> x * x)(8)") end + + def test_uglify + assert source = File.read(File.expand_path("../fixtures/uglify.js", __FILE__)) + source = <<-JS + #{source} + + function uglify(source) { + var ast = UglifyJS.parse(source); + var stream = UglifyJS.OutputStream(); + ast.print(stream); + return stream.toString(); + } + JS + context = ExecJS.compile(source) + assert_equal "function foo(bar){return bar}", + context.call("uglify", "function foo(bar) {\n return bar;\n}") + end end