tsquery icon indicating copy to clipboard operation
tsquery copied to clipboard

Duplicate nodes getting added to ancestors array in traverse

Open cbranch101 opened this issue 11 months ago • 2 comments
trafficstars

When I run the following sample code

    const content = `export const ComponentName = () => {}`;
    // this is just calling ts.createSourceFile
    const ast = parseContents(content, "/test");
    traverse(ast, (node, ancestors) => {
      const ancestorTypes = ancestors.map((a) => SyntaxKind[a.kind]);
      console.log({
        node: SyntaxKind[node.kind],
        ancestors: ancestorTypes,
      });
    });

When processing the VariableDeclaration node, I get the following console log { node: 'VariableDeclaration', ancestors: [ 'VariableDeclarationList', 'VariableDeclarationList', 'FirstStatement', 'SourceFile', 'SourceFile' ] }

The issue seems to be related to the handling of nodes that have SyntaxList children. I think the issue is this code in traverse in particular

  if (node.parent != null) {
    ancestors.unshift(node.parent);
  }

It seems like SyntaxList's parent isn't being assigned correctly, so that step allows the same node to get added twice. This in turn, makes a query like SourceFile > VariableStatement > VariableDeclarationList > VariableDeclaration impossible, where as, for some reason, VariableDeclarationList > VariableDeclaration does work.

I fixed this locally just by adding a duplicate check to traverse, but I am concerned this might introduce issues else where.

  if (node.parent != null && ancestors[0] !== node.parent) {
    ancestors.unshift(node.parent);
  }

cbranch101 avatar Dec 10 '24 21:12 cbranch101

Has a quick look - would you mind checking if changing:

if (node.parent != null) {
  ancestors.unshift(node.parent);
}
iterator(node, ancestors);
let children: Array<Node> = [];

to:

iterator(node, ancestors);
let children: Array<Node> = [];
ancestors.unshift(node.parent);

Fixes your issue as well? Seems like if there are multiple children for one node, then it can add the item to ancestors multiple times which doesn't really make sense!

phenomnomnominal avatar Dec 11 '24 10:12 phenomnomnominal

Ah yep, that also fixes it, good call

cbranch101 avatar Dec 11 '24 13:12 cbranch101