benjamn / recast

JavaScript syntax tree transformer, nondestructive pretty-printer, and automatic source map generator
MIT License
4.99k stars 349 forks source link

Strange not not found error #1261

Closed iliakan closed 1 year ago

iliakan commented 1 year ago

Hello,

Could you please explain, how's that possible?

source.nodes().at(0).program.body.at(0).body.body.at(0).body.body.at(0).expression.arguments.at(0).arguments.at(0).params.at(0).typeAnnotation.typeAnnotation.elementTypes[1].type
'TSTypeReference'

source.find(jscodeshift.TSTypeReference).length
0

In other words, I can access the node, but it's not found. WAT? 😮

Here's the code:

class SelectedFiltersComponent {
  public ngOnInit(): void {
    combineLatest()
      .pipe(
        map(([data, selectedData]: [IFilterData, IFilterParams]) => {
          return items;
        }),
      )
  }
}

As you can see, there're at least two TypeReference nodes IFilterData and IFilterParams, but for some reason they're not found.

benjamn commented 1 year ago

@iliakan Can you try npm i recast@next?

iliakan commented 1 year ago

It's with recast@next ;)

iliakan commented 1 year ago

I thought... Maybe there's a limitation inside find... Such as it doesn't go into some types of nodes...

iliakan commented 1 year ago

@benjamn Also, here it can't find IPaginatedItems.

Tried to make it as simple as possible. May be related.

export class A {

  public test: () => void = () =>

      pluck<IPaginatedItems>('data')

}
eventualbuddha commented 1 year ago

This looks like a bug in jscodeshift. Using recast and @babel/core visits those nodes just fine:

import { transform } from '@codemod/core';

const sources = [`
  class SelectedFiltersComponent {
      public ngOnInit(): void {
        combineLatest()
          .pipe(
            map(([data, selectedData]: [IFilterData, IFilterParams]) => {
              return items;
            }),
          )
      }
    }
`,
`
  export class A {

    public test: () => void = () =>

        pluck<IPaginatedItems>('data')

  }
`
];

for (const source of sources) {
  transform(source, {
    plugins: [
      {
        visitor: {
          TSTypeReference(path) {
            // prints:
            //   IFilterData
            //   IFilterParams
            //   IPaginatedItems
            console.log(source.slice(path.node.start, path.node.end));
          }
        }
      }
    ],
  });
}