Issue originally made by @brenmar
Bug information
- Babel version: 6.5.2
- Node version: 4.3.1
Description
calling path.skip() on a path that has been replaced with a replaceWith() method does not skip the traversal, and the traversal continues, this can lead to infinite recursion of the replaced nodes or visiting nodes that should be being skipped.
The simple code example below illustrates this.
import * as t from 'babel-types'
import traverse from 'babel-traverse'
import generate from 'babel-generator'
import * as babylon from 'babylon'
function skipReplacementBug() {
let ast = babylon.parse('id + id');
traverse(ast, {
noScope: true,
Identifier(path) {
// if this if check is removed traversal will infinitely recurse until call stack size exceeded as it doesn't skip
if (path.node.name === 'id') {
console.log('replacing identifier');
path.replaceWith(t.memberExpression(t.identifier('owner'), t.identifier('member')));
path.skip();
}
},
MemberExpression(path) {
console.log('should not reach this but it does as replacement is not being skipped...');
}
});
console.log(generate(ast).code);
}
skipReplacementBug();
Bug information
Description
calling path.skip() on a path that has been replaced with a replaceWith() method does not skip the traversal, and the traversal continues, this can lead to infinite recursion of the replaced nodes or visiting nodes that should be being skipped.
The simple code example below illustrates this.