Skip to content

Calling path.skip() on a path that has been replaced with a replaceWith() (or other replace methods) does not skip the traversal. (T7117) #4098

@babel-bot

Description

@babel-bot

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();

Metadata

Metadata

Assignees

No one assigned

    Labels

    Has PRoutdatedA closed issue/PR that is archived due to age. Recommended to make a new issuepkg: traverse

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions