Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support JSX elements in TSX #415

Merged

Conversation

eyakubovich
Copy link
Contributor

  • Adds support for JSX elements: {expr} <Foo.Bar.Baz attr=val />

  • The grammar uses nested_identifier for tags in the Foo.Bar.Baz form. It's the same symbol as what's used in namespaces: namespace Foo.Bar.Baz {}

    As such it ends up producing a bit of junk (unconnected cliques) but I don't know if it can be fixed w/o tree sitter queries supporting matching only if under a specified ancestor.

  • Unlike JavaScript, TypeScript requires variables to be declared. In JSX, <foo attr={x = 1}> {y = 2} is allowed if x, y are not in scope. They'll be created on first use. In TSX, this is disallowed which simplifies lexical_scope propogation compared to the JS TSG implementation.

@eyakubovich eyakubovich requested a review from a team as a code owner March 14, 2024 19:11
Copy link
Collaborator

@hendrikvanantwerpen hendrikvanantwerpen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small remarks, but generally okay! Thanks for immediately adding comprehensive tests.

// ^ defined: 11
// ^ defined: 11

const el2 = <x></x>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with tsx, so this is a question for my understanding. The x here is a reference, but what about foo above? Is that an unresolved reference, or is it treated as a literal because it doesn't resolve to anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example, foo is an undefined reference. The spec doesn't seem to define much beyond the grammar: https://facebook.github.io/jsx/.

For TSX, the TS handbook also defines the rules around type checking: https://www.typescriptlang.org/docs/handbook/jsx.html#type-checking
Specifically, the element tags need to be declared inside some interfaces and also there are rules regarding tags staring with lower case and upper case.

- Adds support for JSX elements:
  <Foo attr=val>{expr}</Foo>
  <Foo.Bar.Baz attr=val />

- The grammar uses nested_identifier for tags in the
  Foo.Bar.Baz form. It's the same symbol as what's used
  in namespaces: namespace Foo.Bar.Baz {}

  As such it ends up producing a bit of junk (unconnected cliques)
  but I don't know if it can be fixed w/o tree sitter queries
  supporting matching only if under a specified ancestor.

- Unlike JavaScript, TypeScript requires variables to be declared.
  In JSX, <foo attr={x = 1}> {y = 2} </foo> is allowed if x, y are
  not in scope. They'll be created on first use. In TSX, this is
  disallowed which simplifies lexical_scope propogation compared to
  the JS TSG implementation.
Copy link
Collaborator

@hendrikvanantwerpen hendrikvanantwerpen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@hendrikvanantwerpen hendrikvanantwerpen merged commit a8c7109 into github:main Mar 15, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants