mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(transformer): start implementing react jsx transform (#1057)
This commit is contained in:
parent
94d3e28aac
commit
d8f1a7fce6
7 changed files with 255 additions and 58 deletions
|
|
@ -21,6 +21,10 @@ pub struct BooleanLiteral {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BooleanLiteral {
|
impl BooleanLiteral {
|
||||||
|
pub fn new(span: Span, value: bool) -> Self {
|
||||||
|
Self { span, value }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
if self.value {
|
if self.value {
|
||||||
"true"
|
"true"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use oxc_codegen::{Codegen, CodegenOptions};
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_semantic::SemanticBuilder;
|
use oxc_semantic::SemanticBuilder;
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
use oxc_transformer::{TransformOptions, TransformTarget, Transformer};
|
use oxc_transformer::{ReactJsxOptions, TransformOptions, TransformTarget, Transformer};
|
||||||
|
|
||||||
// Instruction:
|
// Instruction:
|
||||||
// create a `test.js`,
|
// create a `test.js`,
|
||||||
|
|
@ -39,8 +39,11 @@ fn main() {
|
||||||
let scopes = Rc::new(RefCell::new(scopes));
|
let scopes = Rc::new(RefCell::new(scopes));
|
||||||
|
|
||||||
let program = allocator.alloc(ret.program);
|
let program = allocator.alloc(ret.program);
|
||||||
let transform_options =
|
let transform_options = TransformOptions {
|
||||||
TransformOptions { target: TransformTarget::ES2015, ..TransformOptions::default() };
|
target: TransformTarget::ES2015,
|
||||||
|
react_jsx: Some(ReactJsxOptions::default()),
|
||||||
|
..TransformOptions::default()
|
||||||
|
};
|
||||||
Transformer::new(&allocator, source_type, &symbols, &scopes, transform_options).build(program);
|
Transformer::new(&allocator, source_type, &symbols, &scopes, transform_options).build(program);
|
||||||
let printed = Codegen::<false>::new(source_text.len(), codegen_options).build(program);
|
let printed = Codegen::<false>::new(source_text.len(), codegen_options).build(program);
|
||||||
println!("Transformed:\n");
|
println!("Transformed:\n");
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ pub use crate::{
|
||||||
pub struct Transformer<'a> {
|
pub struct Transformer<'a> {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
typescript: Option<TypeScript<'a>>,
|
typescript: Option<TypeScript<'a>>,
|
||||||
#[allow(unused)]
|
|
||||||
react_jsx: Option<ReactJsx<'a>>,
|
react_jsx: Option<ReactJsx<'a>>,
|
||||||
regexp_flags: Option<RegexpFlags<'a>>,
|
regexp_flags: Option<RegexpFlags<'a>>,
|
||||||
// es2022
|
// es2022
|
||||||
|
|
@ -110,6 +109,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||||
for stmt in stmts.iter_mut() {
|
for stmt in stmts.iter_mut() {
|
||||||
self.visit_statement(stmt);
|
self.visit_statement(stmt);
|
||||||
}
|
}
|
||||||
|
self.react_jsx.as_mut().map(|t| t.add_react_jsx_runtime_import(stmts));
|
||||||
// TODO: we need scope id to insert the vars into the correct statements
|
// TODO: we need scope id to insert the vars into the correct statements
|
||||||
self.es2021_logical_assignment_operators.as_mut().map(|t| t.add_vars_to_statements(stmts));
|
self.es2021_logical_assignment_operators.as_mut().map(|t| t.add_vars_to_statements(stmts));
|
||||||
self.es2020_nullish_coalescing_operators.as_mut().map(|t| t.add_vars_to_statements(stmts));
|
self.es2020_nullish_coalescing_operators.as_mut().map(|t| t.add_vars_to_statements(stmts));
|
||||||
|
|
@ -118,7 +118,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||||
|
|
||||||
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
||||||
// self.typescript.as_mut().map(|t| t.transform_expression(expr));
|
// self.typescript.as_mut().map(|t| t.transform_expression(expr));
|
||||||
// self.react_jsx.as_mut().map(|t| t.transform_expression(expr));
|
self.react_jsx.as_mut().map(|t| t.transform_expression(expr));
|
||||||
self.regexp_flags.as_mut().map(|t| t.transform_expression(expr));
|
self.regexp_flags.as_mut().map(|t| t.transform_expression(expr));
|
||||||
|
|
||||||
self.es2021_logical_assignment_operators.as_mut().map(|t| t.transform_expression(expr));
|
self.es2021_logical_assignment_operators.as_mut().map(|t| t.transform_expression(expr));
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
|
mod options;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use oxc_ast::AstBuilder;
|
use oxc_allocator::Vec;
|
||||||
|
use oxc_ast::{ast::*, AstBuilder};
|
||||||
|
use oxc_span::Span;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
pub use self::options::{ReactJsxOptions, ReactJsxRuntime};
|
||||||
pub struct ReactJsxOptions {
|
|
||||||
_runtime: ReactJsxRuntime,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
const SPAN: Span = Span::new(0, 0);
|
||||||
pub enum ReactJsxRuntime {
|
|
||||||
#[default]
|
|
||||||
Classic,
|
|
||||||
#[allow(unused)]
|
|
||||||
Automatic,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transform React JSX
|
/// Transform React JSX
|
||||||
///
|
///
|
||||||
|
|
@ -21,12 +16,190 @@ pub enum ReactJsxRuntime {
|
||||||
/// * <https://babeljs.io/docs/babel-plugin-transform-react-jsx>
|
/// * <https://babeljs.io/docs/babel-plugin-transform-react-jsx>
|
||||||
/// * <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-react-jsx>
|
/// * <https://github.com/babel/babel/tree/main/packages/babel-helper-builder-react-jsx>
|
||||||
pub struct ReactJsx<'a> {
|
pub struct ReactJsx<'a> {
|
||||||
_ast: Rc<AstBuilder<'a>>,
|
ast: Rc<AstBuilder<'a>>,
|
||||||
_options: ReactJsxOptions,
|
options: ReactJsxOptions,
|
||||||
|
|
||||||
|
has_jsx: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ReactJsx<'a> {
|
impl<'a> ReactJsx<'a> {
|
||||||
pub fn new(_ast: Rc<AstBuilder<'a>>, _options: ReactJsxOptions) -> Self {
|
pub fn new(ast: Rc<AstBuilder<'a>>, options: ReactJsxOptions) -> Self {
|
||||||
Self { _ast, _options }
|
Self { ast, options, has_jsx: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_expression<'b>(&mut self, expr: &'b mut Expression<'a>) {
|
||||||
|
if let Expression::JSXElement(e) = expr {
|
||||||
|
self.has_jsx = true;
|
||||||
|
if let Some(e) = self.transform_jsx_element(e) {
|
||||||
|
*expr = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_react_jsx_runtime_import(&self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||||
|
if self.options.runtime.is_classic() || !self.has_jsx {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut specifiers = self.ast.new_vec_with_capacity(1);
|
||||||
|
specifiers.push(ImportDeclarationSpecifier::ImportSpecifier(ImportSpecifier {
|
||||||
|
span: SPAN,
|
||||||
|
imported: ModuleExportName::Identifier(IdentifierName::new(SPAN, "jsx".into())),
|
||||||
|
local: BindingIdentifier::new(SPAN, "_jsx".into()),
|
||||||
|
import_kind: ImportOrExportKind::Value,
|
||||||
|
}));
|
||||||
|
let source = StringLiteral::new(SPAN, "react/jsx-runtime".into());
|
||||||
|
let import_statement = self.ast.import_declaration(
|
||||||
|
SPAN,
|
||||||
|
Some(specifiers),
|
||||||
|
source,
|
||||||
|
None,
|
||||||
|
ImportOrExportKind::Value,
|
||||||
|
);
|
||||||
|
let decl =
|
||||||
|
self.ast.module_declaration(ModuleDeclaration::ImportDeclaration(import_statement));
|
||||||
|
stmts.insert(0, decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_jsx_element(&self, e: &JSXElement<'a>) -> Option<Expression<'a>> {
|
||||||
|
let callee = self.transform_create_element();
|
||||||
|
|
||||||
|
let mut arguments = self.ast.new_vec_with_capacity(2 + e.children.len());
|
||||||
|
arguments.push(Argument::Expression(self.transform_element_name(&e.opening_element.name)?));
|
||||||
|
arguments.push(Argument::Expression(
|
||||||
|
self.transform_jsx_attributes(&e.opening_element.attributes)?,
|
||||||
|
));
|
||||||
|
arguments.extend(
|
||||||
|
e.children
|
||||||
|
.iter()
|
||||||
|
.filter_map(|child| self.transform_jsx_child(child))
|
||||||
|
.map(Argument::Expression),
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(self.ast.call_expression(SPAN, callee, arguments, false, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_create_element(&self) -> Expression<'a> {
|
||||||
|
match self.options.runtime {
|
||||||
|
ReactJsxRuntime::Classic => {
|
||||||
|
// React
|
||||||
|
let object = IdentifierReference::new(SPAN, "React".into());
|
||||||
|
let object = self.ast.identifier_reference_expression(object);
|
||||||
|
|
||||||
|
// React.createElement
|
||||||
|
let property = IdentifierName::new(SPAN, "createElement".into());
|
||||||
|
self.ast.static_member_expression(SPAN, object, property, false)
|
||||||
|
}
|
||||||
|
ReactJsxRuntime::Automatic => {
|
||||||
|
let ident = IdentifierReference::new(SPAN, "_jsx".into());
|
||||||
|
self.ast.identifier_reference_expression(ident)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_element_name(&self, name: &JSXElementName<'a>) -> Option<Expression<'a>> {
|
||||||
|
match name {
|
||||||
|
JSXElementName::Identifier(ident) => {
|
||||||
|
let name = ident.name.clone();
|
||||||
|
Some(if ident.name.chars().next().is_some_and(|c| c.is_ascii_lowercase()) {
|
||||||
|
self.ast.literal_string_expression(StringLiteral::new(SPAN, name))
|
||||||
|
} else {
|
||||||
|
self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
/* TODO */
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_jsx_attributes(
|
||||||
|
&self,
|
||||||
|
attributes: &Vec<'a, JSXAttributeItem<'a>>,
|
||||||
|
) -> Option<Expression<'a>> {
|
||||||
|
if attributes.is_empty() {
|
||||||
|
return Some(self.ast.literal_null_expression(NullLiteral::new(SPAN)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut properties = self.ast.new_vec_with_capacity(attributes.len());
|
||||||
|
for attribute in attributes {
|
||||||
|
let kind = PropertyKind::Init;
|
||||||
|
let object_property = match attribute {
|
||||||
|
JSXAttributeItem::Attribute(attr) => {
|
||||||
|
let key = match &attr.name {
|
||||||
|
JSXAttributeName::Identifier(ident) => PropertyKey::Identifier(
|
||||||
|
self.ast.alloc(IdentifierName::new(SPAN, ident.name.clone())),
|
||||||
|
),
|
||||||
|
JSXAttributeName::NamespacedName(_ident) => {
|
||||||
|
/* TODO */
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let value = match &attr.value {
|
||||||
|
Some(value) => {
|
||||||
|
match value {
|
||||||
|
JSXAttributeValue::StringLiteral(s) => {
|
||||||
|
self.ast.literal_string_expression(s.clone())
|
||||||
|
}
|
||||||
|
JSXAttributeValue::Element(_) | JSXAttributeValue::Fragment(_) => {
|
||||||
|
/* TODO */
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
JSXAttributeValue::ExpressionContainer(c) => {
|
||||||
|
match &c.expression {
|
||||||
|
JSXExpression::Expression(e) => self.ast.copy(e),
|
||||||
|
JSXExpression::EmptyExpression(_e) =>
|
||||||
|
/* TODO */
|
||||||
|
{
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.ast.literal_boolean_expression(BooleanLiteral::new(SPAN, true))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let object_property =
|
||||||
|
self.ast.object_property(SPAN, kind, key, value, None, false, false, false);
|
||||||
|
ObjectPropertyKind::ObjectProperty(object_property)
|
||||||
|
}
|
||||||
|
JSXAttributeItem::SpreadAttribute(attr) => {
|
||||||
|
let argument = self.ast.copy(&attr.argument);
|
||||||
|
let spread_property = self.ast.spread_element(SPAN, argument);
|
||||||
|
ObjectPropertyKind::SpreadProperty(spread_property)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
properties.push(object_property);
|
||||||
|
}
|
||||||
|
|
||||||
|
let object_expression = self.ast.object_expression(SPAN, properties, None);
|
||||||
|
Some(object_expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_jsx_child(&self, child: &JSXChild<'a>) -> Option<Expression<'a>> {
|
||||||
|
match child {
|
||||||
|
JSXChild::Text(text) => {
|
||||||
|
let text = text.value.trim();
|
||||||
|
(!text.trim().is_empty()).then(|| {
|
||||||
|
let text = text
|
||||||
|
.split(char::is_whitespace)
|
||||||
|
.map(str::trim)
|
||||||
|
.filter(|c| !c.is_empty())
|
||||||
|
.collect::<std::vec::Vec<_>>()
|
||||||
|
.join(" ");
|
||||||
|
let s = StringLiteral::new(SPAN, text.into());
|
||||||
|
self.ast.literal_string_expression(s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
JSXChild::ExpressionContainer(e) => match &e.expression {
|
||||||
|
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
||||||
|
JSXExpression::EmptyExpression(_) => None,
|
||||||
|
},
|
||||||
|
JSXChild::Element(e) => self.transform_jsx_element(e),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
crates/oxc_transformer/src/react_jsx/options.rs
Normal file
27
crates/oxc_transformer/src/react_jsx/options.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||||
|
pub struct ReactJsxOptions {
|
||||||
|
/// Decides which runtime to use.
|
||||||
|
pub runtime: ReactJsxRuntime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum ReactJsxRuntime {
|
||||||
|
/// Does not automatically import anything (default).
|
||||||
|
#[default]
|
||||||
|
Classic,
|
||||||
|
/// Auto imports the functions that JSX transpiles to.
|
||||||
|
Automatic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReactJsxRuntime {
|
||||||
|
pub fn is_classic(&self) -> bool {
|
||||||
|
matches!(self, Self::Classic)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_automatic(&self) -> bool {
|
||||||
|
matches!(self, Self::Automatic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Passed: 175/1083
|
Passed: 187/1083
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-numeric-separator
|
* babel-plugin-transform-numeric-separator
|
||||||
|
|
@ -804,7 +804,7 @@ Passed: 175/1083
|
||||||
* regression/11061/input.mjs
|
* regression/11061/input.mjs
|
||||||
* variable-declaration/non-null-in-optional-chain/input.ts
|
* variable-declaration/non-null-in-optional-chain/input.ts
|
||||||
|
|
||||||
# babel-plugin-transform-react-jsx (26/172)
|
# babel-plugin-transform-react-jsx (38/172)
|
||||||
* autoImport/after-polyfills/input.mjs
|
* autoImport/after-polyfills/input.mjs
|
||||||
* autoImport/after-polyfills-2/input.mjs
|
* autoImport/after-polyfills-2/input.mjs
|
||||||
* autoImport/after-polyfills-compiled-to-cjs/input.mjs
|
* autoImport/after-polyfills-compiled-to-cjs/input.mjs
|
||||||
|
|
@ -817,41 +817,36 @@ Passed: 175/1083
|
||||||
* autoImport/import-source-pragma/input.js
|
* autoImport/import-source-pragma/input.js
|
||||||
* autoImport/react-defined/input.js
|
* autoImport/react-defined/input.js
|
||||||
* pure/false-default-pragma-automatic-runtime/input.js
|
* pure/false-default-pragma-automatic-runtime/input.js
|
||||||
* pure/false-default-pragma-classic-runtime/input.js
|
* pure/false-pragma-comment-automatic-runtime/input.js
|
||||||
* pure/false-pragma-comment-classic-runtime/input.js
|
* pure/false-pragma-comment-classic-runtime/input.js
|
||||||
|
* pure/false-pragma-option-automatic-runtime/input.js
|
||||||
* pure/false-pragma-option-classic-runtime/input.js
|
* pure/false-pragma-option-classic-runtime/input.js
|
||||||
* pure/true-default-pragma-automatic-runtime/input.js
|
* pure/true-default-pragma-automatic-runtime/input.js
|
||||||
* pure/true-default-pragma-classic-runtime/input.js
|
* pure/true-pragma-comment-automatic-runtime/input.js
|
||||||
* pure/true-pragma-comment-classic-runtime/input.js
|
* pure/true-pragma-comment-classic-runtime/input.js
|
||||||
|
* pure/true-pragma-option-automatic-runtime/input.js
|
||||||
* pure/true-pragma-option-classic-runtime/input.js
|
* pure/true-pragma-option-classic-runtime/input.js
|
||||||
* pure/unset-default-pragma-automatic-runtime/input.js
|
* pure/unset-default-pragma-automatic-runtime/input.js
|
||||||
* pure/unset-default-pragma-classic-runtime/input.js
|
* pure/unset-pragma-comment-automatic-runtime/input.js
|
||||||
* pure/unset-pragma-comment-classic-runtime/input.js
|
* pure/unset-pragma-comment-classic-runtime/input.js
|
||||||
|
* pure/unset-pragma-option-automatic-runtime/input.js
|
||||||
* pure/unset-pragma-option-classic-runtime/input.js
|
* pure/unset-pragma-option-classic-runtime/input.js
|
||||||
* react/adds-appropriate-newlines-when-using-spread-attribute/input.js
|
* react/.should-properly-handle-comments-adjacent-to-children/input.js
|
||||||
* react/adds-appropriate-newlines-when-using-spread-attribute-babel-7/input.js
|
* react/adds-appropriate-newlines-when-using-spread-attribute-babel-7/input.js
|
||||||
* react/arrow-functions/input.js
|
* react/arrow-functions/input.js
|
||||||
* react/assignment/input.js
|
|
||||||
* react/assignment-babel-7/input.js
|
* react/assignment-babel-7/input.js
|
||||||
* react/avoids-spread-babel-7/input.js
|
* react/avoids-spread-babel-7/input.js
|
||||||
* react/concatenates-adjacent-string-literals/input.js
|
|
||||||
* react/does-not-add-source-self/input.mjs
|
* react/does-not-add-source-self/input.mjs
|
||||||
* react/does-not-add-source-self-babel-7/input.mjs
|
* react/does-not-add-source-self-babel-7/input.mjs
|
||||||
* react/dont-coerce-expression-containers/input.js
|
|
||||||
* react/duplicate-props/input.js
|
* react/duplicate-props/input.js
|
||||||
* react/flattens-spread/input.js
|
* react/flattens-spread/input.js
|
||||||
* react/handle-spread-with-proto/input.js
|
|
||||||
* react/handle-spread-with-proto-babel-7/input.js
|
* react/handle-spread-with-proto-babel-7/input.js
|
||||||
* react/honor-custom-jsx-comment/input.js
|
* react/honor-custom-jsx-comment/input.js
|
||||||
* react/honor-custom-jsx-comment-if-jsx-pragma-option-set/input.js
|
* react/honor-custom-jsx-comment-if-jsx-pragma-option-set/input.js
|
||||||
* react/honor-custom-jsx-pragma-option/input.js
|
* react/honor-custom-jsx-pragma-option/input.js
|
||||||
* react/jsx-with-retainlines-option/input.js
|
|
||||||
* react/jsx-without-retainlines-option/input.js
|
|
||||||
* react/optimisation.react.constant-elements/input.js
|
* react/optimisation.react.constant-elements/input.js
|
||||||
* react/pragma-works-with-no-space-at-the-end/input.js
|
* react/pragma-works-with-no-space-at-the-end/input.js
|
||||||
* react/proto-in-jsx-attribute/input.js
|
|
||||||
* react/should-add-quotes-es3/input.js
|
* react/should-add-quotes-es3/input.js
|
||||||
* react/should-allow-constructor-as-prop/input.js
|
|
||||||
* react/should-allow-deeper-js-namespacing/input.js
|
* react/should-allow-deeper-js-namespacing/input.js
|
||||||
* react/should-allow-elements-as-attributes/input.js
|
* react/should-allow-elements-as-attributes/input.js
|
||||||
* react/should-allow-js-namespacing/input.js
|
* react/should-allow-js-namespacing/input.js
|
||||||
|
|
@ -859,37 +854,28 @@ Passed: 175/1083
|
||||||
* react/should-allow-nested-fragments/input.js
|
* react/should-allow-nested-fragments/input.js
|
||||||
* react/should-allow-no-pragmafrag-if-frag-unused/input.js
|
* react/should-allow-no-pragmafrag-if-frag-unused/input.js
|
||||||
* react/should-allow-pragmafrag-and-frag/input.js
|
* react/should-allow-pragmafrag-and-frag/input.js
|
||||||
* react/should-avoid-wrapping-in-extra-parens-if-not-needed/input.js
|
* react/should-disallow-spread-children/input.js
|
||||||
* react/should-convert-simple-tags/input.js
|
* react/should-disallow-valueless-key/input.js
|
||||||
* react/should-convert-simple-text/input.js
|
|
||||||
* react/should-escape-xhtml-jsxattribute/input.js
|
* react/should-escape-xhtml-jsxattribute/input.js
|
||||||
* react/should-escape-xhtml-jsxattribute-babel-7/input.js
|
* react/should-escape-xhtml-jsxattribute-babel-7/input.js
|
||||||
* react/should-escape-xhtml-jsxtext/input.js
|
* react/should-escape-xhtml-jsxtext/input.js
|
||||||
* react/should-escape-xhtml-jsxtext-babel-7/input.js
|
* react/should-escape-xhtml-jsxtext-babel-7/input.js
|
||||||
* react/should-handle-attributed-elements/input.js
|
* react/should-handle-attributed-elements/input.js
|
||||||
* react/should-handle-has-own-property-correctly/input.js
|
|
||||||
* react/should-have-correct-comma-in-nested-children/input.js
|
|
||||||
* react/should-insert-commas-after-expressions-before-whitespace/input.js
|
|
||||||
* react/should-not-add-quotes-to-identifier-names/input.js
|
* react/should-not-add-quotes-to-identifier-names/input.js
|
||||||
* react/should-not-allow-jsx-pragma-to-be-anywhere-in-comment/input.js
|
|
||||||
* react/should-not-mangle-expressioncontainer-attribute-values/input.js
|
* react/should-not-mangle-expressioncontainer-attribute-values/input.js
|
||||||
* react/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
* react/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
||||||
* react/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
* react/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
||||||
* react/should-properly-handle-comments-between-props/input.js
|
|
||||||
* react/should-quote-jsx-attributes/input.js
|
* react/should-quote-jsx-attributes/input.js
|
||||||
* react/should-support-xml-namespaces-if-flag/input.js
|
* react/should-support-xml-namespaces-if-flag/input.js
|
||||||
* react/should-transform-known-hyphenated-tags/input.js
|
* react/should-warn-when-importSource-is-set/input.js
|
||||||
|
* react/should-warn-when-importSource-pragma-is-set/input.js
|
||||||
* react/this-tag-name/input.js
|
* react/this-tag-name/input.js
|
||||||
* react/weird-symbols/input.js
|
* react/weird-symbols/input.js
|
||||||
* react/wraps-props-in-react-spread-for-first-spread-attributes/input.js
|
|
||||||
* react/wraps-props-in-react-spread-for-first-spread-attributes-babel-7/input.js
|
* react/wraps-props-in-react-spread-for-first-spread-attributes-babel-7/input.js
|
||||||
* react/wraps-props-in-react-spread-for-last-spread-attributes/input.js
|
|
||||||
* react/wraps-props-in-react-spread-for-last-spread-attributes-babel-7/input.js
|
* react/wraps-props-in-react-spread-for-last-spread-attributes-babel-7/input.js
|
||||||
* react/wraps-props-in-react-spread-for-middle-spread-attributes/input.js
|
|
||||||
* react/wraps-props-in-react-spread-for-middle-spread-attributes-babel-7/input.js
|
* react/wraps-props-in-react-spread-for-middle-spread-attributes-babel-7/input.js
|
||||||
* react-automatic/adds-appropriate-newlines-when-using-spread-attribute/input.js
|
* react-automatic/.should-properly-handle-comments-adjacent-to-children/input.js
|
||||||
* react-automatic/arrow-functions/input.js
|
* react-automatic/arrow-functions/input.js
|
||||||
* react-automatic/assignment/input.js
|
|
||||||
* react-automatic/concatenates-adjacent-string-literals/input.js
|
* react-automatic/concatenates-adjacent-string-literals/input.js
|
||||||
* react-automatic/does-not-add-source-self-automatic/input.mjs
|
* react-automatic/does-not-add-source-self-automatic/input.mjs
|
||||||
* react-automatic/dont-coerce-expression-containers/input.js
|
* react-automatic/dont-coerce-expression-containers/input.js
|
||||||
|
|
@ -907,7 +893,6 @@ Passed: 175/1083
|
||||||
* react-automatic/optimisation.react.constant-elements/input.js
|
* react-automatic/optimisation.react.constant-elements/input.js
|
||||||
* react-automatic/pragma-works-with-no-space-at-the-end/input.js
|
* react-automatic/pragma-works-with-no-space-at-the-end/input.js
|
||||||
* react-automatic/should-add-quotes-es3/input.js
|
* react-automatic/should-add-quotes-es3/input.js
|
||||||
* react-automatic/should-allow-constructor-as-prop/input.js
|
|
||||||
* react-automatic/should-allow-deeper-js-namespacing/input.js
|
* react-automatic/should-allow-deeper-js-namespacing/input.js
|
||||||
* react-automatic/should-allow-elements-as-attributes/input.js
|
* react-automatic/should-allow-elements-as-attributes/input.js
|
||||||
* react-automatic/should-allow-js-namespacing/input.js
|
* react-automatic/should-allow-js-namespacing/input.js
|
||||||
|
|
@ -915,6 +900,9 @@ Passed: 175/1083
|
||||||
* react-automatic/should-avoid-wrapping-in-extra-parens-if-not-needed/input.js
|
* react-automatic/should-avoid-wrapping-in-extra-parens-if-not-needed/input.js
|
||||||
* react-automatic/should-convert-simple-tags/input.js
|
* react-automatic/should-convert-simple-tags/input.js
|
||||||
* react-automatic/should-convert-simple-text/input.js
|
* react-automatic/should-convert-simple-text/input.js
|
||||||
|
* react-automatic/should-disallow-spread-children/input.js
|
||||||
|
* react-automatic/should-disallow-valueless-key/input.js
|
||||||
|
* react-automatic/should-disallow-xml-namespacing/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxattribute/input.js
|
* react-automatic/should-escape-xhtml-jsxattribute/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxattribute-babel-7/input.js
|
* react-automatic/should-escape-xhtml-jsxattribute-babel-7/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxtext/input.js
|
* react-automatic/should-escape-xhtml-jsxtext/input.js
|
||||||
|
|
@ -922,33 +910,33 @@ Passed: 175/1083
|
||||||
* react-automatic/should-handle-attributed-elements/input.js
|
* react-automatic/should-handle-attributed-elements/input.js
|
||||||
* react-automatic/should-handle-has-own-property-correctly/input.js
|
* react-automatic/should-handle-has-own-property-correctly/input.js
|
||||||
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
||||||
* react-automatic/should-insert-commas-after-expressions-before-whitespace/input.js
|
|
||||||
* react-automatic/should-not-add-quotes-to-identifier-names/input.js
|
* react-automatic/should-not-add-quotes-to-identifier-names/input.js
|
||||||
* react-automatic/should-not-mangle-expressioncontainer-attribute-values/input.js
|
* react-automatic/should-not-mangle-expressioncontainer-attribute-values/input.js
|
||||||
* react-automatic/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
* react-automatic/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
||||||
* react-automatic/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
* react-automatic/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
||||||
* react-automatic/should-properly-handle-comments-between-props/input.js
|
* react-automatic/should-properly-handle-comments-between-props/input.js
|
||||||
* react-automatic/should-properly-handle-keys/input.js
|
* react-automatic/should-properly-handle-keys/input.js
|
||||||
* react-automatic/should-properly-handle-null-prop-spread/input.js
|
|
||||||
* react-automatic/should-quote-jsx-attributes/input.js
|
* react-automatic/should-quote-jsx-attributes/input.js
|
||||||
* react-automatic/should-support-xml-namespaces-if-flag/input.js
|
* react-automatic/should-support-xml-namespaces-if-flag/input.js
|
||||||
|
* react-automatic/should-throw-error-namespaces-if-not-flag/input.js
|
||||||
* react-automatic/should-transform-known-hyphenated-tags/input.js
|
* react-automatic/should-transform-known-hyphenated-tags/input.js
|
||||||
* react-automatic/should-use-createElement-when-key-comes-after-spread/input.js
|
* react-automatic/should-use-createElement-when-key-comes-after-spread/input.js
|
||||||
* react-automatic/should-use-jsx-when-key-comes-before-spread/input.js
|
* react-automatic/should-use-jsx-when-key-comes-before-spread/input.js
|
||||||
|
* react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js
|
||||||
* react-automatic/this-tag-name/input.js
|
* react-automatic/this-tag-name/input.js
|
||||||
* react-automatic/weird-symbols/input.js
|
* react-automatic/weird-symbols/input.js
|
||||||
* react-automatic/wraps-props-in-react-spread-for-last-spread-attributes/input.js
|
|
||||||
* react-automatic/wraps-props-in-react-spread-for-middle-spread-attributes/input.js
|
|
||||||
* regression/issue-12478-automatic/input.js
|
* regression/issue-12478-automatic/input.js
|
||||||
* regression/issue-12478-classic/input.js
|
* regression/issue-12478-classic/input.js
|
||||||
* regression/issue-15353-classic/input.js
|
* regression/issue-15353-classic/input.js
|
||||||
* regression/pragma-frag-set-default-classic-runtime/input.js
|
* regression/pragma-frag-set-default-classic-runtime/input.js
|
||||||
* runtime/classic/input.js
|
* removed-options/invalid-use-builtins-false/input.js
|
||||||
|
* removed-options/invalid-use-builtins-true/input.js
|
||||||
|
* removed-options/invalid-use-spread-false/input.js
|
||||||
|
* removed-options/invalid-use-spread-true/input.js
|
||||||
* runtime/defaults-to-automatic/input.js
|
* runtime/defaults-to-automatic/input.js
|
||||||
* runtime/defaults-to-classis-babel-7/input.js
|
* runtime/invalid-runtime/input.js
|
||||||
* runtime/pragma-runtime-classsic/input.js
|
* runtime/pragma-runtime-classsic/input.js
|
||||||
* runtime/runtime-automatic/input.js
|
* runtime/runtime-automatic/input.js
|
||||||
* sourcemaps/JSXText/input.js
|
|
||||||
* spread-transform/transform-to-babel-extend/input.js
|
* spread-transform/transform-to-babel-extend/input.js
|
||||||
* spread-transform/transform-to-object-assign/input.js
|
* spread-transform/transform-to-object-assign/input.js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,9 @@ pub trait TestCase {
|
||||||
let options = self.options();
|
let options = self.options();
|
||||||
TransformOptions {
|
TransformOptions {
|
||||||
target: TransformTarget::ESNext,
|
target: TransformTarget::ESNext,
|
||||||
react_jsx: Some(ReactJsxOptions::default()),
|
react_jsx: options
|
||||||
|
.get_plugin("transform-react-jsx")
|
||||||
|
.map(get_options::<ReactJsxOptions>),
|
||||||
assumptions: options.assumptions,
|
assumptions: options.assumptions,
|
||||||
class_static_block: options.get_plugin("transform-class-static-block").is_some(),
|
class_static_block: options.get_plugin("transform-class-static-block").is_some(),
|
||||||
logical_assignment_operators: options
|
logical_assignment_operators: options
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue