question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to skip child nodes

See original GitHub issue

Code:

var traverse = require("@babel/traverse").default;
var parser = require("@babel/parser");
var generate = require("@babel/generator").default;
var types = require("@babel/types");

var ast = parser.parse('{"abc";"123";}');
traverse(ast, {
  BlockStatement(path) {
    var p = path.get("body")[0];
    console.log("before", p.shouldSkip);
    p.skip();
    console.log("after", p.shouldSkip, path.get("body")[0].shouldSkip);
  },
  ExpressionStatement(path) {
    console.log(generate(path.node).code);
  }
});

return;

Output:

before false
after true false
"abc";
"123";

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
nicolo-ribaudocommented, Feb 16, 2020

This is definitely a bug. If you try to run this code in the monorepo:

const load = n => require(`./packages/babel-${n}`);
const babel = load("core");
const parser = load("parser");
const traverse = load("traverse").default;
const generate = load("generator").default;

const ast = parser.parse('{"abc";"123";}');
traverse(ast, {
  BlockStatement(path) {
    const p = path.get("body")[0];
    console.log("before", p.shouldSkip, path.get("body")[0] === p);
    p.skip();

    console.log("after 1", p.shouldSkip);
    path.get("body");
    console.log("after 2", p.shouldSkip);
  },
  ExpressionStatement(path) {
    console.log(generate(path.node).code);
  },
});

It will log after 1 true, after 1 false, but shouldSkip shouldn’t change from after 1 to after2.

1reaction
Domiiicommented, Aug 20, 2021

Skipping just does not work in general. Flags always get wiped before a visit, even without calling path.get in between:

Order of events

  1. Before some p gets visited, I call p.skip(). That in turn sets NodePath._traverseFlags
  2. Before p gets visited, setContext is called. Stacktrace looks like so:
    at NodePath.setContext (code\node_modules\@babel\traverse\lib\path\context.js:143:13)
    at NodePath.pushContext (code\node_modules\@babel\traverse\lib\path\context.js:219:8)
    at TraversalContext.visitQueue (code\node_modules\@babel\traverse\lib\context.js:89:14)
    at TraversalContext.visitSingle (code\node_modules\@babel\traverse\lib\context.js:73:19)
    at TraversalContext.visit (code\node_modules\@babel\traverse\lib\context.js:127:19)
    ...
    
  3. setContext unconditionally unsets _traverseFlags
  4. Skipped node still gets visited.

Thus skip will not work.

The only situation where skip can work is a partial skip; that is if you skip the node itself during its own enter call. In that case, enter was called but exit will not be called.

At this point I would like to ask point that it has been quite a while. Is there any news on this? NodePath.skip being straight-up broken looks quite bad. I know there are workarounds, but this is just a pretty obvious bug that requires fixing, if not at least acknowledgement.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to skip child node within parent node(Xpath)
I need to extract below text from parent tag div node excluding its child nodes: Software Quality Assurance & Testing Stack Exchange is...
Read more >
XmlReader.Skip skips the children of the current node. : XML ...
Skip skips the children of the current node. using System; using System.Xml; public class Sample { public static void Main() { using (XmlReader...
Read more >
Skip Child Element | Cypress examples (v9.7.0)
Remove child elements by selector​​ We need to get the "div#make" element's text, but without the text of the child element "span. picked"....
Read more >
first-child - CSS: Cascading Style Sheets - MDN Web Docs
The :first-child CSS pseudo-class represents the first element among a group of sibling elements. Try it. CSS Demo: :first-child. Reset.
Read more >
XmlReader.ReadToDescendant Method (System.Xml)
The namespace URI of the element you wish to move to. Returns. Boolean. true if a matching descendant element is found; otherwise false...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found