mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(transformer): add diagnostics to react transform (#2974)
This commit is contained in:
parent
ef602af4cc
commit
c211f1e57f
4 changed files with 57 additions and 25 deletions
30
crates/oxc_transformer/src/react/jsx/diagnostics.rs
Normal file
30
crates/oxc_transformer/src/react/jsx/diagnostics.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use oxc_diagnostics::{
|
||||
miette::{self, Diagnostic},
|
||||
thiserror::Error,
|
||||
};
|
||||
use oxc_span::Span;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("pragma and pragmaFrag cannot be set when runtime is automatic.")]
|
||||
#[diagnostic(severity(warning), help("Remove `pragma` and `pragmaFrag` options."))]
|
||||
pub struct PragmaAndPragmaFragCannotBeSet;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("importSource cannot be set when runtime is classic.")]
|
||||
#[diagnostic(severity(warning), help("Remove `importSource` option."))]
|
||||
pub struct ImportSourceCannotBeSet;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can set `throwIfNamespace: false` to bypass this warning.")]
|
||||
#[diagnostic(severity(warning))]
|
||||
pub struct NamespaceDoesNotSupport(#[label] pub Span);
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Please provide an explicit key value. Using \"key\" as a shorthand for \"key={{true}}\" is not allowed.")]
|
||||
#[diagnostic(severity(warning))]
|
||||
pub struct ValuelessKey(#[label] pub Span);
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Spread children are not supported in React.")]
|
||||
#[diagnostic(severity(warning))]
|
||||
pub struct SpreadChildrenAreNotSupported(#[label] pub Span);
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
mod diagnostics;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_ast::{ast::*, AstBuilder};
|
||||
use oxc_span::{CompactStr, SPAN};
|
||||
use oxc_span::{CompactStr, GetSpan, SPAN};
|
||||
use oxc_syntax::{
|
||||
identifier::{is_irregular_whitespace, is_line_terminator},
|
||||
xml_entities::XML_ENTITIES,
|
||||
|
|
@ -16,6 +18,11 @@ pub use super::{
|
|||
options::{ReactJsxRuntime, ReactOptions},
|
||||
};
|
||||
|
||||
use self::diagnostics::{
|
||||
ImportSourceCannotBeSet, NamespaceDoesNotSupport, PragmaAndPragmaFragCannotBeSet,
|
||||
SpreadChildrenAreNotSupported, ValuelessKey,
|
||||
};
|
||||
|
||||
/// [plugin-transform-react-jsx](https://babeljs.io/docs/babel-plugin-transform-react-jsx)
|
||||
///
|
||||
/// This plugin generates production-ready JS code.
|
||||
|
|
@ -99,7 +106,7 @@ impl<'a> ReactJsx<'a> {
|
|||
pub fn add_runtime_imports(&mut self, program: &mut Program<'a>) {
|
||||
if self.options.runtime.is_classic() {
|
||||
if self.options.import_source != "react" {
|
||||
// self.ctx.error(ImportSourceCannotBeSet);
|
||||
self.ctx.error(ImportSourceCannotBeSet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -107,7 +114,7 @@ impl<'a> ReactJsx<'a> {
|
|||
if self.options.pragma != "React.createElement"
|
||||
|| self.options.pragma_frag != "React.Fragment"
|
||||
{
|
||||
// self.ctx.error(PragmaAndPragmaFragCannotBeSet);
|
||||
self.ctx.error(PragmaAndPragmaFragCannotBeSet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -332,9 +339,9 @@ impl<'a> ReactJsx<'a> {
|
|||
}
|
||||
}
|
||||
JSXAttributeItem::Attribute(attr) if attr.is_key() => {
|
||||
// if attr.value.is_none() {
|
||||
// self.ctx.error(ValuelessKey(attr.name.span()));
|
||||
// }
|
||||
if attr.value.is_none() {
|
||||
self.ctx.error(ValuelessKey(attr.name.span()));
|
||||
}
|
||||
// In automatic mode, extract the key before spread prop,
|
||||
// and add it to the third argument later.
|
||||
if is_automatic && !has_key_after_props_spread {
|
||||
|
|
@ -431,9 +438,9 @@ impl<'a> ReactJsx<'a> {
|
|||
self.transform_jsx_member_expression(member_expr)
|
||||
}
|
||||
JSXElementName::NamespacedName(name) => {
|
||||
// if self.options.throw_if_namespace {
|
||||
// self.ctx.error(NamespaceDoesNotSupport(name.span));
|
||||
// }
|
||||
if self.options.throw_if_namespace {
|
||||
self.ctx.error(NamespaceDoesNotSupport(name.span));
|
||||
}
|
||||
let name = self.ast().new_atom(&name.to_string());
|
||||
let string_literal = StringLiteral::new(SPAN, name);
|
||||
self.ast().literal_string_expression(string_literal)
|
||||
|
|
@ -610,8 +617,8 @@ impl<'a> ReactJsx<'a> {
|
|||
},
|
||||
JSXChild::Element(e) => Some(self.transform_jsx(&JSXElementOrFragment::Element(e))),
|
||||
JSXChild::Fragment(e) => Some(self.transform_jsx(&JSXElementOrFragment::Fragment(e))),
|
||||
JSXChild::Spread(_e) => {
|
||||
// self.ctx.error(SpreadChildrenAreNotSupported(e.span));
|
||||
JSXChild::Spread(e) => {
|
||||
self.ctx.error(SpreadChildrenAreNotSupported(e.span));
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ pub struct ReactOptions {
|
|||
#[serde(default = "default_as_true")]
|
||||
pub development: bool,
|
||||
|
||||
/// Toggles whether or not to throw an error if a XML namespaced tag name is used.
|
||||
///
|
||||
/// Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.
|
||||
#[serde(default = "default_as_true")]
|
||||
pub throw_if_namespace: bool,
|
||||
|
||||
/// Enables `@babel/plugin-transform-react-pure-annotations`.
|
||||
///
|
||||
/// It will mark top-level React method calls as pure for tree shaking.
|
||||
|
|
@ -100,6 +106,7 @@ impl Default for ReactOptions {
|
|||
jsx_source_plugin: true,
|
||||
runtime: ReactJsxRuntime::default(),
|
||||
development: default_as_true(),
|
||||
throw_if_namespace: default_as_true(),
|
||||
pure: default_as_true(),
|
||||
import_source: default_for_import_source(),
|
||||
pragma: default_for_pragma(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Passed: 191/415
|
||||
Passed: 203/415
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-react-jsx-source
|
||||
|
|
@ -141,20 +141,17 @@ Passed: 191/415
|
|||
* regression/another-preset-with-custom-jsx-keep-source-self/input.mjs
|
||||
* regression/runtime-classic-allow-multiple-source-self/input.mjs
|
||||
|
||||
# babel-plugin-transform-react-jsx (100/163)
|
||||
# babel-plugin-transform-react-jsx (112/163)
|
||||
* autoImport/auto-import-react-source-type-module/input.js
|
||||
* autoImport/complicated-scope-module/input.js
|
||||
* autoImport/import-source-pragma/input.js
|
||||
* autoImport/react-defined/input.js
|
||||
* pure/false-pragma-comment-automatic-runtime/input.js
|
||||
* pure/false-pragma-comment-classic-runtime/input.js
|
||||
* pure/false-pragma-option-automatic-runtime/input.js
|
||||
* pure/true-pragma-comment-automatic-runtime/input.js
|
||||
* pure/true-pragma-comment-classic-runtime/input.js
|
||||
* pure/true-pragma-option-automatic-runtime/input.js
|
||||
* pure/unset-pragma-comment-automatic-runtime/input.js
|
||||
* pure/unset-pragma-comment-classic-runtime/input.js
|
||||
* pure/unset-pragma-option-automatic-runtime/input.js
|
||||
* react/adds-appropriate-newlines-when-using-spread-attribute-babel-7/input.js
|
||||
* react/arrow-functions/input.js
|
||||
* react/assignment-babel-7/input.js
|
||||
|
|
@ -169,10 +166,6 @@ Passed: 191/415
|
|||
* react/should-allow-jsx-docs-comment-with-pragma/input.js
|
||||
* react/should-allow-no-pragmafrag-if-frag-unused/input.js
|
||||
* react/should-allow-pragmafrag-and-frag/input.js
|
||||
* react/should-disallow-spread-children/input.js
|
||||
* react/should-disallow-valueless-key/input.js
|
||||
* react/should-disallow-xml-namespacing/input.js
|
||||
* react/should-throw-error-namespaces-if-not-flag/input.js
|
||||
* react/should-warn-when-importSource-is-set/input.js
|
||||
* react/should-warn-when-importSource-pragma-is-set/input.js
|
||||
* react/wraps-props-in-react-spread-for-first-spread-attributes-babel-7/input.js
|
||||
|
|
@ -188,17 +181,12 @@ Passed: 191/415
|
|||
* react-automatic/pragma-works-with-no-space-at-the-end/input.js
|
||||
* react-automatic/should-add-quotes-es3/input.js
|
||||
* react-automatic/should-allow-nested-fragments/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-jsxtext/input.js
|
||||
* react-automatic/should-escape-xhtml-jsxtext-babel-7/input.js
|
||||
* react-automatic/should-handle-attributed-elements/input.js
|
||||
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
||||
* react-automatic/should-properly-handle-keys/input.js
|
||||
* react-automatic/should-throw-error-namespaces-if-not-flag/input.js
|
||||
* react-automatic/should-throw-when-filter-is-specified/input.js
|
||||
* react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js
|
||||
* regression/issue-12478-automatic/input.js
|
||||
* regression/issue-12478-classic/input.js
|
||||
* regression/pragma-frag-set-default-classic-runtime/input.js
|
||||
|
|
|
|||
Loading…
Reference in a new issue