ast-grep-vscode icon indicating copy to clipboard operation
ast-grep-vscode copied to clipboard

[bug] incorrect AST for TSX

Open HugeLetters opened this issue 1 year ago • 13 comments
trafficstars

I'm having issues with the code in the playground below - I've tried to do a minimal repro but unfortunately couldn't really pinpoint the issue.

The problem is that this error does not appear in the playground. Yet when I use ast-grep TS API - it produces an incorrect AST. I also have the same issue when using VSCode extension - I'm using [email protected] image

⏯ Playground Link

Playground link

🙁 Actual behavior

The error is that searching for export default $A pattern produces no results - the issue seems to be with the const defined on line 18. Instead of being represented a single lexical declaration all its children nodes get dumped into the root node which causes AST eventually to report an error which prevents it from detecting a default export. I was able to pinpoint the issue to line 94 - if you remove all 3 & from the className the error disappears. But deleting everything below line 153 works too.

I could provide a repo link if that would help - this could be an issue with tsx gramar, not ast-grep but given that I have the error with API/VSCode extension but not in playground I would assume all of them use the same grammar and thus the issue is with ast-grep. If there's any other info I could provide please let me know

HugeLetters avatar Mar 21 '24 23:03 HugeLetters

Hi @HugeLetters , can you try the query

ast-grep -p 'export default $A' src/pages/scan.tsx 
# or
ast-grep -p 'export default $A' 

in your terminal?

Also, what's your extension version, OS and its version, VSCode version?

HerringtonDarkholme avatar Mar 22 '24 00:03 HerringtonDarkholme

@HerringtonDarkholme running the command also gives nothing. Btw I could fix the error by just wrapping className in {} so it's not a critical problem for me.

VSCode extension - @0.1.3 OS - Ubuntu 22.04.04 VSCode - 1.87.2

HugeLetters avatar Mar 22 '24 00:03 HugeLetters

Also using tree-sitter for node directly has the same issue so maybe the error is outside of ast-grep scope - I'm curious why it works in the playground though

HugeLetters avatar Mar 22 '24 00:03 HugeLetters

I do believe this is a tree-sitter problem.

This is the minimal reproduction I can give. @HugeLetters would you like to submit a ticket to tree-sitter-typescript? Thanks!

const Page = () => (
    <div
      className="relative isolate flex w-full touch-pan-y touch-pinch-zoom flex-col items-center justify-end gap-6 overflow-x-hidden px-10"
    >
      <div
        id={'13'}
        className="!absolute -z-10 flex size-full justify-center [&>video]:!w-auto [&>video]:max-w-none [&>video]:!shrink-0"
      />
    </div>
);
Page.x = {};

export default Page;

Deleting any tailwind class will invalidate the repro, curiously.

HerringtonDarkholme avatar Mar 22 '24 00:03 HerringtonDarkholme

@HerringtonDarkholme yeah, sure, I will submit it to them

Thanks to yours example I could trim down the repro to this

const A = () => (
  <>
    <d c="&>v]" />
  </>
);

export default A;

HugeLetters avatar Mar 22 '24 00:03 HugeLetters

I've tried to run this with tree-sitter CLI directly and it also doesn't have this problem :|

I'm not sure where I should submit this problem at this point

HugeLetters avatar Mar 22 '24 00:03 HugeLetters

Would you like to check the version of tre-sitter-typescript? ast-grep uses 0.20.5

HerringtonDarkholme avatar Mar 22 '24 00:03 HerringtonDarkholme

Yup, same

HugeLetters avatar Mar 22 '24 01:03 HugeLetters

this is what I got

(ERROR (identifier) parameters: (formal_parameters) (jsx_opening_element) (jsx_element open_tag: (jsx_opening_element name: (identifier) attribute: (jsx_attribute (property_identifier)) (ERROR)) (jsx_text) (ERROR) close_tag: (jsx_closing_element)) (jsx_text))

HerringtonDarkholme avatar Mar 22 '24 04:03 HerringtonDarkholme

@HugeLetters how are you using tree-sitter-typescript? I cannot figure out a way to run typescript-tsx instead of typescript. the tree-sitter parse only does the TS parse not tsx.

HerringtonDarkholme avatar Mar 22 '24 04:03 HerringtonDarkholme

I've tried to run this with tree-sitter CLI directly and it also doesn't have this problem :|

I'm pretty sure this is because you are using typescript instead of tsx.

Also using tree-sitter for node directly has the same issue so maybe the error is outside of ast-grep scope

the tree-sitter for node should reflect the correct usage.

HerringtonDarkholme avatar Mar 22 '24 04:03 HerringtonDarkholme

@HerringtonDarkholme

pnpm i -g tree-sitter-cli
pnpm i tree-sitter-typescript
cd ./node_modules/tree-sitter-typescript/tsx
tree-sitter build
tree-sitter parse ~/<path>/scan.tsx

outputs

(program [0, 0] - [7, 0]
  (lexical_declaration [0, 0] - [4, 2]
    (variable_declarator [0, 6] - [4, 1]
      name: (identifier [0, 6] - [0, 7])
      value: (arrow_function [0, 10] - [4, 1]
        parameters: (formal_parameters [0, 10] - [0, 12])
        body: (parenthesized_expression [0, 16] - [4, 1]
          (jsx_element [1, 2] - [3, 5]
            open_tag: (jsx_opening_element [1, 2] - [1, 4])
            (jsx_self_closing_element [2, 4] - [2, 18]
              name: (identifier [2, 5] - [2, 6])
              attribute: (jsx_attribute [2, 7] - [2, 15]
                (property_identifier [2, 7] - [2, 8])
                (string [2, 9] - [2, 15]
                  (string_fragment [2, 10] - [2, 14]))))
            close_tag: (jsx_closing_element [3, 2] - [3, 5]))))))
  (export_statement [6, 0] - [6, 17]
    value: (identifier [6, 15] - [6, 16])))

It looks close to the tree produced by ast-grep playground but there're some minor differences around the fragment opening and closing tags

HugeLetters avatar Mar 22 '24 12:03 HugeLetters

Tried to run it with typescript instead of tsx and I get a different errors from yours

(program [0, 0] - [7, 0]
  (lexical_declaration [0, 0] - [6, 17]
    (variable_declarator [0, 6] - [0, 7]
      name: (identifier [0, 6] - [0, 7]))
    (ERROR [0, 8] - [6, 16]
      parameters: (formal_parameters [0, 10] - [0, 12])
      (ERROR [1, 3] - [6, 14]
        (type_parameters [2, 4] - [3, 5]
          (ERROR [2, 5] - [2, 6]
            (identifier [2, 5] - [2, 6]))
          (type_parameter [2, 7] - [2, 15]
            name: (type_identifier [2, 7] - [2, 8])
            value: (default_type [2, 8] - [2, 15]
              (literal_type [2, 9] - [2, 15]
                (string [2, 9] - [2, 15]
                  (string_fragment [2, 10] - [2, 14])))))
          (ERROR [2, 16] - [3, 4])))
      (identifier [6, 15] - [6, 16]))))

HugeLetters avatar Mar 22 '24 12:03 HugeLetters