Comparing version 4.5.4 to 4.5.5
@@ -127,3 +127,7 @@ "use strict"; | ||
each(exts, function (old, ext) { | ||
require.extensions[ext] = old; | ||
if (old === undefined) { | ||
delete require.extensions[ext]; | ||
} else { | ||
require.extensions[ext] = old; | ||
} | ||
}); | ||
@@ -130,0 +134,0 @@ |
"use strict"; | ||
module.exports = Buffer; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -11,165 +11,173 @@ var repeating = require("repeating"); | ||
function Buffer(position, format) { | ||
this.position = position; | ||
this._indent = format.indent.base; | ||
this.format = format; | ||
this.buf = ""; | ||
} | ||
var Buffer = (function () { | ||
function Buffer(position, format) { | ||
_classCallCheck(this, Buffer); | ||
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); | ||
this.position = position; | ||
this._indent = format.indent.base; | ||
this.format = format; | ||
this.buf = ""; | ||
} | ||
}; | ||
Buffer.prototype.indentSize = function () { | ||
return this.getIndent().length; | ||
}; | ||
Buffer.prototype.get = function get() { | ||
return trimRight(this.buf); | ||
}; | ||
Buffer.prototype.indent = function () { | ||
this._indent++; | ||
}; | ||
Buffer.prototype.getIndent = function getIndent() { | ||
if (this.format.compact || this.format.concise) { | ||
return ""; | ||
} else { | ||
return repeating(this.format.indent.style, this._indent); | ||
} | ||
}; | ||
Buffer.prototype.dedent = function () { | ||
this._indent--; | ||
}; | ||
Buffer.prototype.indentSize = function indentSize() { | ||
return this.getIndent().length; | ||
}; | ||
Buffer.prototype.semicolon = function () { | ||
this.push(";"); | ||
}; | ||
Buffer.prototype.indent = function indent() { | ||
this._indent++; | ||
}; | ||
Buffer.prototype.ensureSemicolon = function () { | ||
if (!this.isLast(";")) this.semicolon(); | ||
}; | ||
Buffer.prototype.dedent = function dedent() { | ||
this._indent--; | ||
}; | ||
Buffer.prototype.rightBrace = function () { | ||
this.newline(true); | ||
this.push("}"); | ||
}; | ||
Buffer.prototype.semicolon = function semicolon() { | ||
this.push(";"); | ||
}; | ||
Buffer.prototype.keyword = function (name) { | ||
this.push(name); | ||
this.space(); | ||
}; | ||
Buffer.prototype.ensureSemicolon = function ensureSemicolon() { | ||
if (!this.isLast(";")) this.semicolon(); | ||
}; | ||
Buffer.prototype.space = function () { | ||
if (this.format.compact) return; | ||
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) { | ||
this.push(" "); | ||
} | ||
}; | ||
Buffer.prototype.rightBrace = function rightBrace() { | ||
this.newline(true); | ||
this.push("}"); | ||
}; | ||
Buffer.prototype.removeLast = function (cha) { | ||
if (this.format.compact) return; | ||
if (!this.isLast(cha)) return; | ||
Buffer.prototype.keyword = function keyword(name) { | ||
this.push(name); | ||
this.space(); | ||
}; | ||
this.buf = this.buf.substr(0, this.buf.length - 1); | ||
this.position.unshift(cha); | ||
}; | ||
Buffer.prototype.space = function space() { | ||
if (this.format.compact) return; | ||
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) { | ||
this.push(" "); | ||
} | ||
}; | ||
Buffer.prototype.newline = function (i, removeLast) { | ||
if (this.format.compact) return; | ||
Buffer.prototype.removeLast = function removeLast(cha) { | ||
if (this.format.compact) return; | ||
if (!this.isLast(cha)) return; | ||
if (this.format.concise) { | ||
this.space(); | ||
return; | ||
} | ||
this.buf = this.buf.substr(0, this.buf.length - 1); | ||
this.position.unshift(cha); | ||
}; | ||
if (!removeLast) removeLast = false; | ||
Buffer.prototype.newline = function newline(i, removeLast) { | ||
if (this.format.compact) return; | ||
if (isNumber(i)) { | ||
i = Math.min(2, i); | ||
if (this.format.concise) { | ||
this.space(); | ||
return; | ||
} | ||
if (this.endsWith("{\n") || this.endsWith(":\n")) i--; | ||
if (i <= 0) return; | ||
if (!removeLast) removeLast = false; | ||
while (i > 0) { | ||
this._newline(removeLast); | ||
i--; | ||
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; | ||
} | ||
return; | ||
} | ||
if (isBoolean(i)) { | ||
removeLast = i; | ||
} | ||
if (isBoolean(i)) { | ||
removeLast = i; | ||
} | ||
this._newline(removeLast); | ||
}; | ||
this._newline(removeLast); | ||
}; | ||
Buffer.prototype._newline = function (removeLast) { | ||
// never allow more than two lines | ||
if (this.endsWith("\n\n")) return; | ||
Buffer.prototype._newline = function _newline(removeLast) { | ||
// never allow more than two lines | ||
if (this.endsWith("\n\n")) return; | ||
// remove the last newline | ||
if (removeLast && this.isLast("\n")) this.removeLast("\n"); | ||
// remove the last newline | ||
if (removeLast && this.isLast("\n")) this.removeLast("\n"); | ||
this.removeLast(" "); | ||
this._removeSpacesAfterLastNewline(); | ||
this._push("\n"); | ||
}; | ||
this.removeLast(" "); | ||
this._removeSpacesAfterLastNewline(); | ||
this._push("\n"); | ||
}; | ||
/** | ||
* If buffer ends with a newline and some spaces after it, trim those spaces. | ||
*/ | ||
/** | ||
* 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; | ||
Buffer.prototype._removeSpacesAfterLastNewline = function _removeSpacesAfterLastNewline() { | ||
var lastNewlineIndex = this.buf.lastIndexOf("\n"); | ||
if (lastNewlineIndex === -1) return; | ||
var index = this.buf.length - 1; | ||
while (index > lastNewlineIndex) { | ||
if (this.buf[index] !== " ") { | ||
break; | ||
var index = this.buf.length - 1; | ||
while (index > lastNewlineIndex) { | ||
if (this.buf[index] !== " ") { | ||
break; | ||
} | ||
index--; | ||
} | ||
index--; | ||
} | ||
if (index === lastNewlineIndex) { | ||
this.buf = this.buf.substring(0, index + 1); | ||
} | ||
}; | ||
if (index === lastNewlineIndex) { | ||
this.buf = this.buf.substring(0, index + 1); | ||
} | ||
}; | ||
Buffer.prototype.push = function push(str, noIndent) { | ||
if (!this.format.compact && this._indent && !noIndent && str !== "\n") { | ||
// we have an indent level and we aren't pushing a newline | ||
var indent = this.getIndent(); | ||
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); | ||
// 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); | ||
} | ||
// we've got a newline before us so prepend on the indentation | ||
if (this.isLast("\n")) this._push(indent); | ||
} | ||
this._push(str); | ||
}; | ||
this._push(str); | ||
}; | ||
Buffer.prototype._push = function _push(str) { | ||
this.position.push(str); | ||
this.buf += str; | ||
}; | ||
Buffer.prototype._push = function (str) { | ||
this.position.push(str); | ||
this.buf += str; | ||
}; | ||
Buffer.prototype.endsWith = function endsWith(str) { | ||
return this.buf.slice(-str.length) === str; | ||
}; | ||
Buffer.prototype.endsWith = function (str) { | ||
return this.buf.slice(-str.length) === str; | ||
}; | ||
Buffer.prototype.isLast = function isLast(cha) { | ||
if (this.format.compact) return false; | ||
Buffer.prototype.isLast = function (cha) { | ||
if (this.format.compact) return false; | ||
var buf = this.buf; | ||
var last = buf[buf.length - 1]; | ||
var buf = this.buf; | ||
var last = buf[buf.length - 1]; | ||
if (Array.isArray(cha)) { | ||
return includes(cha, last); | ||
} else { | ||
return cha === last; | ||
} | ||
}; | ||
if (Array.isArray(cha)) { | ||
return includes(cha, last); | ||
} else { | ||
return cha === last; | ||
} | ||
}; | ||
return Buffer; | ||
})(); | ||
module.exports = Buffer; |
"use strict"; | ||
module.exports = function (ast, opts, code) { | ||
var gen = new CodeGenerator(ast, opts, code); | ||
return gen.generate(); | ||
}; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
module.exports.CodeGenerator = CodeGenerator; | ||
var detectIndent = require("detect-indent"); | ||
@@ -22,353 +17,366 @@ var Whitespace = require("./whitespace"); | ||
function CodeGenerator(ast, opts, code) { | ||
if (!opts) opts = {}; | ||
var CodeGenerator = (function () { | ||
function CodeGenerator(ast, opts, code) { | ||
_classCallCheck(this, CodeGenerator); | ||
this.comments = ast.comments || []; | ||
this.tokens = ast.tokens || []; | ||
this.format = CodeGenerator.normalizeOptions(code, opts); | ||
this.opts = opts; | ||
this.ast = ast; | ||
if (!opts) opts = {}; | ||
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); | ||
} | ||
this.comments = ast.comments || []; | ||
this.tokens = ast.tokens || []; | ||
this.format = CodeGenerator.normalizeOptions(code, opts); | ||
this.opts = opts; | ||
this.ast = ast; | ||
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; | ||
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); | ||
} | ||
var format = { | ||
comments: opts.comments == null || opts.comments, | ||
compact: opts.compact, | ||
indent: { | ||
adjustMultilineComment: true, | ||
style: style, | ||
base: 0 | ||
CodeGenerator.normalizeOptions = function normalizeOptions(code, opts) { | ||
var style = " "; | ||
if (code) { | ||
var indent = detectIndent(code).indent; | ||
if (indent && indent !== " ") style = indent; | ||
} | ||
}; | ||
if (format.compact === "auto") { | ||
format.compact = code.length > 100000; // 100KB | ||
var format = { | ||
comments: opts.comments == null || opts.comments, | ||
compact: opts.compact, | ||
indent: { | ||
adjustMultilineComment: true, | ||
style: style, | ||
base: 0 | ||
} | ||
}; | ||
if (format.compact) { | ||
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB")); | ||
if (format.compact === "auto") { | ||
format.compact = code.length > 100000; // 100KB | ||
if (format.compact) { | ||
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB")); | ||
} | ||
} | ||
} | ||
return format; | ||
}; | ||
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") | ||
}; | ||
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 generate() { | ||
var ast = this.ast; | ||
CodeGenerator.prototype.generate = function () { | ||
var ast = this.ast; | ||
this.print(ast); | ||
this.print(ast); | ||
var comments = []; | ||
each(ast.comments, function (comment) { | ||
if (!comment._displayed) comments.push(comment); | ||
}); | ||
this._printComments(comments); | ||
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() | ||
return { | ||
map: this.map.get(), | ||
code: this.buffer.get() | ||
}; | ||
}; | ||
}; | ||
CodeGenerator.prototype.buildPrint = function (parent) { | ||
var _this = this; | ||
CodeGenerator.prototype.buildPrint = function buildPrint(parent) { | ||
var _this = this; | ||
var print = function (node, opts) { | ||
return _this.print(node, parent, opts); | ||
}; | ||
var print = function (node, opts) { | ||
return _this.print(node, parent, opts); | ||
}; | ||
print.sequence = function (nodes, opts) { | ||
if (!opts) opts = {}; | ||
print.sequence = function (nodes, opts) { | ||
if (!opts) opts = {}; | ||
opts.statement = true; | ||
return _this.printJoin(print, nodes, opts); | ||
}; | ||
opts.statement = true; | ||
return _this.printJoin(print, nodes, opts); | ||
}; | ||
print.join = function (nodes, opts) { | ||
return _this.printJoin(print, nodes, opts); | ||
}; | ||
print.join = function (nodes, opts) { | ||
return _this.printJoin(print, nodes, opts); | ||
}; | ||
print.list = function (items, opts) { | ||
if (!opts) opts = {}; | ||
var _opts = opts; | ||
if (!_opts.separator) _opts.separator = ", "; | ||
print.list = function (items, opts) { | ||
if (!opts) opts = {}; | ||
var _opts = opts; | ||
if (!_opts.separator) _opts.separator = ", "; | ||
print.join(items, opts); | ||
}; | ||
print.join(items, opts); | ||
}; | ||
print.block = function (node) { | ||
return _this.printBlock(print, node); | ||
}; | ||
print.block = function (node) { | ||
return _this.printBlock(print, node); | ||
}; | ||
print.indentOnComments = function (node) { | ||
return _this.printAndIndentOnComments(print, node); | ||
print.indentOnComments = function (node) { | ||
return _this.printAndIndentOnComments(print, node); | ||
}; | ||
return print; | ||
}; | ||
return print; | ||
}; | ||
CodeGenerator.prototype.print = function print(node, parent, opts) { | ||
var _this = this; | ||
CodeGenerator.prototype.print = function (node, parent, opts) { | ||
var _this = this; | ||
if (!node) return ""; | ||
if (!node) return ""; | ||
if (parent && parent._compact) { | ||
node._compact = true; | ||
} | ||
if (parent && parent._compact) { | ||
node._compact = true; | ||
} | ||
var oldConcise = this.format.concise; | ||
if (node._compact) { | ||
this.format.concise = true; | ||
} | ||
var oldConcise = this.format.concise; | ||
if (node._compact) { | ||
this.format.concise = true; | ||
} | ||
if (!opts) opts = {}; | ||
if (!opts) opts = {}; | ||
var newline = function (leading) { | ||
if (!opts.statement && !n.isUserWhitespacable(node, parent)) { | ||
return; | ||
} | ||
var newline = function (leading) { | ||
if (!opts.statement && !n.isUserWhitespacable(node, parent)) { | ||
return; | ||
} | ||
var lines = 0; | ||
var lines = 0; | ||
if (node.start != null && !node._ignoreUserWhitespace) { | ||
// user node | ||
if (leading) { | ||
lines = _this.whitespace.getNewlinesBefore(node); | ||
if (node.start != null && !node._ignoreUserWhitespace) { | ||
// user node | ||
if (leading) { | ||
lines = _this.whitespace.getNewlinesBefore(node); | ||
} else { | ||
lines = _this.whitespace.getNewlinesAfter(node); | ||
} | ||
} else { | ||
lines = _this.whitespace.getNewlinesAfter(node); | ||
} | ||
} else { | ||
// generated node | ||
if (!leading) lines++; // always include at least a single line after | ||
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0; | ||
// 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++; | ||
var needs = n.needsWhitespaceAfter; | ||
if (leading) needs = n.needsWhitespaceBefore; | ||
if (needs(node, parent)) lines++; | ||
// generated nodes can't add starting file whitespace | ||
if (!_this.buffer.buf) lines = 0; | ||
} | ||
// generated nodes can't add starting file whitespace | ||
if (!_this.buffer.buf) lines = 0; | ||
} | ||
_this.newline(lines); | ||
}; | ||
_this.newline(lines); | ||
}; | ||
if (this[node.type]) { | ||
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent); | ||
var needsParens = needsNoLineTermParens || n.needsParens(node, parent); | ||
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(); | ||
if (needsParens) this.push("("); | ||
if (needsNoLineTermParens) this.indent(); | ||
this.printLeadingComments(node, parent); | ||
this.printLeadingComments(node, parent); | ||
newline(true); | ||
newline(true); | ||
if (opts.before) opts.before(); | ||
this.map.mark(node, "start"); | ||
if (opts.before) opts.before(); | ||
this.map.mark(node, "start"); | ||
this[node.type](node, this.buildPrint(node), parent); | ||
this[node.type](node, this.buildPrint(node), parent); | ||
if (needsNoLineTermParens) { | ||
this.newline(); | ||
this.dedent(); | ||
} | ||
if (needsParens) this.push(")"); | ||
if (needsNoLineTermParens) { | ||
this.newline(); | ||
this.dedent(); | ||
} | ||
if (needsParens) this.push(")"); | ||
this.map.mark(node, "end"); | ||
if (opts.after) opts.after(); | ||
this.map.mark(node, "end"); | ||
if (opts.after) opts.after(); | ||
newline(false); | ||
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.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; | ||
}; | ||
this.format.concise = oldConcise; | ||
}; | ||
CodeGenerator.prototype.printJoin = function (print, nodes, opts) { | ||
var _this = this; | ||
CodeGenerator.prototype.printJoin = function printJoin(print, nodes, opts) { | ||
var _this = this; | ||
if (!nodes || !nodes.length) return; | ||
if (!nodes || !nodes.length) return; | ||
if (!opts) opts = {}; | ||
if (!opts) opts = {}; | ||
var len = nodes.length; | ||
var len = nodes.length; | ||
if (opts.indent) this.indent(); | ||
if (opts.indent) this.indent(); | ||
each(nodes, function (node, i) { | ||
print(node, { | ||
statement: opts.statement, | ||
addNewlines: opts.addNewlines, | ||
after: function () { | ||
if (opts.iterator) { | ||
opts.iterator(node, i); | ||
} | ||
each(nodes, function (node, i) { | ||
print(node, { | ||
statement: opts.statement, | ||
addNewlines: opts.addNewlines, | ||
after: function () { | ||
if (opts.iterator) { | ||
opts.iterator(node, i); | ||
} | ||
if (opts.separator && i < len - 1) { | ||
_this.push(opts.separator); | ||
if (opts.separator && i < len - 1) { | ||
_this.push(opts.separator); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
if (opts.indent) this.dedent(); | ||
}; | ||
if (opts.indent) this.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(" "); | ||
CodeGenerator.prototype.printAndIndentOnComments = function printAndIndentOnComments(print, node) { | ||
var indent = !!node.leadingComments; | ||
if (indent) this.indent(); | ||
print(node); | ||
} | ||
}; | ||
if (indent) this.dedent(); | ||
}; | ||
CodeGenerator.prototype.generateComment = function (comment) { | ||
var val = comment.value; | ||
if (comment.type === "Line") { | ||
val = "//" + val; | ||
} else { | ||
val = "/*" + val + "*/"; | ||
} | ||
return val; | ||
}; | ||
CodeGenerator.prototype.printBlock = function printBlock(print, node) { | ||
if (t.isEmptyStatement(node)) { | ||
this.semicolon(); | ||
} else { | ||
this.push(" "); | ||
print(node); | ||
} | ||
}; | ||
CodeGenerator.prototype.printTrailingComments = function (node, parent) { | ||
this._printComments(this.getComments("trailingComments", node, parent)); | ||
}; | ||
CodeGenerator.prototype.generateComment = function generateComment(comment) { | ||
var val = comment.value; | ||
if (comment.type === "Line") { | ||
val = "//" + val; | ||
} else { | ||
val = "/*" + val + "*/"; | ||
} | ||
return val; | ||
}; | ||
CodeGenerator.prototype.printLeadingComments = function (node, parent) { | ||
this._printComments(this.getComments("leadingComments", node, parent)); | ||
}; | ||
CodeGenerator.prototype.printTrailingComments = function printTrailingComments(node, parent) { | ||
this._printComments(this.getComments("trailingComments", node, parent)); | ||
}; | ||
CodeGenerator.prototype.getComments = function (key, node, parent) { | ||
var _this = this; | ||
CodeGenerator.prototype.printLeadingComments = function printLeadingComments(node, parent) { | ||
this._printComments(this.getComments("leadingComments", node, parent)); | ||
}; | ||
if (t.isExpressionStatement(parent)) { | ||
return []; | ||
} | ||
CodeGenerator.prototype.getComments = function getComments(key, node, parent) { | ||
var _this = this; | ||
var comments = []; | ||
var nodes = [node]; | ||
if (t.isExpressionStatement(parent)) { | ||
return []; | ||
} | ||
if (t.isExpressionStatement(node)) { | ||
nodes.push(node.argument); | ||
} | ||
var comments = []; | ||
var nodes = [node]; | ||
each(nodes, function (node) { | ||
comments = comments.concat(_this._getComments(key, node)); | ||
}); | ||
if (t.isExpressionStatement(node)) { | ||
nodes.push(node.argument); | ||
} | ||
return comments; | ||
}; | ||
each(nodes, function (node) { | ||
comments = comments.concat(_this._getComments(key, node)); | ||
}); | ||
CodeGenerator.prototype._getComments = function (key, node) { | ||
return node && node[key] || []; | ||
}; | ||
return comments; | ||
}; | ||
CodeGenerator.prototype._printComments = function (comments) { | ||
var _this = this; | ||
CodeGenerator.prototype._getComments = function _getComments(key, node) { | ||
return node && node[key] || []; | ||
}; | ||
if (this.format.compact) return; | ||
CodeGenerator.prototype._printComments = function _printComments(comments) { | ||
var _this = this; | ||
if (!this.format.comments) return; | ||
if (!comments || !comments.length) return; | ||
if (this.format.compact) return; | ||
each(comments, function (comment) { | ||
var skip = false; | ||
if (!this.format.comments) return; | ||
if (!comments || !comments.length) return; | ||
// find the original comment in the ast and set it as displayed | ||
each(_this.ast.comments, function (origComment) { | ||
if (origComment.start === comment.start) { | ||
// comment has already been output | ||
if (origComment._displayed) skip = true; | ||
each(comments, function (comment) { | ||
var skip = false; | ||
origComment._displayed = true; | ||
return false; | ||
} | ||
}); | ||
// find the original comment in the ast and set it as displayed | ||
each(_this.ast.comments, function (origComment) { | ||
if (origComment.start === comment.start) { | ||
// comment has already been output | ||
if (origComment._displayed) skip = true; | ||
if (skip) return; | ||
origComment._displayed = true; | ||
return false; | ||
} | ||
}); | ||
// whitespace before | ||
_this.newline(_this.whitespace.getNewlinesBefore(comment)); | ||
if (skip) return; | ||
var column = _this.position.column; | ||
var val = _this.generateComment(comment); | ||
// whitespace before | ||
_this.newline(_this.whitespace.getNewlinesBefore(comment)); | ||
if (column && !_this.isLast(["\n", " ", "[", "{"])) { | ||
_this._push(" "); | ||
column++; | ||
} | ||
var column = _this.position.column; | ||
var val = _this.generateComment(comment); | ||
// | ||
if (column && !_this.isLast(["\n", " ", "[", "{"])) { | ||
_this._push(" "); | ||
column++; | ||
} | ||
if (comment.type === "Block" && _this.format.indent.adjustMultilineComment) { | ||
var offset = comment.loc.start.column; | ||
if (offset) { | ||
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g"); | ||
val = val.replace(newlineRegex, "\n"); | ||
// | ||
if (comment.type === "Block" && _this.format.indent.adjustMultilineComment) { | ||
var offset = comment.loc.start.column; | ||
if (offset) { | ||
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g"); | ||
val = val.replace(newlineRegex, "\n"); | ||
} | ||
var indent = Math.max(_this.indentSize(), column); | ||
val = val.replace(/\n/g, "\n" + repeating(" ", indent)); | ||
} | ||
var indent = Math.max(_this.indentSize(), column); | ||
val = val.replace(/\n/g, "\n" + repeating(" ", indent)); | ||
} | ||
if (column === 0) { | ||
val = _this.getIndent() + val; | ||
} | ||
if (column === 0) { | ||
val = _this.getIndent() + val; | ||
} | ||
// | ||
// | ||
_this._push(val); | ||
_this._push(val); | ||
// whitespace after | ||
_this.newline(_this.whitespace.getNewlinesAfter(comment)); | ||
}); | ||
}; | ||
// whitespace after | ||
_this.newline(_this.whitespace.getNewlinesAfter(comment)); | ||
}); | ||
}; | ||
return CodeGenerator; | ||
})(); | ||
each(Buffer.prototype, function (fn, key) { | ||
CodeGenerator.prototype[key] = function () { | ||
return fn.apply(this.buffer, arguments); | ||
}; | ||
}); | ||
each(CodeGenerator.generators, function (generator) { | ||
extend(CodeGenerator.prototype, generator); | ||
}); | ||
module.exports = function (ast, opts, code) { | ||
var gen = new CodeGenerator(ast, opts, code); | ||
return gen.generate(); | ||
}; | ||
module.exports.CodeGenerator = CodeGenerator; |
"use strict"; | ||
module.exports = Node; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -29,75 +29,83 @@ var whitespace = require("./whitespace"); | ||
function Node(node, parent) { | ||
this.parent = parent; | ||
this.node = node; | ||
} | ||
var Node = (function () { | ||
function Node(node, parent) { | ||
_classCallCheck(this, Node); | ||
Node.isUserWhitespacable = function (node) { | ||
return t.isUserWhitespacable(node); | ||
}; | ||
this.parent = parent; | ||
this.node = node; | ||
} | ||
Node.needsWhitespace = function (node, parent, type) { | ||
if (!node) return 0; | ||
Node.isUserWhitespacable = function isUserWhitespacable(node) { | ||
return t.isUserWhitespacable(node); | ||
}; | ||
if (t.isExpressionStatement(node)) { | ||
node = node.expression; | ||
} | ||
Node.needsWhitespace = function needsWhitespace(node, parent, type) { | ||
if (!node) return 0; | ||
var linesInfo = find(whitespace.nodes, node, parent); | ||
if (t.isExpressionStatement(node)) { | ||
node = node.expression; | ||
} | ||
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; | ||
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; | ||
}; | ||
return linesInfo && linesInfo[type] || 0; | ||
}; | ||
Node.needsWhitespaceBefore = function (node, parent) { | ||
return Node.needsWhitespace(node, parent, "before"); | ||
}; | ||
Node.needsWhitespaceBefore = function needsWhitespaceBefore(node, parent) { | ||
return Node.needsWhitespace(node, parent, "before"); | ||
}; | ||
Node.needsWhitespaceAfter = function (node, parent) { | ||
return Node.needsWhitespace(node, parent, "after"); | ||
}; | ||
Node.needsWhitespaceAfter = function needsWhitespaceAfter(node, parent) { | ||
return Node.needsWhitespace(node, parent, "after"); | ||
}; | ||
Node.needsParens = function (node, parent) { | ||
if (!parent) return false; | ||
Node.needsParens = function needsParens(node, parent) { | ||
if (!parent) return false; | ||
if (t.isNewExpression(parent) && parent.callee === node) { | ||
if (t.isCallExpression(node)) return true; | ||
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; | ||
} | ||
var hasCall = some(node, function (val) { | ||
return t.isCallExpression(val); | ||
}); | ||
if (hasCall) return true; | ||
} | ||
return find(parens, node, parent); | ||
}; | ||
return find(parens, node, parent); | ||
}; | ||
Node.needsParensNoLineTerminator = function (node, parent) { | ||
if (!parent) return false; | ||
Node.needsParensNoLineTerminator = function needsParensNoLineTerminator(node, parent) { | ||
if (!parent) return false; | ||
// no comments | ||
if (!node.leadingComments || !node.leadingComments.length) { | ||
// 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; | ||
} | ||
}; | ||
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) { | ||
return true; | ||
} | ||
return Node; | ||
})(); | ||
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) || t.isReturnStatement(parent) || t.isThrowStatement(parent)) { | ||
return true; | ||
} | ||
module.exports = Node; | ||
return false; | ||
}; | ||
each(Node, function (fn, key) { | ||
@@ -104,0 +112,0 @@ Node.prototype[key] = function () { |
"use strict"; | ||
module.exports = Position; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
function Position() { | ||
this.line = 1; | ||
this.column = 0; | ||
} | ||
var Position = (function () { | ||
function Position() { | ||
_classCallCheck(this, Position); | ||
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++; | ||
} | ||
this.line = 1; | ||
this.column = 0; | ||
} | ||
}; | ||
Position.prototype.unshift = function (str) { | ||
for (var i = 0; i < str.length; i++) { | ||
if (str[i] === "\n") { | ||
this.line--; | ||
} else { | ||
this.column--; | ||
Position.prototype.push = function push(str) { | ||
for (var i = 0; i < str.length; i++) { | ||
if (str[i] === "\n") { | ||
this.line++; | ||
this.column = 0; | ||
} else { | ||
this.column++; | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
Position.prototype.unshift = function unshift(str) { | ||
for (var i = 0; i < str.length; i++) { | ||
if (str[i] === "\n") { | ||
this.line--; | ||
} else { | ||
this.column--; | ||
} | ||
} | ||
}; | ||
return Position; | ||
})(); | ||
module.exports = Position; |
"use strict"; | ||
module.exports = SourceMap; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -8,50 +8,58 @@ var sourceMap = require("source-map"); | ||
function SourceMap(position, opts, code) { | ||
this.position = position; | ||
this.opts = opts; | ||
var SourceMap = (function () { | ||
function SourceMap(position, opts, code) { | ||
_classCallCheck(this, SourceMap); | ||
if (opts.sourceMap) { | ||
this.map = new sourceMap.SourceMapGenerator({ | ||
file: opts.sourceMapName, | ||
sourceRoot: opts.sourceRoot | ||
}); | ||
this.position = position; | ||
this.opts = opts; | ||
this.map.setSourceContent(opts.sourceFileName, code); | ||
} else { | ||
this.map = null; | ||
} | ||
} | ||
if (opts.sourceMap) { | ||
this.map = new sourceMap.SourceMapGenerator({ | ||
file: opts.sourceMapName, | ||
sourceRoot: opts.sourceRoot | ||
}); | ||
SourceMap.prototype.get = function () { | ||
var map = this.map; | ||
if (map) { | ||
return map.toJSON(); | ||
} else { | ||
return map; | ||
this.map.setSourceContent(opts.sourceFileName, code); | ||
} else { | ||
this.map = null; | ||
} | ||
} | ||
}; | ||
SourceMap.prototype.mark = function (node, type) { | ||
var loc = node.loc; | ||
if (!loc) return; // no location info | ||
SourceMap.prototype.get = function get() { | ||
var map = this.map; | ||
if (map) { | ||
return map.toJSON(); | ||
} else { | ||
return map; | ||
} | ||
}; | ||
var map = this.map; | ||
if (!map) return; // no source map | ||
SourceMap.prototype.mark = function mark(node, type) { | ||
var loc = node.loc; | ||
if (!loc) return; // no location info | ||
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes | ||
var map = this.map; | ||
if (!map) return; // no source map | ||
var position = this.position; | ||
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes | ||
var generated = { | ||
line: position.line, | ||
column: position.column | ||
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 | ||
}); | ||
}; | ||
var original = loc[type]; | ||
return SourceMap; | ||
})(); | ||
map.addMapping({ | ||
source: this.opts.sourceFileName, | ||
generated: generated, | ||
original: original | ||
}); | ||
}; | ||
module.exports = SourceMap; |
"use strict"; | ||
module.exports = Whitespace; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -27,90 +27,98 @@ var sortBy = require("lodash/collection/sortBy"); | ||
function Whitespace(tokens, comments) { | ||
this.tokens = sortBy(tokens.concat(comments), "start"); | ||
this.used = {}; | ||
var Whitespace = (function () { | ||
function Whitespace(tokens, comments) { | ||
_classCallCheck(this, Whitespace); | ||
// Profiling this code shows that while generator passes over it, indexes | ||
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing. | ||
this.tokens = sortBy(tokens.concat(comments), "start"); | ||
this.used = {}; | ||
// 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. | ||
// Profiling this code shows that while generator passes over it, indexes | ||
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing. | ||
this._lastFoundIndex = 0; | ||
} | ||
// 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. | ||
Whitespace.prototype.getNewlinesBefore = function (node) { | ||
var startToken; | ||
var endToken; | ||
var tokens = this.tokens; | ||
var token; | ||
this._lastFoundIndex = 0; | ||
} | ||
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]; | ||
Whitespace.prototype.getNewlinesBefore = function getNewlinesBefore(node) { | ||
var startToken; | ||
var endToken; | ||
var tokens = this.tokens; | ||
var token; | ||
// this is the token this node starts with | ||
if (node.start === token.start) { | ||
startToken = tokens[i - 1]; | ||
endToken = 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._lastFoundIndex = i; | ||
break; | ||
// 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); | ||
}; | ||
return this.getNewlinesBetween(startToken, endToken); | ||
}; | ||
Whitespace.prototype.getNewlinesAfter = function (node) { | ||
var startToken; | ||
var endToken; | ||
var tokens = this.tokens; | ||
var token; | ||
Whitespace.prototype.getNewlinesAfter = function getNewlinesAfter(node) { | ||
var startToken; | ||
var endToken; | ||
var tokens = this.tokens; | ||
var token; | ||
for (var j = 0; j < tokens.length; j++) { | ||
// optimize for forward traversal by shifting for loop index | ||
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length); | ||
token = tokens[i]; | ||
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 is the token this node ends with | ||
if (node.end === token.end) { | ||
startToken = token; | ||
endToken = tokens[i + 1]; | ||
this._lastFoundIndex = i; | ||
break; | ||
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 | ||
if (endToken && endToken.type.type === "eof") { | ||
return 1; | ||
} else { | ||
return lines; | ||
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; | ||
Whitespace.prototype.getNewlinesBetween = function getNewlinesBetween(startToken, endToken) { | ||
if (!endToken || !endToken.loc) return 0; | ||
var start = startToken ? startToken.loc.end.line : 1; | ||
var end = endToken.loc.start.line; | ||
var lines = 0; | ||
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++; | ||
for (var line = start; line < end; line++) { | ||
if (typeof this.used[line] === "undefined") { | ||
this.used[line] = true; | ||
lines++; | ||
} | ||
} | ||
} | ||
return lines; | ||
}; | ||
return lines; | ||
}; | ||
return Whitespace; | ||
})(); | ||
module.exports = Whitespace; |
"use strict"; | ||
module.exports = File; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -21,408 +21,445 @@ var sourceMapToComment = require("source-map-to-comment"); | ||
function File(opts) { | ||
this.dynamicImportedNoDefault = []; | ||
this.dynamicImportIds = {}; | ||
this.dynamicImported = []; | ||
this.dynamicImports = []; | ||
var checkTransformerVisitor = { | ||
enter: function enter(node, parent, scope, state) { | ||
checkNode(state.stack, node, scope); | ||
} | ||
}; | ||
this.usedHelpers = {}; | ||
this.dynamicData = {}; | ||
this.data = {}; | ||
var checkNode = function checkNode(stack, node, scope) { | ||
each(stack, function (pass) { | ||
if (pass.shouldRun) return; | ||
pass.checkNode(node, scope); | ||
}); | ||
}; | ||
this.lastStatements = []; | ||
this.opts = this.normalizeOptions(opts); | ||
this.ast = {}; | ||
var File = (function () { | ||
function File(opts) { | ||
_classCallCheck(this, File); | ||
this.buildTransformers(); | ||
} | ||
this.dynamicImportedNoDefault = []; | ||
this.dynamicImportIds = {}; | ||
this.dynamicImported = []; | ||
this.dynamicImports = []; | ||
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"]; | ||
this.usedHelpers = {}; | ||
this.dynamicData = {}; | ||
this.data = {}; | ||
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", "returnUsedHelpers", "resolveModuleSource", "moduleId", | ||
this.lastStatements = []; | ||
this.opts = this.normalizeOptions(opts); | ||
this.ast = {}; | ||
// legacy | ||
"format", | ||
this.buildTransformers(); | ||
} | ||
// these are used by plugins | ||
"ignore", "only", "extensions", "accept"]; | ||
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", "returnUsedHelpers", "resolveModuleSource", "moduleId", | ||
File.prototype.normalizeOptions = function (opts) { | ||
opts = assign({}, opts); | ||
// legacy | ||
"format", | ||
for (var key in opts) { | ||
if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) { | ||
throw new ReferenceError("Unknown option: " + key); | ||
// these are used by plugins | ||
"ignore", "only", "extensions", "accept"]; | ||
File.prototype.normalizeOptions = function normalizeOptions(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, | ||
returnUsedHelpers: false, | ||
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 | ||
}); | ||
defaults(opts, { | ||
keepModuleIdExtensions: false, | ||
resolveModuleSource: null, | ||
returnUsedHelpers: false, | ||
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); | ||
} | ||
// 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; | ||
} | ||
if (opts.moduleId) { | ||
opts.moduleIds = true; | ||
} | ||
opts.basename = path.basename(opts.filename, path.extname(opts.filename)); | ||
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); | ||
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); | ||
} | ||
if (includes(opts.loose, "all") || includes(opts.loose, true)) { | ||
opts.loose = Object.keys(transform.transformers); | ||
} | ||
defaults(opts, { | ||
moduleRoot: opts.sourceRoot | ||
}); | ||
defaults(opts, { | ||
moduleRoot: opts.sourceRoot | ||
}); | ||
defaults(opts, { | ||
sourceRoot: opts.moduleRoot | ||
}); | ||
defaults(opts, { | ||
sourceRoot: opts.moduleRoot | ||
}); | ||
defaults(opts, { | ||
filenameRelative: opts.filename | ||
}); | ||
defaults(opts, { | ||
filenameRelative: opts.filename | ||
}); | ||
defaults(opts, { | ||
sourceFileName: opts.filenameRelative, | ||
sourceMapName: opts.filenameRelative | ||
}); | ||
defaults(opts, { | ||
sourceFileName: opts.filenameRelative, | ||
sourceMapName: opts.filenameRelative | ||
}); | ||
if (opts.playground) { | ||
opts.experimental = true; | ||
} | ||
if (opts.playground) { | ||
opts.experimental = true; | ||
} | ||
if (opts.externalHelpers) { | ||
this.set("helpersNamespace", t.identifier("babelHelpers")); | ||
} | ||
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); | ||
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`"); | ||
} | ||
if (opts.reactCompat) { | ||
opts.optional.push("reactCompat"); | ||
console.error("The reactCompat option has been moved into the optional transformer `reactCompat`"); | ||
} | ||
var ensureEnabled = function ensureEnabled(key) { | ||
var namespace = transform.transformerNamespaces[key]; | ||
if (namespace === "es7") opts.experimental = true; | ||
if (namespace === "playground") opts.playground = true; | ||
}; | ||
var ensureEnabled = function ensureEnabled(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); | ||
each(opts.whitelist, ensureEnabled); | ||
each(opts.optional, ensureEnabled); | ||
return opts; | ||
}; | ||
return opts; | ||
}; | ||
File.prototype.isLoose = function (key) { | ||
return includes(this.opts.loose, key); | ||
}; | ||
File.prototype.isLoose = function isLoose(key) { | ||
return includes(this.opts.loose, key); | ||
}; | ||
File.prototype.buildTransformers = function () { | ||
var file = this; | ||
File.prototype.buildTransformers = function buildTransformers() { | ||
var file = this; | ||
var transformers = {}; | ||
var transformers = {}; | ||
var secondaryStack = []; | ||
var stack = []; | ||
var secondaryStack = []; | ||
var stack = []; | ||
each(transform.transformers, function (transformer, key) { | ||
var pass = transformers[key] = transformer.buildPass(file); | ||
each(transform.transformers, function (transformer, key) { | ||
var pass = transformers[key] = transformer.buildPass(file); | ||
if (pass.canRun(file)) { | ||
stack.push(pass); | ||
if (pass.canRun(file)) { | ||
stack.push(pass); | ||
if (transformer.secondPass) { | ||
secondaryStack.push(pass); | ||
} | ||
if (transformer.secondPass) { | ||
secondaryStack.push(pass); | ||
} | ||
if (transformer.manipulateOptions) { | ||
transformer.manipulateOptions(file.opts, file); | ||
if (transformer.manipulateOptions) { | ||
transformer.manipulateOptions(file.opts, file); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
this.transformerStack = stack.concat(secondaryStack); | ||
this.transformers = transformers; | ||
}; | ||
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.debug = function debug(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]; | ||
File.prototype.getModuleFormatter = function getModuleFormatter(type) { | ||
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type]; | ||
if (!ModuleFormatter) { | ||
var loc = util.resolve(type); | ||
if (loc) ModuleFormatter = require(loc); | ||
} | ||
if (!ModuleFormatter) { | ||
var loc = util.resolve(type); | ||
if (loc) ModuleFormatter = require(loc); | ||
} | ||
if (!ModuleFormatter) { | ||
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type)); | ||
} | ||
if (!ModuleFormatter) { | ||
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type)); | ||
} | ||
return new ModuleFormatter(this); | ||
}; | ||
return new ModuleFormatter(this); | ||
}; | ||
File.prototype.parseShebang = function (code) { | ||
var shebangMatch = shebangRegex.exec(code); | ||
File.prototype.parseShebang = function parseShebang(code) { | ||
var shebangMatch = shebangRegex.exec(code); | ||
if (shebangMatch) { | ||
this.shebang = shebangMatch[0]; | ||
if (shebangMatch) { | ||
this.shebang = shebangMatch[0]; | ||
// remove shebang | ||
code = code.replace(shebangRegex, ""); | ||
} | ||
// remove shebang | ||
code = code.replace(shebangRegex, ""); | ||
} | ||
return code; | ||
}; | ||
return code; | ||
}; | ||
File.prototype.set = function (key, val) { | ||
return this.data[key] = val; | ||
}; | ||
File.prototype.set = function set(key, val) { | ||
return this.data[key] = val; | ||
}; | ||
File.prototype.setDynamic = function (key, fn) { | ||
this.dynamicData[key] = fn; | ||
}; | ||
File.prototype.setDynamic = function setDynamic(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.get = function get(key) { | ||
var data = this.data[key]; | ||
if (data) { | ||
return data; | ||
} else { | ||
var dynamic = this.dynamicData[key]; | ||
if (dynamic) { | ||
return this.set(key, dynamic()); | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
File.prototype.addImport = function (source, name, noDefault) { | ||
if (!name) name = source; | ||
File.prototype.addImport = function addImport(source, name, noDefault) { | ||
if (!name) name = source; | ||
var id = this.dynamicImportIds[name]; | ||
var id = this.dynamicImportIds[name]; | ||
if (!id) { | ||
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(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; | ||
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.dynamicImported.push(declar); | ||
if (noDefault) this.dynamicImportedNoDefault.push(declar); | ||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports); | ||
} | ||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports); | ||
} | ||
return id; | ||
}; | ||
return id; | ||
}; | ||
File.prototype.isConsequenceExpressionStatement = function (node) { | ||
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0; | ||
}; | ||
File.prototype.isConsequenceExpressionStatement = function isConsequenceExpressionStatement(node) { | ||
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0; | ||
}; | ||
File.prototype.attachAuxiliaryComment = function (node) { | ||
var comment = this.opts.auxiliaryComment; | ||
if (comment) { | ||
var _node = node; | ||
if (!_node.leadingComments) _node.leadingComments = []; | ||
File.prototype.attachAuxiliaryComment = function attachAuxiliaryComment(node) { | ||
var comment = this.opts.auxiliaryComment; | ||
if (comment) { | ||
var _node = node; | ||
if (!_node.leadingComments) _node.leadingComments = []; | ||
node.leadingComments.push({ | ||
type: "Line", | ||
value: " " + comment | ||
}); | ||
} | ||
return node; | ||
}; | ||
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); | ||
} | ||
File.prototype.addHelper = function addHelper(name) { | ||
if (!includes(File.helpers, name)) { | ||
throw new ReferenceError("Unknown helper " + name); | ||
} | ||
var program = this.ast.program; | ||
var program = this.ast.program; | ||
var declar = program._declarations && program._declarations[name]; | ||
if (declar) return declar.id; | ||
var declar = program._declarations && program._declarations[name]; | ||
if (declar) return declar.id; | ||
this.usedHelpers[name] = true; | ||
this.usedHelpers[name] = true; | ||
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; | ||
} | ||
}; | ||
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 () {}; | ||
File.prototype.logDeopt = function logDeopt() {}; | ||
File.prototype.errorWithNode = function (node, msg, Error) { | ||
if (!Error) Error = SyntaxError; | ||
File.prototype.errorWithNode = function errorWithNode(node, msg, Error) { | ||
if (!Error) Error = SyntaxError; | ||
var loc = node.loc.start; | ||
var err = new Error("Line " + loc.line + ": " + msg); | ||
err.loc = loc; | ||
return err; | ||
}; | ||
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.addCode = function addCode(code) { | ||
code = (code || "") + ""; | ||
this.code = code; | ||
return this.parseShebang(code); | ||
}; | ||
File.prototype.parse = function (code) { | ||
var _this = this; | ||
File.prototype.parse = (function (_parse) { | ||
var _parseWrapper = function parse() { | ||
return _parse.apply(this, arguments); | ||
}; | ||
code = this.addCode(code); | ||
_parseWrapper.toString = function () { | ||
return _parse.toString(); | ||
}; | ||
var opts = this.opts; | ||
return _parseWrapper; | ||
})(function (code) { | ||
var _this = this; | ||
opts.allowImportExportEverywhere = this.isLoose("es6.modules"); | ||
opts.strictMode = this.transformers.useStrict.canRun(); | ||
code = this.addCode(code); | ||
return parse(opts, code, function (tree) { | ||
_this.transform(tree); | ||
return _this.generate(); | ||
var opts = this.opts; | ||
opts.allowImportExportEverywhere = this.isLoose("es6.modules"); | ||
opts.strictMode = this.transformers.useStrict.canRun(); | ||
return parse(opts, code, function (tree) { | ||
_this.transform(tree); | ||
return _this.generate(); | ||
}); | ||
}); | ||
}; | ||
File.prototype.transform = function (ast) { | ||
this.debug(); | ||
File.prototype.transform = function transform(ast) { | ||
this.debug(); | ||
this.ast = ast; | ||
this.lastStatements = t.getLastStatements(ast.program); | ||
this.scope = new Scope(ast.program, ast, null, this); | ||
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(); | ||
} | ||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules); | ||
if (modFormatter.init && this.transformers["es6.modules"].canRun()) { | ||
modFormatter.init(); | ||
} | ||
this.checkNode(ast); | ||
this.checkNode(ast); | ||
this.call("pre"); | ||
this.call("pre"); | ||
each(this.transformerStack, function (pass) { | ||
pass.transform(); | ||
}); | ||
each(this.transformerStack, function (pass) { | ||
pass.transform(); | ||
}); | ||
this.call("post"); | ||
}; | ||
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); | ||
File.prototype.call = function call(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 enter(node, parent, scope, state) { | ||
checkNode(state.stack, node, scope); | ||
} | ||
}; | ||
File.prototype.checkNode = (function (_checkNode) { | ||
var _checkNodeWrapper = function checkNode() { | ||
return _checkNode.apply(this, arguments); | ||
}; | ||
var checkNode = function checkNode(stack, node, scope) { | ||
each(stack, function (pass) { | ||
if (pass.shouldRun) return; | ||
pass.checkNode(node, scope); | ||
}); | ||
}; | ||
_checkNodeWrapper.toString = function () { | ||
return _checkNode.toString(); | ||
}; | ||
File.prototype.checkNode = function (node, scope) { | ||
var stack = this.transformerStack; | ||
if (!scope) scope = this.scope; | ||
return _checkNodeWrapper; | ||
})(function (node, scope) { | ||
var stack = this.transformerStack; | ||
if (!scope) scope = this.scope; | ||
checkNode(stack, node, scope); | ||
checkNode(stack, node, scope); | ||
scope.traverse(node, checkTransformerVisitor, { | ||
stack: stack | ||
scope.traverse(node, checkTransformerVisitor, { | ||
stack: stack | ||
}); | ||
}); | ||
}; | ||
File.prototype.generate = function () { | ||
var opts = this.opts; | ||
var ast = this.ast; | ||
File.prototype.generate = (function (_generate) { | ||
var _generateWrapper = function generate() { | ||
return _generate.apply(this, arguments); | ||
}; | ||
var result = { | ||
code: "", | ||
map: null, | ||
ast: null | ||
}; | ||
_generateWrapper.toString = function () { | ||
return _generate.toString(); | ||
}; | ||
if (this.opts.returnUsedHelpers) { | ||
result.usedHelpers = Object.keys(this.usedHelpers); | ||
} | ||
return _generateWrapper; | ||
})(function () { | ||
var opts = this.opts; | ||
var ast = this.ast; | ||
if (opts.ast) result.ast = ast; | ||
if (!opts.code) return result; | ||
var result = { | ||
code: "", | ||
map: null, | ||
ast: null | ||
}; | ||
var _result = generate(ast, opts, this.code); | ||
result.code = _result.code; | ||
result.map = _result.map; | ||
if (this.opts.returnUsedHelpers) { | ||
result.usedHelpers = Object.keys(this.usedHelpers); | ||
} | ||
if (this.shebang) { | ||
// add back shebang | ||
result.code = this.shebang + "\n" + result.code; | ||
} | ||
if (opts.ast) result.ast = ast; | ||
if (!opts.code) return result; | ||
if (opts.sourceMap === "inline") { | ||
result.code += "\n" + sourceMapToComment(result.map); | ||
result.map = null; | ||
} | ||
var _result = generate(ast, opts, this.code); | ||
result.code = _result.code; | ||
result.map = _result.map; | ||
return result; | ||
}; | ||
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; | ||
}); | ||
return File; | ||
})(); | ||
module.exports = File; | ||
// todo, (node, msg) |
"use strict"; | ||
var _toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
module.exports = ReplaceSupers; | ||
@@ -8,67 +12,13 @@ | ||
/** | ||
* 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]); | ||
var isIllegalBareSuper = function isIllegalBareSuper(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; | ||
}; | ||
/** | ||
* 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]); | ||
var isSuper = function isSuper(node, parent) { | ||
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent); | ||
}; | ||
/** | ||
* Description | ||
*/ | ||
ReplaceSupers.prototype.replace = function () { | ||
this.traverseLevel(this.methodNode.value, true); | ||
}; | ||
var visitor = { | ||
@@ -102,171 +52,234 @@ enter: function enter(node, parent, scope, state) { | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Boolean} topLevel | ||
*/ | ||
var ReplaceSupers = (function () { | ||
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) { | ||
var state = { self: this, topLevel: topLevel }; | ||
this.scope.traverse(node, visitor, state); | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {Object} opts | ||
* @param {Boolean} [inClass] | ||
*/ | ||
/** | ||
* Description | ||
*/ | ||
function ReplaceSupers(opts, inClass) { | ||
_classCallCheck(this, ReplaceSupers); | ||
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; | ||
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; | ||
} | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Object} id | ||
* @param {Object} parent | ||
* @returns {Object} | ||
*/ | ||
/** | ||
* 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.getLooseSuperProperty = function (id, parent) { | ||
var methodNode = this.methodNode; | ||
var methodName = methodNode.key; | ||
var superName = this.superName || t.identifier("Function"); | ||
ReplaceSupers.prototype.setSuperProperty = function setSuperProperty(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]); | ||
}; | ||
if (parent.property === id) { | ||
return; | ||
} else if (t.isCallExpression(parent, { callee: id })) { | ||
// super(); -> ClassName.prototype.MethodName.call(this); | ||
parent.arguments.unshift(t.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} | ||
*/ | ||
if (methodName.name === "constructor") { | ||
// constructor() { super(); } | ||
return t.memberExpression(superName, t.identifier("call")); | ||
ReplaceSupers.prototype.getSuperProperty = function getSuperProperty(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 replace() { | ||
this.traverseLevel(this.methodNode.value, true); | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Boolean} topLevel | ||
*/ | ||
ReplaceSupers.prototype.traverseLevel = function traverseLevel(node, topLevel) { | ||
var state = { self: this, topLevel: topLevel }; | ||
this.scope.traverse(node, visitor, state); | ||
}; | ||
/** | ||
* Description | ||
*/ | ||
ReplaceSupers.prototype.getThisReference = function getThisReference() { | ||
if (this.topLevelThisReference) { | ||
return this.topLevelThisReference; | ||
} else { | ||
id = superName; | ||
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; | ||
} | ||
}; | ||
// foo() { super(); } | ||
if (!methodNode["static"]) { | ||
id = t.memberExpression(id, t.identifier("prototype")); | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Object} id | ||
* @param {Object} parent | ||
* @returns {Object} | ||
*/ | ||
ReplaceSupers.prototype.getLooseSuperProperty = function getLooseSuperProperty(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")); | ||
} | ||
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; | ||
} | ||
} 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 | ||
*/ | ||
/** | ||
* 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; | ||
ReplaceSupers.prototype.looseHandle = function looseHandle(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()); | ||
} | ||
}; | ||
// 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 | ||
*/ | ||
/** | ||
* 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; | ||
ReplaceSupers.prototype.specHandle = function specHandle(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 (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; | ||
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)); | ||
// 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(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()); | ||
} | ||
} 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; | ||
if (!property) return; | ||
this.hasSuper = true; | ||
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]); | ||
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(_toConsumableArray(args))); | ||
} | ||
} else { | ||
return t.callExpression(t.memberExpression(superProperty, t.identifier("call")), [thisReference].concat(args)); | ||
return superProperty; | ||
} | ||
} else { | ||
return superProperty; | ||
} | ||
}; | ||
}; | ||
var isIllegalBareSuper = function isIllegalBareSuper(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; | ||
}; | ||
return ReplaceSupers; | ||
})(); | ||
var isSuper = function isSuper(node, parent) { | ||
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent); | ||
}; | ||
module.exports = ReplaceSupers; |
"use strict"; | ||
module.exports = DefaultFormatter; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -11,75 +11,2 @@ var messages = require("../../messages"); | ||
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; | ||
var _occurs = occurs; | ||
var _source = source; | ||
if (!_occurs[_source]) _occurs[_source] = 0; | ||
occurs[source] += node.specifiers.length; | ||
}; | ||
var exportsVisitor = { | ||
enter: function enter(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 enter(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 = { | ||
@@ -123,164 +50,245 @@ enter: function enter(node, parent, scope, formatter) { | ||
DefaultFormatter.prototype.remapAssignments = function () { | ||
if (this.hasLocalImports) { | ||
this.file.scope.traverse(this.file.ast, remapVisitor, this); | ||
var importsVisitor = { | ||
enter: function enter(node, parent, scope, formatter) { | ||
if (t.isImportDeclaration(node)) { | ||
formatter.hasLocalImports = true; | ||
extend(formatter.localImports, t.getBindingIdentifiers(node)); | ||
formatter.bumpImportOccurences(node); | ||
} | ||
} | ||
}; | ||
DefaultFormatter.prototype.isLocalReference = function (node) { | ||
var localImports = this.localImports; | ||
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node; | ||
}; | ||
var exportsVisitor = { | ||
enter: function enter(node, parent, scope, formatter) { | ||
var declar = node && node.declaration; | ||
if (t.isExportDeclaration(node)) { | ||
formatter.hasLocalImports = true; | ||
DefaultFormatter.prototype.remapExportAssignment = function (node) { | ||
return t.assignmentExpression("=", node.left, t.assignmentExpression(node.operator, t.memberExpression(t.identifier("exports"), node.left), node.right)); | ||
}; | ||
if (declar && t.isStatement(declar)) { | ||
extend(formatter.localExports, t.getBindingIdentifiers(declar)); | ||
} | ||
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); | ||
if (!node["default"]) { | ||
formatter.hasNonDefaultExports = true; | ||
} | ||
if (node.source) { | ||
formatter.bumpImportOccurences(node); | ||
} | ||
} | ||
} | ||
}; | ||
DefaultFormatter.prototype.getModuleName = function () { | ||
var opts = this.file.opts; | ||
if (opts.moduleId) return opts.moduleId; | ||
var DefaultFormatter = (function () { | ||
function DefaultFormatter(file) { | ||
_classCallCheck(this, DefaultFormatter); | ||
var filenameRelative = opts.filenameRelative; | ||
var moduleName = ""; | ||
this.scope = file.scope; | ||
this.file = file; | ||
this.ids = object(); | ||
if (opts.moduleRoot) { | ||
moduleName = opts.moduleRoot + "/"; | ||
} | ||
this.hasNonDefaultExports = false; | ||
if (!opts.filenameRelative) { | ||
return moduleName + opts.filename.replace(/^\//, ""); | ||
} | ||
this.hasLocalExports = false; | ||
this.hasLocalImports = false; | ||
if (opts.sourceRoot) { | ||
// remove sourceRoot from filename | ||
var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "/?"); | ||
filenameRelative = filenameRelative.replace(sourceRootRegEx, ""); | ||
} | ||
this.localImportOccurences = object(); | ||
this.localExports = object(); | ||
this.localImports = object(); | ||
if (!opts.keepModuleIdExtensions) { | ||
// remove extension | ||
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, ""); | ||
this.getLocalExports(); | ||
this.getLocalImports(); | ||
this.remapAssignments(); | ||
} | ||
moduleName += filenameRelative; | ||
DefaultFormatter.prototype.doDefaultExportInterop = function doDefaultExportInterop(node) { | ||
return node["default"] && !this.noInteropRequireExport && !this.hasNonDefaultExports; | ||
}; | ||
// normalize path separators | ||
moduleName = moduleName.replace(/\\/g, "/"); | ||
DefaultFormatter.prototype.bumpImportOccurences = function bumpImportOccurences(node) { | ||
var source = node.source.value; | ||
var occurs = this.localImportOccurences; | ||
var _occurs = occurs; | ||
var _source = source; | ||
if (!_occurs[_source]) _occurs[_source] = 0; | ||
return moduleName; | ||
}; | ||
occurs[source] += node.specifiers.length; | ||
}; | ||
DefaultFormatter.prototype._pushStatement = function (ref, nodes) { | ||
if (t.isClass(ref) || t.isFunction(ref)) { | ||
if (ref.id) { | ||
nodes.push(t.toStatement(ref)); | ||
ref = ref.id; | ||
DefaultFormatter.prototype.getLocalExports = function getLocalExports() { | ||
this.file.scope.traverse(this.file.ast, exportsVisitor, this); | ||
}; | ||
DefaultFormatter.prototype.getLocalImports = function getLocalImports() { | ||
this.file.scope.traverse(this.file.ast, importsVisitor, this); | ||
}; | ||
DefaultFormatter.prototype.remapAssignments = function remapAssignments() { | ||
if (this.hasLocalImports) { | ||
this.file.scope.traverse(this.file.ast, remapVisitor, this); | ||
} | ||
} | ||
}; | ||
return ref; | ||
}; | ||
DefaultFormatter.prototype.isLocalReference = function isLocalReference(node) { | ||
var localImports = this.localImports; | ||
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node; | ||
}; | ||
DefaultFormatter.prototype._hoistExport = function (declar, assign, priority) { | ||
if (t.isFunctionDeclaration(declar)) { | ||
assign._blockHoist = priority || 2; | ||
} | ||
DefaultFormatter.prototype.remapExportAssignment = function remapExportAssignment(node) { | ||
return t.assignmentExpression("=", node.left, t.assignmentExpression(node.operator, t.memberExpression(t.identifier("exports"), node.left), node.right)); | ||
}; | ||
return assign; | ||
}; | ||
DefaultFormatter.prototype.isLocalReference = function isLocalReference(node, scope) { | ||
var localExports = this.localExports; | ||
var name = node.name; | ||
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name); | ||
}; | ||
DefaultFormatter.prototype.getExternalReference = function (node, nodes) { | ||
var ids = this.ids; | ||
var id = node.source.value; | ||
DefaultFormatter.prototype.getModuleName = function getModuleName() { | ||
var opts = this.file.opts; | ||
if (opts.moduleId) return opts.moduleId; | ||
if (ids[id]) { | ||
return ids[id]; | ||
} else { | ||
return this.ids[id] = this._getExternalReference(node, nodes); | ||
} | ||
}; | ||
var filenameRelative = opts.filenameRelative; | ||
var moduleName = ""; | ||
DefaultFormatter.prototype.checkExportIdentifier = function (node) { | ||
if (t.isIdentifier(node, { name: "__esModule" })) { | ||
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name)); | ||
} | ||
}; | ||
if (opts.moduleRoot) { | ||
moduleName = opts.moduleRoot + "/"; | ||
} | ||
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { | ||
if (node.source) { | ||
var ref = this.getExternalReference(node, nodes); | ||
if (!opts.filenameRelative) { | ||
return moduleName + opts.filename.replace(/^\//, ""); | ||
} | ||
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)); | ||
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 _pushStatement(ref, nodes) { | ||
if (t.isClass(ref) || t.isFunction(ref)) { | ||
if (ref.id) { | ||
nodes.push(t.toStatement(ref)); | ||
ref = ref.id; | ||
} | ||
} | ||
// export { foo } from "test"; | ||
nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), ref, node)); | ||
return ref; | ||
}; | ||
DefaultFormatter.prototype._hoistExport = function _hoistExport(declar, assign, priority) { | ||
if (t.isFunctionDeclaration(declar)) { | ||
assign._blockHoist = priority || 2; | ||
} | ||
} 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])])); | ||
}; | ||
return assign; | ||
}; | ||
DefaultFormatter.prototype.buildExportsAssignment = function (id, init) { | ||
this.checkExportIdentifier(id); | ||
return util.template("exports-assign", { | ||
VALUE: init, | ||
KEY: id | ||
}, true); | ||
}; | ||
DefaultFormatter.prototype.getExternalReference = function getExternalReference(node, nodes) { | ||
var ids = this.ids; | ||
var id = node.source.value; | ||
DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { | ||
var declar = node.declaration; | ||
if (ids[id]) { | ||
return ids[id]; | ||
} else { | ||
return this.ids[id] = this._getExternalReference(node, nodes); | ||
} | ||
}; | ||
var id = declar.id; | ||
DefaultFormatter.prototype.checkExportIdentifier = function checkExportIdentifier(node) { | ||
if (t.isIdentifier(node, { name: "__esModule" })) { | ||
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name)); | ||
} | ||
}; | ||
if (node["default"]) { | ||
id = t.identifier("default"); | ||
} | ||
DefaultFormatter.prototype.exportSpecifier = function exportSpecifier(specifier, node, nodes) { | ||
if (node.source) { | ||
var ref = this.getExternalReference(node, nodes); | ||
var assign; | ||
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)); | ||
} | ||
if (t.isVariableDeclaration(declar)) { | ||
for (var i = 0; i < declar.declarations.length; i++) { | ||
var decl = declar.declarations[i]; | ||
// 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)); | ||
} | ||
}; | ||
decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression; | ||
DefaultFormatter.prototype.buildExportsWildcard = function buildExportsWildcard(objectIdentifier) { | ||
return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [t.identifier("exports"), t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier])])); | ||
}; | ||
var newDeclar = t.variableDeclaration(declar.kind, [decl]); | ||
if (i === 0) t.inherits(newDeclar, declar); | ||
nodes.push(newDeclar); | ||
DefaultFormatter.prototype.buildExportsAssignment = function buildExportsAssignment(id, init) { | ||
this.checkExportIdentifier(id); | ||
return util.template("exports-assign", { | ||
VALUE: init, | ||
KEY: id | ||
}, true); | ||
}; | ||
DefaultFormatter.prototype.exportDeclaration = function exportDeclaration(node, nodes) { | ||
var declar = node.declaration; | ||
var id = declar.id; | ||
if (node["default"]) { | ||
id = t.identifier("default"); | ||
} | ||
} else { | ||
var ref = declar; | ||
if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) { | ||
ref = declar.id; | ||
nodes.push(declar); | ||
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); | ||
} | ||
}; | ||
assign = this.buildExportsAssignment(id, ref, node); | ||
return DefaultFormatter; | ||
})(); | ||
nodes.push(assign); | ||
this._hoistExport(declar, assign); | ||
} | ||
}; | ||
module.exports = DefaultFormatter; |
"use strict"; | ||
module.exports = AMDFormatter; | ||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var DefaultFormatter = require("./_default"); | ||
@@ -12,96 +14,106 @@ var CommonFormatter = require("./common"); | ||
function AMDFormatter() { | ||
CommonFormatter.apply(this, arguments); | ||
} | ||
var AMDFormatter = (function (DefaultFormatter) { | ||
function AMDFormatter() { | ||
this.init = CommonFormatter.prototype.init; | ||
util.inherits(AMDFormatter, DefaultFormatter); | ||
_classCallCheck(this, AMDFormatter); | ||
AMDFormatter.prototype.init = CommonFormatter.prototype.init; | ||
AMDFormatter.prototype.buildDependencyLiterals = function () { | ||
var names = []; | ||
for (var name in this.ids) { | ||
names.push(t.literal(name)); | ||
if (DefaultFormatter != null) { | ||
DefaultFormatter.apply(this, arguments); | ||
} | ||
} | ||
return names; | ||
}; | ||
/** | ||
* Wrap the entire body in a `define` wrapper. | ||
*/ | ||
_inherits(AMDFormatter, DefaultFormatter); | ||
AMDFormatter.prototype.transform = function (program) { | ||
var body = program.body; | ||
AMDFormatter.prototype.buildDependencyLiterals = function buildDependencyLiterals() { | ||
var names = []; | ||
for (var name in this.ids) { | ||
names.push(t.literal(name)); | ||
} | ||
return names; | ||
}; | ||
// build an array of module names | ||
/** | ||
* Wrap the entire body in a `define` wrapper. | ||
*/ | ||
var names = [t.literal("exports")]; | ||
if (this.passModuleArg) names.push(t.literal("module")); | ||
names = names.concat(this.buildDependencyLiterals()); | ||
names = t.arrayExpression(names); | ||
AMDFormatter.prototype.transform = function transform(program) { | ||
var body = program.body; | ||
// build up define container | ||
// build an array of module names | ||
var params = values(this.ids); | ||
if (this.passModuleArg) params.unshift(t.identifier("module")); | ||
params.unshift(t.identifier("exports")); | ||
var names = [t.literal("exports")]; | ||
if (this.passModuleArg) names.push(t.literal("module")); | ||
names = names.concat(this.buildDependencyLiterals()); | ||
names = t.arrayExpression(names); | ||
var container = t.functionExpression(null, params, t.blockStatement(body)); | ||
// build up define container | ||
var defineArgs = [names, container]; | ||
var moduleName = this.getModuleName(); | ||
if (moduleName) defineArgs.unshift(t.literal(moduleName)); | ||
var params = values(this.ids); | ||
if (this.passModuleArg) params.unshift(t.identifier("module")); | ||
params.unshift(t.identifier("exports")); | ||
var call = t.callExpression(t.identifier("define"), defineArgs); | ||
var container = t.functionExpression(null, params, t.blockStatement(body)); | ||
program.body = [t.expressionStatement(call)]; | ||
}; | ||
var defineArgs = [names, container]; | ||
var moduleName = this.getModuleName(); | ||
if (moduleName) defineArgs.unshift(t.literal(moduleName)); | ||
/** | ||
* Get the AMD module name that we'll prepend to the wrapper | ||
* to define this module | ||
*/ | ||
var call = t.callExpression(t.identifier("define"), defineArgs); | ||
AMDFormatter.prototype.getModuleName = function () { | ||
if (this.file.opts.moduleIds) { | ||
return DefaultFormatter.prototype.getModuleName.apply(this, arguments); | ||
} else { | ||
return null; | ||
} | ||
}; | ||
program.body = [t.expressionStatement(call)]; | ||
}; | ||
AMDFormatter.prototype._getExternalReference = function (node) { | ||
return this.scope.generateUidIdentifier(node.source.value); | ||
}; | ||
/** | ||
* Get the AMD module name that we'll prepend to the wrapper | ||
* to define this module | ||
*/ | ||
AMDFormatter.prototype.importDeclaration = function (node) { | ||
this.getExternalReference(node); | ||
}; | ||
AMDFormatter.prototype.getModuleName = function getModuleName() { | ||
if (this.file.opts.moduleIds) { | ||
return DefaultFormatter.prototype.getModuleName.apply(this, arguments); | ||
} else { | ||
return null; | ||
} | ||
}; | ||
AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) { | ||
var key = t.getSpecifierName(specifier); | ||
var ref = this.getExternalReference(node); | ||
AMDFormatter.prototype._getExternalReference = function _getExternalReference(node) { | ||
return this.scope.generateUidIdentifier(node.source.value); | ||
}; | ||
if (includes(this.file.dynamicImportedNoDefault, node)) { | ||
// Prevent unnecessary renaming of dynamic imports. | ||
this.ids[node.source.value] = ref; | ||
} else if (t.isImportBatchSpecifier(specifier)) {} 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); | ||
} | ||
AMDFormatter.prototype.importDeclaration = function importDeclaration(node) { | ||
this.getExternalReference(node); | ||
}; | ||
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(key, ref)])); | ||
}; | ||
AMDFormatter.prototype.importSpecifier = function importSpecifier(specifier, node, nodes) { | ||
var key = t.getSpecifierName(specifier); | ||
var ref = this.getExternalReference(node); | ||
AMDFormatter.prototype.exportDeclaration = function (node) { | ||
if (this.doDefaultExportInterop(node)) { | ||
this.passModuleArg = true; | ||
} | ||
if (includes(this.file.dynamicImportedNoDefault, node)) { | ||
// Prevent unnecessary renaming of dynamic imports. | ||
this.ids[node.source.value] = ref; | ||
} else if (t.isImportBatchSpecifier(specifier)) {} 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); | ||
} | ||
CommonFormatter.prototype.exportDeclaration.apply(this, arguments); | ||
}; | ||
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(key, ref)])); | ||
}; | ||
AMDFormatter.prototype.exportDeclaration = function exportDeclaration(node) { | ||
if (this.doDefaultExportInterop(node)) { | ||
this.passModuleArg = true; | ||
} | ||
CommonFormatter.prototype.exportDeclaration.apply(this, arguments); | ||
}; | ||
return AMDFormatter; | ||
})(DefaultFormatter); | ||
module.exports = AMDFormatter; | ||
// import * as bar from "foo"; |
"use strict"; | ||
module.exports = CommonJSFormatter; | ||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var DefaultFormatter = require("./_default"); | ||
@@ -10,89 +12,99 @@ var includes = require("lodash/collection/includes"); | ||
function CommonJSFormatter() { | ||
DefaultFormatter.apply(this, arguments); | ||
} | ||
var CommonJSFormatter = (function (DefaultFormatter) { | ||
function CommonJSFormatter() { | ||
_classCallCheck(this, CommonJSFormatter); | ||
util.inherits(CommonJSFormatter, DefaultFormatter); | ||
if (DefaultFormatter != null) { | ||
DefaultFormatter.apply(this, arguments); | ||
} | ||
} | ||
CommonJSFormatter.prototype.init = function () { | ||
var file = this.file; | ||
var scope = file.scope; | ||
_inherits(CommonJSFormatter, DefaultFormatter); | ||
scope.rename("module"); | ||
CommonJSFormatter.prototype.init = function init() { | ||
var file = this.file; | ||
var scope = file.scope; | ||
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)); | ||
} | ||
}; | ||
scope.rename("module"); | ||
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { | ||
var variableName = t.getSpecifierName(specifier); | ||
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)); | ||
} | ||
}; | ||
var ref = this.getExternalReference(node, nodes); | ||
CommonJSFormatter.prototype.importSpecifier = function importSpecifier(specifier, node, nodes) { | ||
var variableName = t.getSpecifierName(specifier); | ||
// 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")); | ||
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 { | ||
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]); | ||
// import { foo } from "foo"; | ||
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, t.memberExpression(ref, t.getSpecifierId(specifier)))])); | ||
} | ||
} | ||
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]); | ||
CommonJSFormatter.prototype.importDeclaration = function importDeclaration(node, nodes) { | ||
// import "foo"; | ||
nodes.push(util.template("require", { | ||
MODULE_NAME: node.source | ||
}, true)); | ||
}; | ||
CommonJSFormatter.prototype.exportDeclaration = function exportDeclaration(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; | ||
} | ||
// 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)))])); | ||
nodes.push(assign); | ||
return; | ||
} | ||
} | ||
}; | ||
CommonJSFormatter.prototype.importDeclaration = function (node, nodes) { | ||
// import "foo"; | ||
nodes.push(util.template("require", { | ||
MODULE_NAME: node.source | ||
}, true)); | ||
}; | ||
DefaultFormatter.prototype.exportDeclaration.apply(this, arguments); | ||
}; | ||
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); | ||
CommonJSFormatter.prototype._getExternalReference = function _getExternalReference(node, nodes) { | ||
var source = node.source.value; | ||
var call = t.callExpression(t.identifier("require"), [node.source]); | ||
if (t.isFunctionDeclaration(declar)) { | ||
// we can hoist this assignment to the top of the file | ||
assign._blockHoist = 3; | ||
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; | ||
} | ||
}; | ||
nodes.push(assign); | ||
return; | ||
} | ||
return CommonJSFormatter; | ||
})(DefaultFormatter); | ||
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; | ||
} | ||
}; | ||
module.exports = CommonJSFormatter; |
"use strict"; | ||
module.exports = IgnoreFormatter; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var t = require("../../types"); | ||
function IgnoreFormatter() {} | ||
var IgnoreFormatter = (function () { | ||
function IgnoreFormatter() { | ||
_classCallCheck(this, IgnoreFormatter); | ||
} | ||
IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) { | ||
var declar = t.toStatement(node.declaration, true); | ||
if (declar) nodes.push(t.inherits(declar, node)); | ||
}; | ||
IgnoreFormatter.prototype.exportDeclaration = function exportDeclaration(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 () {}; | ||
IgnoreFormatter.prototype.importDeclaration = function importDeclaration() {}; | ||
IgnoreFormatter.prototype.importSpecifier = function importSpecifier() {}; | ||
IgnoreFormatter.prototype.exportSpecifier = function exportSpecifier() {}; | ||
return IgnoreFormatter; | ||
})(); | ||
module.exports = IgnoreFormatter; |
"use strict"; | ||
module.exports = SystemFormatter; | ||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var DefaultFormatter = require("./_default"); | ||
@@ -13,88 +15,2 @@ var AMDFormatter = require("./amd"); | ||
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 enter(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 = { | ||
@@ -157,37 +73,131 @@ enter: function enter(node, parent, scope, hoistDeclarators) { | ||
SystemFormatter.prototype.transform = function (program) { | ||
var hoistDeclarators = []; | ||
var moduleName = this.getModuleName(); | ||
var moduleNameLiteral = t.literal(moduleName); | ||
var runnerSettersVisitor = { | ||
enter: function enter(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); | ||
} | ||
var block = t.blockStatement(program.body); | ||
this.remove(); | ||
} | ||
} | ||
}; | ||
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 SystemFormatter = (function (AMDFormatter) { | ||
function SystemFormatter(file) { | ||
_classCallCheck(this, SystemFormatter); | ||
var handlerBody = runner.expression.arguments[2].body.body; | ||
if (!moduleName) runner.expression.arguments.shift(); | ||
this.exportIdentifier = file.scope.generateUidIdentifier("export"); | ||
this.noInteropRequireExport = true; | ||
this.noInteropRequireImport = true; | ||
var returnStatement = handlerBody.pop(); | ||
DefaultFormatter.apply(this, arguments); | ||
} | ||
// hoist up all variable declarations | ||
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators); | ||
_inherits(SystemFormatter, AMDFormatter); | ||
if (hoistDeclarators.length) { | ||
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators); | ||
hoistDeclar._blockHoist = true; | ||
handlerBody.unshift(hoistDeclar); | ||
} | ||
SystemFormatter.prototype.init = function init() {}; | ||
// hoist up function declarations for circular references | ||
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody); | ||
SystemFormatter.prototype._addImportSource = function _addImportSource(node, exportNode) { | ||
node._importSource = exportNode.source && exportNode.source.value; | ||
return node; | ||
}; | ||
handlerBody.push(returnStatement); | ||
SystemFormatter.prototype.buildExportsWildcard = function buildExportsWildcard(objectIdentifier, node) { | ||
var leftIdentifier = this.scope.generateUidIdentifier("key"); | ||
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true); | ||
program.body = [runner]; | ||
}; | ||
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 buildExportsAssignment(id, init, node) { | ||
var call = this.buildExportCall(t.literal(id.name), init, true); | ||
return this._addImportSource(call, node); | ||
}; | ||
SystemFormatter.prototype.remapExportAssignment = function remapExportAssignment(node) { | ||
return this.buildExportCall(t.literal(node.left.name), node); | ||
}; | ||
SystemFormatter.prototype.buildExportCall = function buildExportCall(id, init, isStatement) { | ||
var call = t.callExpression(this.exportIdentifier, [id, init]); | ||
if (isStatement) { | ||
return t.expressionStatement(call); | ||
} else { | ||
return call; | ||
} | ||
}; | ||
SystemFormatter.prototype.importSpecifier = function importSpecifier(specifier, node, nodes) { | ||
AMDFormatter.prototype.importSpecifier.apply(this, arguments); | ||
this._addImportSource(last(nodes), node); | ||
}; | ||
SystemFormatter.prototype.buildRunnerSetters = function buildRunnerSetters(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)); | ||
})); | ||
}; | ||
SystemFormatter.prototype.transform = function transform(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]; | ||
}; | ||
return SystemFormatter; | ||
})(AMDFormatter); | ||
module.exports = SystemFormatter; |
"use strict"; | ||
module.exports = UMDFormatter; | ||
var _inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var AMDFormatter = require("./amd"); | ||
var values = require("lodash/object/values"); | ||
var util = require("../../util"); | ||
var t = require("../../types"); | ||
var values = require("lodash/object/values"); | ||
function UMDFormatter() { | ||
AMDFormatter.apply(this, arguments); | ||
} | ||
var UMDFormatter = (function (AMDFormatter) { | ||
function UMDFormatter() { | ||
_classCallCheck(this, UMDFormatter); | ||
util.inherits(UMDFormatter, AMDFormatter); | ||
if (AMDFormatter != null) { | ||
AMDFormatter.apply(this, arguments); | ||
} | ||
} | ||
UMDFormatter.prototype.transform = function (program) { | ||
var body = program.body; | ||
_inherits(UMDFormatter, AMDFormatter); | ||
// build an array of module names | ||
UMDFormatter.prototype.transform = function transform(program) { | ||
var body = program.body; | ||
var names = []; | ||
for (var name in this.ids) { | ||
names.push(t.literal(name)); | ||
} | ||
// build an array of module names | ||
// factory | ||
var names = []; | ||
for (var name in this.ids) { | ||
names.push(t.literal(name)); | ||
} | ||
var ids = values(this.ids); | ||
var args = [t.identifier("exports")]; | ||
if (this.passModuleArg) args.push(t.identifier("module")); | ||
args = args.concat(ids); | ||
// factory | ||
var factory = t.functionExpression(null, args, t.blockStatement(body)); | ||
var ids = values(this.ids); | ||
var args = [t.identifier("exports")]; | ||
if (this.passModuleArg) args.push(t.identifier("module")); | ||
args = args.concat(ids); | ||
// amd | ||
var factory = t.functionExpression(null, args, t.blockStatement(body)); | ||
var defineArgs = [t.literal("exports")]; | ||
if (this.passModuleArg) defineArgs.push(t.literal("module")); | ||
defineArgs = defineArgs.concat(names); | ||
defineArgs = [t.arrayExpression(defineArgs)]; | ||
// amd | ||
// common | ||
var defineArgs = [t.literal("exports")]; | ||
if (this.passModuleArg) defineArgs.push(t.literal("module")); | ||
defineArgs = defineArgs.concat(names); | ||
defineArgs = [t.arrayExpression(defineArgs)]; | ||
var testExports = util.template("test-exports"); | ||
var testModule = util.template("test-module"); | ||
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; | ||
// common | ||
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]); | ||
})); | ||
var testExports = util.template("test-exports"); | ||
var testModule = util.template("test-module"); | ||
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports; | ||
// globals | ||
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]); | ||
})); | ||
//var umdArgs = []; | ||
// 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 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)]; | ||
}; | ||
// | ||
var call = t.callExpression(runner, [factory]); | ||
program.body = [t.expressionStatement(call)]; | ||
}; | ||
return UMDFormatter; | ||
})(AMDFormatter); | ||
module.exports = UMDFormatter; |
"use strict"; | ||
module.exports = TransformerPass; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -12,55 +12,63 @@ var includes = require("lodash/collection/includes"); | ||
function TransformerPass(file, transformer) { | ||
this.transformer = transformer; | ||
this.shouldRun = !transformer.check; | ||
this.handlers = transformer.handlers; | ||
this.file = file; | ||
} | ||
var TransformerPass = (function () { | ||
function TransformerPass(file, transformer) { | ||
_classCallCheck(this, TransformerPass); | ||
TransformerPass.prototype.canRun = function () { | ||
var transformer = this.transformer; | ||
this.transformer = transformer; | ||
this.shouldRun = !transformer.check; | ||
this.handlers = transformer.handlers; | ||
this.file = file; | ||
} | ||
var opts = this.file.opts; | ||
var key = transformer.key; | ||
TransformerPass.prototype.canRun = function canRun() { | ||
var transformer = this.transformer; | ||
// internal | ||
if (key[0] === "_") return true; | ||
var opts = this.file.opts; | ||
var key = transformer.key; | ||
// blacklist | ||
var blacklist = opts.blacklist; | ||
if (blacklist.length && includes(blacklist, key)) return false; | ||
// internal | ||
if (key[0] === "_") return true; | ||
// whitelist | ||
var whitelist = opts.whitelist; | ||
if (whitelist.length) return includes(whitelist, key); | ||
// blacklist | ||
var blacklist = opts.blacklist; | ||
if (blacklist.length && includes(blacklist, key)) return false; | ||
// optional | ||
if (transformer.optional && !includes(opts.optional, key)) return false; | ||
// whitelist | ||
var whitelist = opts.whitelist; | ||
if (whitelist.length) return includes(whitelist, key); | ||
// experimental | ||
if (transformer.experimental && !opts.experimental) return false; | ||
// optional | ||
if (transformer.optional && !includes(opts.optional, key)) return false; | ||
// playground | ||
if (transformer.playground && !opts.playground) return false; | ||
// experimental | ||
if (transformer.experimental && !opts.experimental) return false; | ||
return true; | ||
}; | ||
// playground | ||
if (transformer.playground && !opts.playground) return false; | ||
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; | ||
TransformerPass.prototype.checkNode = function checkNode(node) { | ||
var check = this.transformer.check; | ||
if (check) { | ||
return this.shouldRun = check(node); | ||
} else { | ||
return true; | ||
} | ||
}; | ||
var file = this.file; | ||
TransformerPass.prototype.transform = function transform() { | ||
if (!this.shouldRun) return; | ||
file.debug("Running transformer " + this.transformer.key); | ||
var file = this.file; | ||
file.scope.traverse(file.ast, this.handlers, file); | ||
}; | ||
file.debug("Running transformer " + this.transformer.key); | ||
file.scope.traverse(file.ast, this.handlers, file); | ||
}; | ||
return TransformerPass; | ||
})(); | ||
module.exports = TransformerPass; |
"use strict"; | ||
module.exports = Transformer; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -18,63 +18,71 @@ var TransformerPass = require("./transformer-pass"); | ||
function Transformer(key, transformer, opts) { | ||
transformer = assign({}, transformer); | ||
var Transformer = (function () { | ||
function Transformer(key, transformer, opts) { | ||
_classCallCheck(this, Transformer); | ||
var take = function take(key) { | ||
var val = transformer[key]; | ||
delete transformer[key]; | ||
return val; | ||
}; | ||
transformer = assign({}, transformer); | ||
this.manipulateOptions = take("manipulateOptions"); | ||
this.check = take("check"); | ||
this.post = take("post"); | ||
this.pre = take("pre"); | ||
var take = function take(key) { | ||
var val = transformer[key]; | ||
delete transformer[key]; | ||
return val; | ||
}; | ||
this.experimental = !!take("experimental"); | ||
this.playground = !!take("playground"); | ||
this.secondPass = !!take("secondPass"); | ||
this.optional = !!take("optional"); | ||
this.manipulateOptions = take("manipulateOptions"); | ||
this.check = take("check"); | ||
this.post = take("post"); | ||
this.pre = take("pre"); | ||
this.handlers = this.normalize(transformer); | ||
this.experimental = !!take("experimental"); | ||
this.playground = !!take("playground"); | ||
this.secondPass = !!take("secondPass"); | ||
this.optional = !!take("optional"); | ||
var _ref = this; | ||
this.handlers = this.normalize(transformer); | ||
if (!_ref.opts) _ref.opts = {}; | ||
var _ref = this; | ||
this.key = key; | ||
} | ||
if (!_ref.opts) _ref.opts = {}; | ||
Transformer.prototype.normalize = function (transformer) { | ||
var _this = this; | ||
if (isFunction(transformer)) { | ||
transformer = { ast: transformer }; | ||
this.key = key; | ||
} | ||
traverse.explode(transformer); | ||
Transformer.prototype.normalize = function normalize(transformer) { | ||
var _this = this; | ||
each(transformer, function (fns, type) { | ||
// hidden property | ||
if (type[0] === "_") { | ||
_this[type] = fns; | ||
return; | ||
if (isFunction(transformer)) { | ||
transformer = { ast: transformer }; | ||
} | ||
if (type === "enter" || type === "exit") return; | ||
traverse.explode(transformer); | ||
if (isFunction(fns)) fns = { enter: fns }; | ||
each(transformer, function (fns, type) { | ||
// hidden property | ||
if (type[0] === "_") { | ||
_this[type] = fns; | ||
return; | ||
} | ||
if (!isObject(fns)) return; | ||
if (type === "enter" || type === "exit") return; | ||
if (!fns.enter) fns.enter = function () {}; | ||
if (!fns.exit) fns.exit = function () {}; | ||
if (isFunction(fns)) fns = { enter: fns }; | ||
transformer[type] = fns; | ||
}); | ||
if (!isObject(fns)) return; | ||
return transformer; | ||
}; | ||
if (!fns.enter) fns.enter = function () {}; | ||
if (!fns.exit) fns.exit = function () {}; | ||
Transformer.prototype.buildPass = function (file) { | ||
return new TransformerPass(file, this); | ||
}; | ||
transformer[type] = fns; | ||
}); | ||
return transformer; | ||
}; | ||
Transformer.prototype.buildPass = function buildPass(file) { | ||
return new TransformerPass(file, this); | ||
}; | ||
return Transformer; | ||
})(); | ||
module.exports = Transformer; |
"use strict"; | ||
var _toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; | ||
var t = require("../../../types"); | ||
@@ -14,3 +16,3 @@ | ||
var call = t.callExpression(t.memberExpression(t.memberExpression(object, prop), t.identifier("bind")), [object].concat(node.arguments)); | ||
var call = t.callExpression(t.memberExpression(t.memberExpression(object, prop), t.identifier("bind")), [object].concat(_toConsumableArray(node.arguments))); | ||
@@ -17,0 +19,0 @@ if (temp) { |
"use strict"; | ||
module.exports = TraversalContext; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -9,47 +9,55 @@ var TraversalPath = require("./path"); | ||
function TraversalContext(scope, opts, state, parentPath) { | ||
this.shouldFlatten = false; | ||
this.parentPath = parentPath; | ||
var TraversalConext = (function () { | ||
function TraversalConext(scope, opts, state, parentPath) { | ||
_classCallCheck(this, TraversalConext); | ||
this.scope = scope; | ||
this.state = state; | ||
this.opts = opts; | ||
} | ||
this.shouldFlatten = false; | ||
this.parentPath = parentPath; | ||
TraversalContext.prototype.flatten = function () { | ||
this.shouldFlatten = true; | ||
}; | ||
this.scope = scope; | ||
this.state = state; | ||
this.opts = opts; | ||
} | ||
TraversalContext.prototype.visitNode = function (node, obj, key) { | ||
var iteration = new TraversalPath(this, node, obj, key); | ||
return iteration.visit(); | ||
}; | ||
TraversalConext.prototype.flatten = function flatten() { | ||
this.shouldFlatten = true; | ||
}; | ||
TraversalContext.prototype.visit = function (node, key) { | ||
var nodes = node[key]; | ||
if (!nodes) return; | ||
TraversalConext.prototype.visitNode = function visitNode(node, obj, key) { | ||
var iteration = new TraversalPath(this, node, obj, key); | ||
return iteration.visit(); | ||
}; | ||
if (!Array.isArray(nodes)) { | ||
return this.visitNode(node, node, key); | ||
} | ||
TraversalConext.prototype.visit = function visit(node, key) { | ||
var nodes = node[key]; | ||
if (!nodes) return; | ||
// nothing to traverse! | ||
if (nodes.length === 0) { | ||
return; | ||
} | ||
if (!Array.isArray(nodes)) { | ||
return this.visitNode(node, node, key); | ||
} | ||
for (var i = 0; i < nodes.length; i++) { | ||
if (nodes[i] && this.visitNode(node, nodes, i)) { | ||
return true; | ||
// nothing to traverse! | ||
if (nodes.length === 0) { | ||
return; | ||
} | ||
} | ||
if (this.shouldFlatten) { | ||
node[key] = flatten(node[key]); | ||
for (var i = 0; i < nodes.length; i++) { | ||
if (nodes[i] && this.visitNode(node, nodes, i)) { | ||
return true; | ||
} | ||
} | ||
if (key === "body") { | ||
// we can safely compact this | ||
node[key] = compact(node[key]); | ||
if (this.shouldFlatten) { | ||
node[key] = flatten(node[key]); | ||
if (key === "body") { | ||
// we can safely compact this | ||
node[key] = compact(node[key]); | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
return TraversalConext; | ||
})(); | ||
module.exports = TraversalConext; |
"use strict"; | ||
module.exports = TraversalPath; | ||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); }; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
var traverse = require("./index"); | ||
@@ -10,147 +12,157 @@ var includes = require("lodash/collection/includes"); | ||
function TraversalPath(context, parent, container, key) { | ||
this.shouldRemove = false; | ||
this.shouldSkip = false; | ||
this.shouldStop = false; | ||
var TraversalPath = (function () { | ||
function TraversalPath(context, parent, container, key) { | ||
_classCallCheck(this, TraversalPath); | ||
this.parentPath = context.parentPath; | ||
this.context = context; | ||
this.state = this.context.state; | ||
this.opts = this.context.opts; | ||
this.shouldRemove = false; | ||
this.shouldSkip = false; | ||
this.shouldStop = false; | ||
this.container = container; | ||
this.key = key; | ||
this.parentPath = context.parentPath; | ||
this.context = context; | ||
this.state = this.context.state; | ||
this.opts = this.context.opts; | ||
this.parent = parent; | ||
this.state = context.state; | ||
this.container = container; | ||
this.key = key; | ||
this.setScope(); | ||
} | ||
this.parent = parent; | ||
this.state = context.state; | ||
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); | ||
this.setScope(); | ||
} | ||
return ourScope; | ||
}; | ||
TraversalPath.getScope = function getScope(node, parent, scope) { | ||
var ourScope = scope; | ||
TraversalPath.prototype.setScope = function () { | ||
this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope); | ||
}; | ||
// we're entering a new scope so let's construct it! | ||
if (t.isScope(node, parent)) { | ||
ourScope = new Scope(node, parent, scope); | ||
} | ||
TraversalPath.prototype.remove = function () { | ||
this.shouldRemove = true; | ||
this.shouldSkip = true; | ||
}; | ||
return ourScope; | ||
}; | ||
TraversalPath.prototype.skip = function () { | ||
this.shouldSkip = true; | ||
}; | ||
TraversalPath.prototype.setScope = function setScope() { | ||
this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope); | ||
}; | ||
TraversalPath.prototype.stop = function () { | ||
this.shouldStop = true; | ||
this.shouldSkip = true; | ||
}; | ||
TraversalPath.prototype.remove = function remove() { | ||
this.shouldRemove = true; | ||
this.shouldSkip = true; | ||
}; | ||
TraversalPath.prototype.flatten = function () { | ||
this.context.flatten(); | ||
}; | ||
TraversalPath.prototype.skip = function skip() { | ||
this.shouldSkip = true; | ||
}; | ||
Object.defineProperty(TraversalPath.prototype, "node", { | ||
get: function get() { | ||
return this.container[this.key]; | ||
}, | ||
TraversalPath.prototype.stop = function stop() { | ||
this.shouldStop = true; | ||
this.shouldSkip = true; | ||
}; | ||
set: function set(replacement) { | ||
var isArray = Array.isArray(replacement); | ||
TraversalPath.prototype.flatten = function flatten() { | ||
this.context.flatten(); | ||
}; | ||
// 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); | ||
TraversalPath.prototype.call = function call(key) { | ||
var node = this.node; | ||
if (!node) return; | ||
// replace the node | ||
this.container[this.key] = replacement; | ||
this.setScope(); | ||
var opts = this.opts; | ||
var fn = opts[key] || opts; | ||
if (opts[node.type]) fn = opts[node.type][key] || fn; | ||
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); | ||
} | ||
var replacement = fn.call(this, node, this.parent, this.scope, this.state); | ||
if (replacement) { | ||
this.node = replacement; | ||
} | ||
// 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); | ||
} | ||
if (this.shouldRemove) { | ||
this.container[this.key] = null; | ||
this.flatten(); | ||
} | ||
} | ||
}); | ||
}; | ||
TraversalPath.prototype.call = function (key) { | ||
var node = this.node; | ||
if (!node) return; | ||
TraversalPath.prototype.visit = function visit() { | ||
var opts = this.opts; | ||
var node = this.node; | ||
var opts = this.opts; | ||
var fn = opts[key] || opts; | ||
if (opts[node.type]) fn = opts[node.type][key] || fn; | ||
// type is blacklisted | ||
if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) { | ||
return; | ||
} | ||
var replacement = fn.call(this, node, this.parent, this.scope, this.state); | ||
this.call("enter"); | ||
if (replacement) { | ||
this.node = replacement; | ||
} | ||
if (this.shouldSkip) { | ||
return this.shouldStop; | ||
} | ||
if (this.shouldRemove) { | ||
this.container[this.key] = null; | ||
this.flatten(); | ||
} | ||
}; | ||
node = this.node; | ||
TraversalPath.prototype.visit = function () { | ||
var opts = this.opts; | ||
var 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"); | ||
} | ||
// type is blacklisted | ||
if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) { | ||
return; | ||
} | ||
return this.shouldStop; | ||
}; | ||
this.call("enter"); | ||
TraversalPath.prototype.isReferencedIdentifier = function isReferencedIdentifier() { | ||
return t.isReferencedIdentifier(this.node); | ||
}; | ||
if (this.shouldSkip) { | ||
return this.shouldStop; | ||
} | ||
_prototypeProperties(TraversalPath, null, { | ||
node: { | ||
get: function () { | ||
return this.container[this.key]; | ||
}, | ||
set: function (replacement) { | ||
var isArray = Array.isArray(replacement); | ||
node = this.node; | ||
// 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); | ||
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); | ||
// 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(); | ||
} | ||
}, | ||
configurable: true | ||
} | ||
} else { | ||
traverse.node(node, opts, this.scope, this.state, this); | ||
this.call("exit"); | ||
} | ||
}); | ||
return this.shouldStop; | ||
}; | ||
return TraversalPath; | ||
})(); | ||
TraversalPath.prototype.isReferencedIdentifier = function () { | ||
return t.isReferencedIdentifier(this.node); | ||
}; | ||
module.exports = TraversalPath; |
"use strict"; | ||
module.exports = Scope; | ||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; | ||
@@ -16,644 +16,663 @@ var includes = require("lodash/collection/includes"); | ||
/** | ||
* This searches the current "scope" and collects all references/bindings | ||
* within. | ||
* | ||
* @param {Node} block | ||
* @param {Node} parentBlock | ||
* @param {Scope} [parent] | ||
* @param {File} [file] | ||
*/ | ||
var functionVariableVisitor = { | ||
enter: function enter(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); | ||
}); | ||
} | ||
function Scope(block, parentBlock, parent, file) { | ||
this.parent = parent; | ||
this.file = parent ? parent.file : file; | ||
// 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(); | ||
this.parentBlock = parentBlock; | ||
this.block = block; | ||
// function identifier doesn't belong to this scope | ||
if (state.blockId && node === state.blockId) return; | ||
this.crawl(); | ||
} | ||
// delegate block scope handling to the `blockVariableVisitor` | ||
if (t.isBlockScoped(node)) return; | ||
Scope.globals = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys)); | ||
// this will be hit again once we traverse into it after this iteration | ||
if (t.isExportDeclaration(node) && t.isDeclaration(node.declaration)) return; | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Object} opts | ||
* @param [state] | ||
*/ | ||
Scope.prototype.traverse = function (node, opts, state) { | ||
traverse(node, opts, this, state); | ||
// we've ran into a declaration! | ||
if (t.isDeclaration(node)) state.scope.registerDeclaration(node); | ||
} | ||
}; | ||
/** | ||
* 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; | ||
var programReferenceVisitor = { | ||
enter: function enter(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); | ||
} | ||
} | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {String} name | ||
*/ | ||
Scope.prototype.generateUidIdentifier = function (name) { | ||
var id = t.identifier(this.generateUid(name)); | ||
this.getFunctionParent().registerBinding("uid", id); | ||
return id; | ||
var blockVariableVisitor = { | ||
enter: function enter(node, parent, scope, state) { | ||
if (t.isFunctionDeclaration(node) || t.isBlockScoped(node)) { | ||
state.registerDeclaration(node); | ||
} else if (t.isScope(node, parent)) { | ||
this.skip(); | ||
} | ||
} | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {String} name | ||
*/ | ||
var Scope = (function () { | ||
Scope.prototype.generateUid = function (name) { | ||
name = t.toIdentifier(name).replace(/^_+/, ""); | ||
/** | ||
* This searches the current "scope" and collects all references/bindings | ||
* within. | ||
* | ||
* @param {Node} block | ||
* @param {Node} parentBlock | ||
* @param {Scope} [parent] | ||
* @param {File} [file] | ||
*/ | ||
var uid; | ||
var i = 0; | ||
do { | ||
uid = this._generateUid(name, i); | ||
i++; | ||
} while (this.hasBinding(uid) || this.hasGlobal(uid)); | ||
return uid; | ||
}; | ||
function Scope(block, parentBlock, parent, file) { | ||
_classCallCheck(this, Scope); | ||
Scope.prototype._generateUid = function (name, i) { | ||
var id = name; | ||
if (i > 1) id += i; | ||
return "_" + id; | ||
}; | ||
this.parent = parent; | ||
this.file = parent ? parent.file : file; | ||
/* | ||
* Description | ||
* | ||
* @param {Object} parent | ||
* @returns {Object} | ||
*/ | ||
this.parentBlock = parentBlock; | ||
this.block = block; | ||
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; | ||
this.crawl(); | ||
} | ||
var parts = []; | ||
Scope.globals = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys)); | ||
var add = (function (_add) { | ||
var _addWrapper = function add() { | ||
return _add.apply(this, arguments); | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @param {Object} opts | ||
* @param [state] | ||
*/ | ||
Scope.prototype.traverse = (function (_traverse) { | ||
var _traverseWrapper = function traverse() { | ||
return _traverse.apply(this, arguments); | ||
}; | ||
_addWrapper.toString = function () { | ||
return _add.toString(); | ||
_traverseWrapper.toString = function () { | ||
return _traverse.toString(); | ||
}; | ||
return _addWrapper; | ||
})(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); | ||
} | ||
return _traverseWrapper; | ||
})(function (node, opts, state) { | ||
traverse(node, opts, this, state); | ||
}); | ||
add(node); | ||
/** | ||
* Description | ||
* | ||
* @param {String} [name="temp"] | ||
*/ | ||
var id = parts.join("$"); | ||
id = id.replace(/^_/, "") || "ref"; | ||
Scope.prototype.generateTemp = function generateTemp(name) { | ||
var id = this.generateUidIdentifier(name || "temp"); | ||
this.push({ | ||
key: id.name, | ||
id: id | ||
}); | ||
return id; | ||
}; | ||
return this.generateUidIdentifier(id); | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {String} name | ||
*/ | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @returns {Object} | ||
*/ | ||
Scope.prototype.generateUidIdentifier = function generateUidIdentifier(name) { | ||
var id = t.identifier(this.generateUid(name)); | ||
this.getFunctionParent().registerBinding("uid", id); | ||
return id; | ||
}; | ||
Scope.prototype.generateTempBasedOnNode = function (node) { | ||
if (t.isIdentifier(node) && this.hasBinding(node.name)) { | ||
return null; | ||
} | ||
/** | ||
* Description | ||
* | ||
* @param {String} name | ||
*/ | ||
var id = this.generateUidBasedOnNode(node); | ||
this.push({ | ||
key: id.name, | ||
id: id | ||
}); | ||
return id; | ||
}; | ||
Scope.prototype.generateUid = function generateUid(name) { | ||
name = t.toIdentifier(name).replace(/^_+/, ""); | ||
Scope.prototype.checkBlockScopedCollisions = function (kind, name, id) { | ||
var local = this.getOwnBindingInfo(name); | ||
if (!local) return; | ||
var uid; | ||
var i = 0; | ||
do { | ||
uid = this._generateUid(name, i); | ||
i++; | ||
} while (this.hasBinding(uid) || this.hasGlobal(uid)); | ||
return uid; | ||
}; | ||
if (kind === "param") return; | ||
if (kind === "hoisted" && local.kind === "let") return; | ||
Scope.prototype._generateUid = function _generateUid(name, i) { | ||
var id = name; | ||
if (i > 1) id += i; | ||
return "_" + id; | ||
}; | ||
if (local.kind === "let" || local.kind === "const" || local.kind === "module") { | ||
throw this.file.errorWithNode(id, messages.get("scopeDuplicateDeclaration", name), TypeError); | ||
} | ||
}; | ||
/* | ||
* Description | ||
* | ||
* @param {Object} parent | ||
* @returns {Object} | ||
*/ | ||
Scope.prototype.rename = function (oldName, newName) { | ||
if (!newName) newName = this.generateUidIdentifier(oldName).name; | ||
Scope.prototype.generateUidBasedOnNode = function generateUidBasedOnNode(parent) { | ||
var node = parent; | ||
var info = this.getBindingInfo(oldName); | ||
if (!info) return; | ||
if (t.isAssignmentExpression(parent)) { | ||
node = parent.left; | ||
} else if (t.isVariableDeclarator(parent)) { | ||
node = parent.id; | ||
} else if (t.isProperty(node)) { | ||
node = node.key; | ||
} | ||
var binding = info.identifier; | ||
var scope = info.scope; | ||
var parts = []; | ||
scope.traverse(scope.block, { | ||
enter: function enter(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(); | ||
} | ||
var add = (function (_add) { | ||
var _addWrapper = function add() { | ||
return _add.apply(this, arguments); | ||
}; | ||
_addWrapper.toString = function () { | ||
return _add.toString(); | ||
}; | ||
return _addWrapper; | ||
})(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); | ||
} | ||
} | ||
}); | ||
}); | ||
this.clearOwnBinding(oldName); | ||
scope.bindings[newName] = info; | ||
add(node); | ||
binding.name = newName; | ||
}; | ||
var id = parts.join("$"); | ||
id = id.replace(/^_/, "") || "ref"; | ||
Scope.prototype.inferType = function (node) { | ||
var target; | ||
return this.generateUidIdentifier(id); | ||
}; | ||
if (t.isVariableDeclarator(node)) { | ||
target = node.init; | ||
} | ||
/** | ||
* Description | ||
* | ||
* @param {Object} node | ||
* @returns {Object} | ||
*/ | ||
if (t.isArrayExpression(target)) { | ||
return t.genericTypeAnnotation(t.identifier("Array")); | ||
} | ||
Scope.prototype.generateTempBasedOnNode = function generateTempBasedOnNode(node) { | ||
if (t.isIdentifier(node) && this.hasBinding(node.name)) { | ||
return null; | ||
} | ||
if (t.isObjectExpression(target)) { | ||
return; | ||
} | ||
var id = this.generateUidBasedOnNode(node); | ||
this.push({ | ||
key: id.name, | ||
id: id | ||
}); | ||
return id; | ||
}; | ||
if (t.isLiteral(target)) { | ||
return; | ||
} | ||
Scope.prototype.checkBlockScopedCollisions = function checkBlockScopedCollisions(kind, name, id) { | ||
var local = this.getOwnBindingInfo(name); | ||
if (!local) 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 (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); | ||
} | ||
} | ||
}; | ||
if (t.isIdentifier(target)) { | ||
return; | ||
} | ||
}; | ||
Scope.prototype.rename = function rename(oldName, newName) { | ||
if (!newName) newName = this.generateUidIdentifier(oldName).name; | ||
Scope.prototype.isTypeGeneric = function (name, genericName) { | ||
var info = this.getBindingInfo(name); | ||
if (!info) return false; | ||
var info = this.getBindingInfo(oldName); | ||
if (!info) return; | ||
var type = info.typeAnnotation; | ||
return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName }); | ||
}; | ||
var binding = info.identifier; | ||
var scope = info.scope; | ||
Scope.prototype.assignTypeGeneric = function (name, type) { | ||
this.assignType(name, t.genericTypeAnnotation(t.identifier(type))); | ||
}; | ||
scope.traverse(scope.block, { | ||
enter: function enter(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(); | ||
} | ||
} | ||
} | ||
}); | ||
Scope.prototype.assignType = function (name, type) { | ||
var info = this.getBindingInfo(name); | ||
if (!info) return; | ||
this.clearOwnBinding(oldName); | ||
scope.bindings[newName] = info; | ||
info.identifier.typeAnnotation = info.typeAnnotation = type; | ||
}; | ||
Scope.prototype.getTypeAnnotation = function (name, id, node) { | ||
var info = { | ||
annotation: null, | ||
inferred: false | ||
binding.name = newName; | ||
}; | ||
var type; | ||
Scope.prototype.inferType = function inferType(node) { | ||
var target; | ||
if (id.typeAnnotation) { | ||
type = id.typeAnnotation; | ||
} | ||
if (t.isVariableDeclarator(node)) { | ||
target = node.init; | ||
} | ||
if (!type) { | ||
info.inferred = true; | ||
type = this.inferType(node); | ||
} | ||
if (t.isArrayExpression(target)) { | ||
return t.genericTypeAnnotation(t.identifier("Array")); | ||
} | ||
if (type) { | ||
if (t.isTypeAnnotation(type)) type = type.typeAnnotation; | ||
info.annotation = type; | ||
} | ||
if (t.isObjectExpression(target)) { | ||
return; | ||
} | ||
return info; | ||
}; | ||
if (t.isLiteral(target)) { | ||
return; | ||
} | ||
Scope.prototype.toArray = function (node, i) { | ||
var file = this.file; | ||
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(node) && this.isTypeGeneric(node.name, "Array")) { | ||
return node; | ||
} | ||
if (t.isIdentifier(target)) { | ||
return; | ||
} | ||
}; | ||
if (t.isArrayExpression(node)) { | ||
return node; | ||
} | ||
Scope.prototype.isTypeGeneric = function isTypeGeneric(name, genericName) { | ||
var info = this.getBindingInfo(name); | ||
if (!info) return false; | ||
if (t.isIdentifier(node, { name: "arguments" })) { | ||
return t.callExpression(t.memberExpression(file.addHelper("slice"), t.identifier("call")), [node]); | ||
} | ||
var type = info.typeAnnotation; | ||
return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName }); | ||
}; | ||
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.assignTypeGeneric = function assignTypeGeneric(name, type) { | ||
this.assignType(name, t.genericTypeAnnotation(t.identifier(type))); | ||
}; | ||
Scope.prototype.clearOwnBinding = function (name) { | ||
delete this.bindings[name]; | ||
}; | ||
Scope.prototype.assignType = function assignType(name, type) { | ||
var info = this.getBindingInfo(name); | ||
if (!info) return; | ||
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); | ||
} | ||
}; | ||
info.identifier.typeAnnotation = info.typeAnnotation = type; | ||
}; | ||
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; | ||
Scope.prototype.getTypeAnnotation = function getTypeAnnotation(name, id, node) { | ||
var info = { | ||
annotation: null, | ||
inferred: false | ||
}; | ||
if (info.typeAnnotationInferred) { | ||
// destroy the inferred typeAnnotation | ||
info.typeAnnotation = null; | ||
} | ||
var type; | ||
if (id.typeAnnotation) { | ||
type = id.typeAnnotation; | ||
} | ||
} | ||
}; | ||
Scope.prototype.registerBinding = function (kind, node) { | ||
if (!kind) throw new ReferenceError("no `kind`"); | ||
if (!type) { | ||
info.inferred = true; | ||
type = this.inferType(node); | ||
} | ||
var ids = t.getBindingIdentifiers(node); | ||
if (type) { | ||
if (t.isTypeAnnotation(type)) type = type.typeAnnotation; | ||
info.annotation = type; | ||
} | ||
for (var name in ids) { | ||
var id = ids[name]; | ||
return info; | ||
}; | ||
this.checkBlockScopedCollisions(kind, name, id); | ||
Scope.prototype.toArray = function toArray(node, i) { | ||
var file = this.file; | ||
var typeInfo = this.getTypeAnnotation(name, id, node); | ||
if (t.isIdentifier(node) && this.isTypeGeneric(node.name, "Array")) { | ||
return node; | ||
} | ||
this.bindings[name] = { | ||
typeAnnotationInferred: typeInfo.inferred, | ||
typeAnnotation: typeInfo.annotation, | ||
reassigned: false, | ||
identifier: id, | ||
scope: this, | ||
node: node, | ||
kind: kind | ||
}; | ||
} | ||
}; | ||
if (t.isArrayExpression(node)) { | ||
return node; | ||
} | ||
Scope.prototype.registerVariableDeclaration = function (declar) { | ||
var declars = declar.declarations; | ||
for (var i = 0; i < declars.length; i++) { | ||
this.registerBinding(declars[i], declar.kind); | ||
} | ||
}; | ||
if (t.isIdentifier(node, { name: "arguments" })) { | ||
return t.callExpression(t.memberExpression(file.addHelper("slice"), t.identifier("call")), [node]); | ||
} | ||
var functionVariableVisitor = { | ||
enter: function enter(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); | ||
}); | ||
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); | ||
}; | ||
// 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(); | ||
Scope.prototype.clearOwnBinding = function clearOwnBinding(name) { | ||
delete this.bindings[name]; | ||
}; | ||
// function identifier doesn't belong to this scope | ||
if (state.blockId && node === state.blockId) return; | ||
Scope.prototype.registerDeclaration = function registerDeclaration(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); | ||
} | ||
}; | ||
// delegate block scope handling to the `blockVariableVisitor` | ||
if (t.isBlockScoped(node)) return; | ||
Scope.prototype.registerBindingReassignment = function registerBindingReassignment(node) { | ||
var ids = t.getBindingIdentifiers(node); | ||
for (var name in ids) { | ||
var info = this.getBindingInfo(name); | ||
if (info) { | ||
info.reassigned = true; | ||
// this will be hit again once we traverse into it after this iteration | ||
if (t.isExportDeclaration(node) && t.isDeclaration(node.declaration)) return; | ||
if (info.typeAnnotationInferred) { | ||
// destroy the inferred typeAnnotation | ||
info.typeAnnotation = null; | ||
} | ||
} | ||
} | ||
}; | ||
// we've ran into a declaration! | ||
if (t.isDeclaration(node)) state.scope.registerDeclaration(node); | ||
} | ||
}; | ||
Scope.prototype.registerBinding = function registerBinding(kind, node) { | ||
if (!kind) throw new ReferenceError("no `kind`"); | ||
Scope.prototype.addGlobal = function (node) { | ||
this.globals[node.name] = node; | ||
}; | ||
var ids = t.getBindingIdentifiers(node); | ||
Scope.prototype.hasGlobal = function (name) { | ||
var scope = this; | ||
for (var name in ids) { | ||
var id = ids[name]; | ||
do { | ||
if (scope.globals[name]) return true; | ||
} while (scope = scope.parent); | ||
this.checkBlockScopedCollisions(kind, name, id); | ||
return false; | ||
}; | ||
var typeInfo = this.getTypeAnnotation(name, id, node); | ||
var programReferenceVisitor = { | ||
enter: function enter(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); | ||
this.bindings[name] = { | ||
typeAnnotationInferred: typeInfo.inferred, | ||
typeAnnotation: typeInfo.annotation, | ||
reassigned: false, | ||
identifier: id, | ||
scope: this, | ||
node: node, | ||
kind: kind | ||
}; | ||
} | ||
} | ||
}; | ||
}; | ||
var blockVariableVisitor = { | ||
enter: function enter(node, parent, scope, state) { | ||
if (t.isFunctionDeclaration(node) || t.isBlockScoped(node)) { | ||
state.registerDeclaration(node); | ||
} else if (t.isScope(node, parent)) { | ||
this.skip(); | ||
Scope.prototype.registerVariableDeclaration = function registerVariableDeclaration(declar) { | ||
var declars = declar.declarations; | ||
for (var i = 0; i < declars.length; i++) { | ||
this.registerBinding(declars[i], declar.kind); | ||
} | ||
} | ||
}; | ||
}; | ||
Scope.prototype.crawl = function () { | ||
var block = this.block; | ||
var i; | ||
Scope.prototype.addGlobal = function addGlobal(node) { | ||
this.globals[node.name] = node; | ||
}; | ||
// | ||
Scope.prototype.hasGlobal = function hasGlobal(name) { | ||
var scope = this; | ||
var info = block._scopeInfo; | ||
if (info) { | ||
extend(this, info); | ||
return; | ||
} | ||
do { | ||
if (scope.globals[name]) return true; | ||
} while (scope = scope.parent); | ||
info = block._scopeInfo = { | ||
bindings: object(), | ||
globals: object() | ||
return false; | ||
}; | ||
extend(this, info); | ||
Scope.prototype.crawl = function crawl() { | ||
var block = this.block; | ||
var i; | ||
// 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); | ||
var info = block._scopeInfo; | ||
if (info) { | ||
extend(this, info); | ||
return; | ||
} | ||
if (t.isBlockStatement(block.body)) { | ||
block = block.body; | ||
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 | ||
// FunctionExpression - id | ||
if (t.isFunctionExpression(block) && block.id) { | ||
if (!t.isProperty(this.parentBlock, { method: true })) { | ||
this.registerBinding("var", block.id); | ||
if (t.isFunctionExpression(block) && block.id) { | ||
if (!t.isProperty(this.parentBlock, { method: true })) { | ||
this.registerBinding("var", block.id); | ||
} | ||
} | ||
} | ||
// Function - params, rest | ||
// Function - params, rest | ||
if (t.isFunction(block)) { | ||
for (i = 0; i < block.params.length; i++) { | ||
this.registerBinding("param", block.params[i]); | ||
if (t.isFunction(block)) { | ||
for (i = 0; i < block.params.length; i++) { | ||
this.registerBinding("param", block.params[i]); | ||
} | ||
this.traverse(block.body, blockVariableVisitor, this); | ||
} | ||
this.traverse(block.body, blockVariableVisitor, this); | ||
} | ||
// Program, BlockStatement, Function - let variables | ||
// Program, BlockStatement, Function - let variables | ||
if (t.isBlockStatement(block) || t.isProgram(block)) { | ||
this.traverse(block, blockVariableVisitor, this); | ||
} | ||
if (t.isBlockStatement(block) || t.isProgram(block)) { | ||
this.traverse(block, blockVariableVisitor, this); | ||
} | ||
// CatchClause - param | ||
// CatchClause - param | ||
if (t.isCatchClause(block)) { | ||
this.registerBinding("let", block.param); | ||
} | ||
if (t.isCatchClause(block)) { | ||
this.registerBinding("let", block.param); | ||
} | ||
// ComprehensionExpression - blocks | ||
// ComprehensionExpression - blocks | ||
if (t.isComprehensionExpression(block)) { | ||
this.registerBinding("let", block); | ||
} | ||
if (t.isComprehensionExpression(block)) { | ||
this.registerBinding("let", block); | ||
} | ||
// Program, Function - var variables | ||
// Program, Function - var variables | ||
if (t.isProgram(block) || t.isFunction(block)) { | ||
this.traverse(block, functionVariableVisitor, { | ||
blockId: block.id, | ||
scope: this | ||
}); | ||
} | ||
if (t.isProgram(block) || t.isFunction(block)) { | ||
this.traverse(block, functionVariableVisitor, { | ||
blockId: block.id, | ||
scope: this | ||
}); | ||
} | ||
// Program | ||
// Program | ||
if (t.isProgram(block)) { | ||
this.traverse(block, programReferenceVisitor, this); | ||
} | ||
}; | ||
if (t.isProgram(block)) { | ||
this.traverse(block, programReferenceVisitor, this); | ||
} | ||
}; | ||
/** | ||
* Description | ||
* | ||
* @param {Object} opts | ||
*/ | ||
/** | ||
* Description | ||
* | ||
* @param {Object} opts | ||
*/ | ||
Scope.prototype.push = function (opts) { | ||
var block = this.block; | ||
Scope.prototype.push = function push(opts) { | ||
var block = this.block; | ||
if (t.isLoop(block) || t.isCatchClause(block) || t.isFunction(block)) { | ||
t.ensureBlock(block); | ||
block = block.body; | ||
} | ||
if (t.isLoop(block) || t.isCatchClause(block) || t.isFunction(block)) { | ||
t.ensureBlock(block); | ||
block = block.body; | ||
} | ||
if (t.isBlockStatement(block) || t.isProgram(block)) { | ||
var _block = block; | ||
if (!_block._declarations) _block._declarations = {}; | ||
if (t.isBlockStatement(block) || t.isProgram(block)) { | ||
var _block = block; | ||
if (!_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); | ||
} | ||
}; | ||
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. | ||
*/ | ||
/** | ||
* 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; | ||
}; | ||
Scope.prototype.getFunctionParent = function getFunctionParent() { | ||
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} | ||
*/ | ||
/** | ||
* Walks the scope tree and gathers **all** bindings. | ||
* | ||
* @returns {Object} | ||
*/ | ||
Scope.prototype.getAllBindings = function () { | ||
var ids = object(); | ||
Scope.prototype.getAllBindings = function getAllBindings() { | ||
var ids = object(); | ||
var scope = this; | ||
do { | ||
defaults(ids, scope.bindings); | ||
scope = scope.parent; | ||
} while (scope); | ||
var scope = this; | ||
do { | ||
defaults(ids, scope.bindings); | ||
scope = scope.parent; | ||
} while (scope); | ||
return ids; | ||
}; | ||
return ids; | ||
}; | ||
/** | ||
* Walks the scope tree and gathers all declarations of `kind`. | ||
* | ||
* @param {String} kind | ||
* @returns {Object} | ||
*/ | ||
/** | ||
* Walks the scope tree and gathers all declarations of `kind`. | ||
* | ||
* @param {String} kind | ||
* @returns {Object} | ||
*/ | ||
Scope.prototype.getAllBindingsOfKind = function (kind) { | ||
var ids = object(); | ||
Scope.prototype.getAllBindingsOfKind = function getAllBindingsOfKind(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); | ||
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; | ||
}; | ||
return ids; | ||
}; | ||
// misc | ||
// misc | ||
Scope.prototype.bindingIdentifierEquals = function (name, node) { | ||
return this.getBindingIdentifier(name) === node; | ||
}; | ||
Scope.prototype.bindingIdentifierEquals = function bindingIdentifierEquals(name, node) { | ||
return this.getBindingIdentifier(name) === node; | ||
}; | ||
// get | ||
// get | ||
Scope.prototype.getBindingInfo = function (name) { | ||
var scope = this; | ||
Scope.prototype.getBindingInfo = function getBindingInfo(name) { | ||
var scope = this; | ||
do { | ||
var binding = scope.getOwnBindingInfo(name); | ||
if (binding) return binding; | ||
} while (scope = scope.parent); | ||
}; | ||
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.getOwnBindingInfo = function getOwnBindingInfo(name) { | ||
return this.bindings[name]; | ||
}; | ||
Scope.prototype.getBindingIdentifier = function (name) { | ||
var info = this.getBindingInfo(name); | ||
return info && info.identifier; | ||
}; | ||
Scope.prototype.getBindingIdentifier = function getBindingIdentifier(name) { | ||
var info = this.getBindingInfo(name); | ||
return info && info.identifier; | ||
}; | ||
Scope.prototype.getOwnBindingIdentifier = function (name) { | ||
var binding = this.bindings[name]; | ||
return binding && binding.identifier; | ||
}; | ||
Scope.prototype.getOwnBindingIdentifier = function getOwnBindingIdentifier(name) { | ||
var binding = this.bindings[name]; | ||
return binding && binding.identifier; | ||
}; | ||
// has | ||
// has | ||
Scope.prototype.hasOwnBinding = function (name) { | ||
return !!this.getOwnBindingInfo(name); | ||
}; | ||
Scope.prototype.hasOwnBinding = function hasOwnBinding(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.hasBinding = function hasBinding(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); | ||
}; | ||
Scope.prototype.parentHasBinding = function parentHasBinding(name) { | ||
return this.parent && this.parent.hasBinding(name); | ||
}; | ||
return Scope; | ||
})(); | ||
module.exports = Scope; |
{ | ||
"name": "babel", | ||
"description": "Turn ES6 code into readable vanilla ES5 with source maps", | ||
"version": "4.5.4", | ||
"version": "4.5.5", | ||
"author": "Sebastian McKenzie <sebmck@gmail.com>", | ||
@@ -6,0 +6,0 @@ "homepage": "https://babeljs.io/", |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1666399
13429