We have a conclusion that codegen will print whatever is in the AST,
instead of having an option to enable printing TypeScript syntax. I plan
to remove codegen's `enable_typescript` option after we strip out all
typescript AST in the transformer typescript plugin.
---------
Co-authored-by: Boshen <boshenc@gmail.com>
I've replaced the `BasicBlockElement` with an `Instruction` type which would keep both the instruction kind and its associated AstNodeId.
I also removed the register scheme in the control flow in favor of a simpler approach using explicit enums.
https://github.com/oxc-project/oxc/pull/3381#issuecomment-2126622774
The `@jsx: react` is a typescript option. The `Babel` typescript plugin handles @jsx as well, but this is different. `@jsx` in babel is a [pragma](https://babeljs.io/docs/babel-plugin-transform-react-jsx#pragma) option. So we should use code without these meta options to avoid Babel parsing `@jsx` incorrectly
Fix a small bug in React JSX transform. If `import_source` is invalid, the default value `"react"` is used for JSX runtime imports. But for importing React alone, it was still using the old invalid value.
This also allowed removing `ReactOptions` from `Bindings` and just storing `is_development` instead.
Correct spans in output of React JSX transform, so it should produce correct source maps.
Have copied which AST nodes have spans and which don't from Babel.
React JSX transform contains some confusing logic (ported directly from Babel) where in automatic mode, imports are inserted in one place, and then used in another.
Logic for which imports are needed is duplicated in both places, and it's hard to figure out whether they're in sync or not (I don't think they are in all cases).
This PR unifies the logic in one place. Imports are now added as and when they're used.
The `Bindings` enum is responsible for creating imports and also holds the state of which "mode" the plugin is working in:
1. Classic
2. Automatic script
3. Automatic module
Combining the two choices classic/automatic and script/module into a single enum:
1. clarifies the logic
2. reduces branching
3. reduces lookups on `ReactJsx::options` (which is behind an `Rc` and therefore costly to read from).
Validate React JSX `pragma` and `pragma_frag` options. Don't allow:
* empty string
* `foo.bar.qux`
* `foo.`
* `.bar`
* `.`
If options provided are invalid, raise an error and use the defaults.
Also fast path the defaults.
Due to needing to align output with Babel, React JSX transform has to
perform imports for fragments after dealing with the fragments'
children.
Transform generates a dummy identifier initially, and then generates a
UID later on and replaces the dummy.
The PR avoids that process 2-stage process unless we have to. If the UID
was already generated for a previous fragment, we can just use it
straight away.
Currently React JSX transform in classic mode with a custom
`options.pragma` value parses `options.pragma` on every JSX node, and
inserts new `Atom`s into arena every time.
This PR makes it parse `options.pragma` only once at the start of the
transform pass, and re-use the same `Atom`s for each JSX node.
Set `reference_id` for references to new imported bindings. e.g. `_jsx`
in `_jsx(Foo, {})` where JSX transform has inserted `import {jsx as
_jsx} from "react/jsx-runtime";`.
JSX transform set `symbol_id` on imported bindings. e.g. `_jsx` in `import {jsx as _jsx} from "react/jsx-runtime";`.
Setting matching `reference_id` on `IdentifierReference`s referring to the imports is not yet implemented.
React JSX transform was creating `CompactStr`s (which can involve heap allocations) and then converting them back to `Atom`s to insert into AST.
This PR removes the intermediate `CompactStr`s and allocates strings directly into the arena without intermediate heap allocations.
Previously new `Atom`s were generated and allocated into arena each time e.g. `_React` is used. This PR changes that to allocate each string into arena once only, and then re-use that same `Atom` over and over.
Re-use scope ID from `TSModuleDeclaration` for the scope of the function which replaces it in transformed output.
This should mean the scope tree is left in correct state after the transform.
NB: Still incomplete - we also need to transfer the binding ID from `X` in `namespace X {}` to `let X` in output.
We should not print typescript code as javascript code. Forcing to print as JavaScript code may result in syntax errors. If we truly want javascript code, we can use the `oxc_transformer`.