regenerator
Advanced tools
Comparing version 0.4.9 to 0.4.10
@@ -735,8 +735,9 @@ /** | ||
types.traverse(bodyPath, function(node) { | ||
if (n.Identifier.check(node) && | ||
node.name === catchParamName && | ||
this.scope.lookup(catchParamName) === catchScope) { | ||
this.replace(safeParam); | ||
return false; | ||
types.visit(bodyPath, { | ||
visitIdentifier: function(path) { | ||
if (path.value.name === catchParamName && | ||
path.scope.lookup(catchParamName) === catchScope) { | ||
return safeParam; | ||
} | ||
this.traverse(path); | ||
} | ||
@@ -743,0 +744,0 @@ }); |
@@ -52,11 +52,11 @@ /** | ||
types.traverse(funPath.get("body"), function(node) { | ||
if (n.VariableDeclaration.check(node)) { | ||
var expr = varDeclToExpr(node, false); | ||
types.visit(funPath.get("body"), { | ||
visitVariableDeclaration: function(path) { | ||
var expr = varDeclToExpr(path.value, false); | ||
if (expr === null) { | ||
this.replace(); | ||
path.replace(); | ||
} else { | ||
// We don't need to traverse this expression any further because | ||
// there can't be any new declarations inside an expression. | ||
this.replace(b.expressionStatement(expr)); | ||
return b.expressionStatement(expr); | ||
} | ||
@@ -67,19 +67,25 @@ | ||
return false; | ||
}, | ||
} else if (n.ForStatement.check(node)) { | ||
if (n.VariableDeclaration.check(node.init)) { | ||
var expr = varDeclToExpr(node.init, false); | ||
this.get("init").replace(expr); | ||
visitForStatement: function(path) { | ||
var init = path.value.init; | ||
if (n.VariableDeclaration.check(init)) { | ||
path.get("init").replace(varDeclToExpr(init, false)); | ||
} | ||
this.traverse(path); | ||
}, | ||
} else if (n.ForInStatement.check(node)) { | ||
if (n.VariableDeclaration.check(node.left)) { | ||
var expr = varDeclToExpr(node.left, true); | ||
this.get("left").replace(expr); | ||
visitForInStatement: function(path) { | ||
var left = path.value.left; | ||
if (n.VariableDeclaration.check(left)) { | ||
path.get("left").replace(varDeclToExpr(left, true)); | ||
} | ||
this.traverse(path); | ||
}, | ||
} else if (n.FunctionDeclaration.check(node)) { | ||
visitFunctionDeclaration: function(path) { | ||
var node = path.value; | ||
vars[node.id.name] = node.id; | ||
var parentNode = this.parent.node; | ||
var parentNode = path.parent.node; | ||
var assignment = b.expressionStatement( | ||
@@ -99,16 +105,10 @@ b.assignmentExpression( | ||
if (n.BlockStatement.check(this.parent.node)) { | ||
// Note that the function declaration we want to remove might be | ||
// the same node that firstStmtPath refers to, in case the | ||
// function declaration was already the first statement in the | ||
// enclosing block statement. | ||
var firstStmtPath = this.parent.get("body", 0); | ||
if (n.BlockStatement.check(path.parent.node)) { | ||
// Insert the assignment form before the first statement in the | ||
// enclosing block. | ||
firstStmtPath.replace(assignment, firstStmtPath.value); | ||
path.parent.get("body").unshift(assignment); | ||
// Remove the function declaration now that we've inserted the | ||
// equivalent assignment form at the beginning of the block. | ||
this.replace(); | ||
path.replace(); | ||
@@ -119,3 +119,3 @@ } else { | ||
// without worrying about hoisting it. | ||
this.replace(assignment); | ||
path.replace(assignment); | ||
} | ||
@@ -125,4 +125,5 @@ | ||
return false; | ||
}, | ||
} else if (n.FunctionExpression.check(node)) { | ||
visitFunctionExpression: function(path) { | ||
// Don't descend into nested function expressions. | ||
@@ -129,0 +130,0 @@ return false; |
381
lib/visit.js
@@ -22,37 +22,3 @@ /** | ||
exports.transform = function(node) { | ||
function postOrderTraverse(path) { | ||
assert.ok(path instanceof NodePath); | ||
var value = path.value; | ||
if (isArray.check(value)) { | ||
path.each(postOrderTraverse); | ||
return; | ||
} | ||
if (!isObject.check(value)) { | ||
return; | ||
} | ||
types.eachField(value, function(name, child) { | ||
var childPath = path.get(name); | ||
if (childPath.value !== child) { | ||
childPath.replace(child); | ||
} | ||
postOrderTraverse(childPath); | ||
}); | ||
if (n.Node.check(value)) { | ||
visitForOfStatement.call(path, value, postOrderTraverse); | ||
visitNode.call(path, value, postOrderTraverse); | ||
} | ||
} | ||
if (node instanceof NodePath) { | ||
postOrderTraverse(node); | ||
return node.value; | ||
} | ||
var rootPath = new NodePath({ root: node }); | ||
postOrderTraverse(rootPath.get("root")); | ||
return rootPath.value.root; | ||
return types.visit(node, visitor); | ||
}; | ||
@@ -68,78 +34,85 @@ | ||
function visitNode(node) { | ||
if (!n.Function.check(node) || !node.generator) { | ||
// Note that because we are not returning false here the traversal | ||
// will continue into the subtree rooted at this node, as desired. | ||
return; | ||
} | ||
var visitor = types.PathVisitor.fromMethodsObject({ | ||
visitFunction: function(path) { | ||
// Calling this.traverse(path) first makes for a post-order traversal. | ||
this.traverse(path); | ||
node.generator = false; | ||
var node = path.value; | ||
if (node.expression) { | ||
// Transform expression lambdas into normal functions. | ||
node.expression = false; | ||
node.body = b.blockStatement([ | ||
b.returnStatement(node.body) | ||
]); | ||
} | ||
if (!node.generator) { | ||
return; | ||
} | ||
// TODO Ensure $callee is not the name of any hoisted variable. | ||
var outerFnId = node.id || (node.id = b.identifier("$callee")); | ||
var innerFnId = b.identifier(node.id.name + "$"); | ||
node.generator = false; | ||
// TODO Ensure these identifiers are named uniquely. | ||
var contextId = makeContextId(); | ||
var argsId = b.identifier("$args"); | ||
var wrapGeneratorId = b.identifier("wrapGenerator"); | ||
var shouldAliasArguments = renameArguments(this, argsId); | ||
var vars = hoist(this); | ||
if (node.expression) { | ||
// Transform expression lambdas into normal functions. | ||
node.expression = false; | ||
node.body = b.blockStatement([ | ||
b.returnStatement(node.body) | ||
]); | ||
} | ||
if (shouldAliasArguments) { | ||
vars = vars || b.variableDeclaration("var", []); | ||
vars.declarations.push(b.variableDeclarator( | ||
argsId, b.identifier("arguments") | ||
)); | ||
} | ||
// TODO Ensure $callee is not the name of any hoisted variable. | ||
var outerFnId = node.id || (node.id = b.identifier("$callee")); | ||
var innerFnId = b.identifier(node.id.name + "$"); | ||
var emitter = new Emitter(contextId); | ||
emitter.explode(this.get("body")); | ||
// TODO Ensure these identifiers are named uniquely. | ||
var contextId = makeContextId(); | ||
var argsId = b.identifier("$args"); | ||
var wrapGeneratorId = b.identifier("wrapGenerator"); | ||
var shouldAliasArguments = renameArguments(path, argsId); | ||
var vars = hoist(path); | ||
var outerBody = []; | ||
if (shouldAliasArguments) { | ||
vars = vars || b.variableDeclaration("var", []); | ||
vars.declarations.push(b.variableDeclarator( | ||
argsId, b.identifier("arguments") | ||
)); | ||
} | ||
if (vars && vars.declarations.length > 0) { | ||
outerBody.push(vars); | ||
} | ||
var emitter = new Emitter(contextId); | ||
emitter.explode(path.get("body")); | ||
var wrapGenArgs = [ | ||
emitter.getContextFunction(innerFnId), | ||
outerFnId, | ||
b.thisExpression() | ||
]; | ||
var outerBody = []; | ||
var tryEntryList = emitter.getTryEntryList(); | ||
if (tryEntryList) { | ||
wrapGenArgs.push(tryEntryList); | ||
} | ||
if (vars && vars.declarations.length > 0) { | ||
outerBody.push(vars); | ||
} | ||
outerBody.push(b.returnStatement( | ||
b.callExpression(wrapGeneratorId, wrapGenArgs) | ||
)); | ||
var wrapGenArgs = [ | ||
emitter.getContextFunction(innerFnId), | ||
outerFnId, | ||
b.thisExpression() | ||
]; | ||
node.body = b.blockStatement(outerBody); | ||
var tryEntryList = emitter.getTryEntryList(); | ||
if (tryEntryList) { | ||
wrapGenArgs.push(tryEntryList); | ||
} | ||
var markMethod = b.memberExpression( | ||
wrapGeneratorId, | ||
b.identifier("mark"), | ||
false | ||
); | ||
outerBody.push(b.returnStatement( | ||
b.callExpression(wrapGeneratorId, wrapGenArgs) | ||
)); | ||
if (n.FunctionDeclaration.check(node)) { | ||
var path = this.parent; | ||
node.body = b.blockStatement(outerBody); | ||
while (path && !(n.BlockStatement.check(path.value) || | ||
n.Program.check(path.value))) { | ||
path = path.parent; | ||
} | ||
var markMethod = b.memberExpression( | ||
wrapGeneratorId, | ||
b.identifier("mark"), | ||
false | ||
); | ||
if (path) { | ||
if (n.FunctionDeclaration.check(node)) { | ||
var pp = path.parent; | ||
while (pp && !(n.BlockStatement.check(pp.value) || | ||
n.Program.check(pp.value))) { | ||
pp = pp.parent; | ||
} | ||
if (!pp) { | ||
return; | ||
} | ||
// Here we turn the FunctionDeclaration into a named | ||
@@ -187,3 +160,3 @@ // FunctionExpression that will be assigned to a variable of the | ||
// FunctionExpression passed to wrapGenerator.mark. | ||
this.replace(); | ||
path.replace(); | ||
@@ -208,3 +181,3 @@ // Change the type of the function to be an expression instead of a | ||
var bodyPath = path.get("body"); | ||
var bodyPath = pp.get("body"); | ||
var bodyLen = bodyPath.value.length; | ||
@@ -215,3 +188,3 @@ | ||
if (!shouldNotHoistAbove(firstStmtPath)) { | ||
firstStmtPath.replace(varDecl, firstStmtPath.value); | ||
firstStmtPath.insertBefore(varDecl); | ||
return; | ||
@@ -221,10 +194,91 @@ } | ||
bodyPath.value.push(varDecl); | ||
bodyPath.push(varDecl); | ||
} else { | ||
n.FunctionExpression.assert(node); | ||
return b.callExpression(markMethod, [node]); | ||
} | ||
}, | ||
} else { | ||
n.FunctionExpression.assert(node); | ||
this.replace(b.callExpression(markMethod, [node])); | ||
visitForOfStatement: function(path) { | ||
this.traverse(path); | ||
var node = path.value; | ||
var tempIterId = path.scope.declareTemporary("t$"); | ||
var tempIterDecl = b.variableDeclarator( | ||
tempIterId, | ||
b.callExpression( | ||
b.memberExpression( | ||
b.identifier("wrapGenerator"), | ||
b.identifier("values"), | ||
false | ||
), | ||
[node.right] | ||
) | ||
); | ||
var tempInfoId = path.scope.declareTemporary("t$"); | ||
var tempInfoDecl = b.variableDeclarator(tempInfoId, null); | ||
var init = node.left; | ||
var loopId; | ||
if (n.VariableDeclaration.check(init)) { | ||
loopId = init.declarations[0].id; | ||
init.declarations.push(tempIterDecl, tempInfoDecl); | ||
} else { | ||
loopId = init; | ||
init = b.variableDeclaration("var", [ | ||
tempIterDecl, | ||
tempInfoDecl | ||
]); | ||
} | ||
n.Identifier.assert(loopId); | ||
var loopIdAssignExprStmt = b.expressionStatement( | ||
b.assignmentExpression( | ||
"=", | ||
loopId, | ||
b.memberExpression( | ||
tempInfoId, | ||
b.identifier("value"), | ||
false | ||
) | ||
) | ||
); | ||
if (n.BlockStatement.check(node.body)) { | ||
node.body.body.unshift(loopIdAssignExprStmt); | ||
} else { | ||
node.body = b.blockStatement([ | ||
loopIdAssignExprStmt, | ||
node.body | ||
]); | ||
} | ||
return b.forStatement( | ||
init, | ||
b.unaryExpression( | ||
"!", | ||
b.memberExpression( | ||
b.assignmentExpression( | ||
"=", | ||
tempInfoId, | ||
b.callExpression( | ||
b.memberExpression( | ||
tempIterId, | ||
b.identifier("next"), | ||
false | ||
), | ||
[] | ||
) | ||
), | ||
b.identifier("done"), | ||
false | ||
) | ||
), | ||
null, | ||
node.body | ||
); | ||
} | ||
} | ||
}); | ||
@@ -266,20 +320,27 @@ function shouldNotHoistAbove(stmtPath) { | ||
types.traverse(funcPath, function(node) { | ||
if (node === func) { | ||
hasImplicitArguments = !this.scope.lookup("arguments"); | ||
} else if (n.Function.check(node)) { | ||
return false; | ||
} | ||
types.visit(funcPath, { | ||
visitFunction: function(path) { | ||
if (path.value === func) { | ||
hasImplicitArguments = !path.scope.lookup("arguments"); | ||
this.traverse(path); | ||
} else { | ||
return false; | ||
} | ||
}, | ||
if (n.Identifier.check(node) && node.name === "arguments") { | ||
var isMemberProperty = | ||
n.MemberExpression.check(this.parent.node) && | ||
this.name === "property" && | ||
!this.parent.node.computed; | ||
visitIdentifier: function(path) { | ||
if (path.value.name === "arguments") { | ||
var isMemberProperty = | ||
n.MemberExpression.check(path.parent.node) && | ||
path.name === "property" && | ||
!path.parent.node.computed; | ||
if (!isMemberProperty) { | ||
this.replace(argsId); | ||
didReplaceArguments = true; | ||
return false; | ||
if (!isMemberProperty) { | ||
path.replace(argsId); | ||
didReplaceArguments = true; | ||
return false; | ||
} | ||
} | ||
this.traverse(path); | ||
} | ||
@@ -293,85 +354,1 @@ }); | ||
} | ||
function visitForOfStatement(node, traversePath) { | ||
if (!n.ForOfStatement.check(node)) { | ||
return; | ||
} | ||
var tempIterId = this.scope.declareTemporary("t$"); | ||
var tempIterDecl = b.variableDeclarator( | ||
tempIterId, | ||
b.callExpression( | ||
b.memberExpression( | ||
b.identifier("wrapGenerator"), | ||
b.identifier("values"), | ||
false | ||
), | ||
[node.right] | ||
) | ||
); | ||
var tempInfoId = this.scope.declareTemporary("t$"); | ||
var tempInfoDecl = b.variableDeclarator(tempInfoId, null); | ||
var init = node.left; | ||
var loopId; | ||
if (n.VariableDeclaration.check(init)) { | ||
loopId = init.declarations[0].id; | ||
init.declarations.push(tempIterDecl, tempInfoDecl); | ||
} else { | ||
loopId = init; | ||
init = b.variableDeclaration("var", [ | ||
tempIterDecl, | ||
tempInfoDecl | ||
]); | ||
} | ||
n.Identifier.assert(loopId); | ||
var loopIdAssignExprStmt = b.expressionStatement( | ||
b.assignmentExpression( | ||
"=", | ||
loopId, | ||
b.memberExpression( | ||
tempInfoId, | ||
b.identifier("value"), | ||
false | ||
) | ||
) | ||
); | ||
if (n.BlockStatement.check(node.body)) { | ||
node.body.body.unshift(loopIdAssignExprStmt); | ||
} else { | ||
node.body = b.blockStatement([ | ||
loopIdAssignExprStmt, | ||
node.body | ||
]); | ||
} | ||
this.replace( | ||
b.forStatement( | ||
init, | ||
b.unaryExpression( | ||
"!", | ||
b.memberExpression( | ||
b.assignmentExpression( | ||
"=", | ||
tempInfoId, | ||
b.callExpression( | ||
b.memberExpression( | ||
tempIterId, | ||
b.identifier("next"), | ||
false | ||
), | ||
[] | ||
) | ||
), | ||
b.identifier("done"), | ||
false | ||
) | ||
), | ||
null, | ||
node.body | ||
) | ||
); | ||
} |
@@ -19,3 +19,3 @@ { | ||
], | ||
"version": "0.4.9", | ||
"version": "0.4.10", | ||
"homepage": "http://github.com/facebook/regenerator", | ||
@@ -34,4 +34,4 @@ "repository": { | ||
"esprima": "git://github.com/ariya/esprima.git#harmony", | ||
"recast": "~0.5.23", | ||
"private": "~0.1.2", | ||
"recast": "~0.6.2", | ||
"private": "~0.1.5", | ||
"defs": "~0.6.2" | ||
@@ -38,0 +38,0 @@ }, |
Sorry, the diff of this file is not supported yet
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
2
0
82653
17
2112
+ Addedast-types@0.4.13(transitive)
+ Addeddepd@1.0.1(transitive)
+ Addedrecast@0.6.10(transitive)
- Removedast-types@0.3.38(transitive)
- Removedrecast@0.5.27(transitive)
Updatedprivate@~0.1.5
Updatedrecast@~0.6.2