mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(linter): revert changes to JSX attribute strings (#1101)
This commit is contained in:
parent
bf1e3b5440
commit
a455c81db6
18 changed files with 50 additions and 87 deletions
|
|
@ -190,7 +190,7 @@ pub enum JSXAttributeName<'a> {
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))]
|
#[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))]
|
||||||
pub enum JSXAttributeValue<'a> {
|
pub enum JSXAttributeValue<'a> {
|
||||||
String(JSXString),
|
StringLiteral(StringLiteral),
|
||||||
ExpressionContainer(JSXExpressionContainer<'a>),
|
ExpressionContainer(JSXExpressionContainer<'a>),
|
||||||
Element(Box<'a, JSXElement<'a>>),
|
Element(Box<'a, JSXElement<'a>>),
|
||||||
Fragment(Box<'a, JSXFragment<'a>>),
|
Fragment(Box<'a, JSXFragment<'a>>),
|
||||||
|
|
@ -210,7 +210,7 @@ pub struct JSXIdentifier {
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))]
|
#[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))]
|
||||||
pub enum JSXChild<'a> {
|
pub enum JSXChild<'a> {
|
||||||
Text(JSXString),
|
Text(JSXText),
|
||||||
Element(Box<'a, JSXElement<'a>>),
|
Element(Box<'a, JSXElement<'a>>),
|
||||||
Fragment(Box<'a, JSXFragment<'a>>),
|
Fragment(Box<'a, JSXFragment<'a>>),
|
||||||
ExpressionContainer(JSXExpressionContainer<'a>),
|
ExpressionContainer(JSXExpressionContainer<'a>),
|
||||||
|
|
@ -225,12 +225,9 @@ pub struct JSXSpreadChild<'a> {
|
||||||
pub expression: Expression<'a>,
|
pub expression: Expression<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// JSX String
|
|
||||||
///
|
|
||||||
/// <https://facebook.github.io/jsx/#sec-jsx-string>
|
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||||
pub struct JSXString {
|
pub struct JSXText {
|
||||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub value: Atom,
|
pub value: Atom,
|
||||||
|
|
|
||||||
|
|
@ -1125,8 +1125,8 @@ impl<'a> AstBuilder<'a> {
|
||||||
JSXIdentifier { span, name }
|
JSXIdentifier { span, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn jsx_string(&self, span: Span, value: Atom) -> JSXString {
|
pub fn jsx_text(&self, span: Span, value: Atom) -> JSXText {
|
||||||
JSXString { span, value }
|
JSXText { span, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- TypeScript ---------- */
|
/* ---------- TypeScript ---------- */
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ pub enum AstKind<'a> {
|
||||||
JSXElementName(&'a JSXElementName<'a>),
|
JSXElementName(&'a JSXElementName<'a>),
|
||||||
JSXExpressionContainer(&'a JSXExpressionContainer<'a>),
|
JSXExpressionContainer(&'a JSXExpressionContainer<'a>),
|
||||||
JSXAttributeItem(&'a JSXAttributeItem<'a>),
|
JSXAttributeItem(&'a JSXAttributeItem<'a>),
|
||||||
JSXString(&'a JSXString),
|
JSXText(&'a JSXText),
|
||||||
|
|
||||||
// TypeScript
|
// TypeScript
|
||||||
TSModuleBlock(&'a TSModuleBlock<'a>),
|
TSModuleBlock(&'a TSModuleBlock<'a>),
|
||||||
|
|
@ -242,7 +242,7 @@ impl<'a> AstKind<'a> {
|
||||||
| Self::JSXElementName(_)
|
| Self::JSXElementName(_)
|
||||||
| Self::JSXFragment(_)
|
| Self::JSXFragment(_)
|
||||||
| Self::JSXAttributeItem(_)
|
| Self::JSXAttributeItem(_)
|
||||||
| Self::JSXString(_)
|
| Self::JSXText(_)
|
||||||
| Self::JSXExpressionContainer(_)
|
| Self::JSXExpressionContainer(_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +365,7 @@ impl<'a> GetSpan for AstKind<'a> {
|
||||||
Self::JSXElement(x) => x.span,
|
Self::JSXElement(x) => x.span,
|
||||||
Self::JSXFragment(x) => x.span,
|
Self::JSXFragment(x) => x.span,
|
||||||
Self::JSXAttributeItem(x) => x.span(),
|
Self::JSXAttributeItem(x) => x.span(),
|
||||||
Self::JSXString(x) => x.span,
|
Self::JSXText(x) => x.span,
|
||||||
Self::JSXExpressionContainer(x) => x.span,
|
Self::JSXExpressionContainer(x) => x.span,
|
||||||
|
|
||||||
Self::TSModuleBlock(x) => x.span,
|
Self::TSModuleBlock(x) => x.span,
|
||||||
|
|
@ -532,7 +532,7 @@ impl<'a> AstKind<'a> {
|
||||||
Self::JSXElement(_) => "JSXElement".into(),
|
Self::JSXElement(_) => "JSXElement".into(),
|
||||||
Self::JSXFragment(_) => "JSXFragment".into(),
|
Self::JSXFragment(_) => "JSXFragment".into(),
|
||||||
Self::JSXAttributeItem(_) => "JSXAttributeItem".into(),
|
Self::JSXAttributeItem(_) => "JSXAttributeItem".into(),
|
||||||
Self::JSXString(_) => "JSXString".into(),
|
Self::JSXText(_) => "JSXText".into(),
|
||||||
Self::JSXExpressionContainer(_) => "JSXExpressionContainer".into(),
|
Self::JSXExpressionContainer(_) => "JSXExpressionContainer".into(),
|
||||||
|
|
||||||
Self::TSModuleBlock(_) => "TSModuleBlock".into(),
|
Self::TSModuleBlock(_) => "TSModuleBlock".into(),
|
||||||
|
|
|
||||||
|
|
@ -1064,7 +1064,7 @@ pub trait Visit<'a>: Sized {
|
||||||
}
|
}
|
||||||
JSXAttributeValue::Element(elem) => self.visit_jsx_element(elem),
|
JSXAttributeValue::Element(elem) => self.visit_jsx_element(elem),
|
||||||
JSXAttributeValue::Fragment(elem) => self.visit_jsx_fragment(elem),
|
JSXAttributeValue::Fragment(elem) => self.visit_jsx_fragment(elem),
|
||||||
JSXAttributeValue::String(s) => self.visit_jsx_string(s),
|
JSXAttributeValue::StringLiteral(lit) => self.visit_string_literal(lit),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1097,7 +1097,7 @@ pub trait Visit<'a>: Sized {
|
||||||
JSXChild::Fragment(elem) => self.visit_jsx_fragment(elem),
|
JSXChild::Fragment(elem) => self.visit_jsx_fragment(elem),
|
||||||
JSXChild::ExpressionContainer(expr) => self.visit_jsx_expression_container(expr),
|
JSXChild::ExpressionContainer(expr) => self.visit_jsx_expression_container(expr),
|
||||||
JSXChild::Spread(expr) => self.visit_jsx_spread_child(expr),
|
JSXChild::Spread(expr) => self.visit_jsx_spread_child(expr),
|
||||||
JSXChild::Text(expr) => self.visit_jsx_string(expr),
|
JSXChild::Text(expr) => self.visit_jsx_text(expr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1105,8 +1105,8 @@ pub trait Visit<'a>: Sized {
|
||||||
self.visit_expression(&child.expression);
|
self.visit_expression(&child.expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_jsx_string(&mut self, child: &JSXString) {
|
fn visit_jsx_text(&mut self, child: &JSXText) {
|
||||||
let kind = AstKind::JSXString(self.alloc(child));
|
let kind = AstKind::JSXText(self.alloc(child));
|
||||||
self.enter_node(kind);
|
self.enter_node(kind);
|
||||||
self.leave_node(kind);
|
self.leave_node(kind);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -756,7 +756,7 @@ pub trait VisitMut<'a>: Sized {
|
||||||
}
|
}
|
||||||
JSXAttributeValue::Element(elem) => self.visit_jsx_element(elem),
|
JSXAttributeValue::Element(elem) => self.visit_jsx_element(elem),
|
||||||
JSXAttributeValue::Fragment(elem) => self.visit_jsx_fragment(elem),
|
JSXAttributeValue::Fragment(elem) => self.visit_jsx_fragment(elem),
|
||||||
JSXAttributeValue::String(_) => {}
|
JSXAttributeValue::StringLiteral(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1838,7 +1838,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttributeValue<'a> {
|
||||||
match self {
|
match self {
|
||||||
Self::Fragment(fragment) => fragment.gen(p, ctx),
|
Self::Fragment(fragment) => fragment.gen(p, ctx),
|
||||||
Self::Element(el) => el.gen(p, ctx),
|
Self::Element(el) => el.gen(p, ctx),
|
||||||
Self::String(lit) => lit.gen(p, ctx),
|
Self::StringLiteral(lit) => lit.gen(p, ctx),
|
||||||
Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx),
|
Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1909,7 +1909,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for JSXClosingFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const MINIFY: bool> Gen<MINIFY> for JSXString {
|
impl<const MINIFY: bool> Gen<MINIFY> for JSXText {
|
||||||
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
|
||||||
p.print_str(self.value.as_bytes());
|
p.print_str(self.value.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1556,7 +1556,7 @@ impl<'a> Gen for JSXAttributeValue<'a> {
|
||||||
match self {
|
match self {
|
||||||
Self::Fragment(fragment) => fragment.gen(p),
|
Self::Fragment(fragment) => fragment.gen(p),
|
||||||
Self::Element(el) => el.gen(p),
|
Self::Element(el) => el.gen(p),
|
||||||
Self::String(lit) => lit.gen(p),
|
Self::StringLiteral(lit) => lit.gen(p),
|
||||||
Self::ExpressionContainer(expr_container) => expr_container.gen(p),
|
Self::ExpressionContainer(expr_container) => expr_container.gen(p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1625,7 +1625,7 @@ impl Gen for JSXClosingFragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gen for JSXString {
|
impl Gen for JSXText {
|
||||||
fn gen(&self, p: &mut Formatter) {
|
fn gen(&self, p: &mut Formatter) {
|
||||||
p.print_str(self.value.as_bytes());
|
p.print_str(self.value.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use oxc_diagnostics::{
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
|
use oxc_semantic::AstNodeId;
|
||||||
use oxc_span::Span;
|
use oxc_span::Span;
|
||||||
|
|
||||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
use crate::{context::LintContext, rule::Rule, AstNode};
|
||||||
|
|
@ -40,12 +41,14 @@ impl Rule for NoUselessEscape {
|
||||||
{
|
{
|
||||||
check(
|
check(
|
||||||
ctx,
|
ctx,
|
||||||
|
node.id(),
|
||||||
literal.span.start,
|
literal.span.start,
|
||||||
&check_regexp(literal.span.source_text(ctx.source_text())),
|
&check_regexp(literal.span.source_text(ctx.source_text())),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AstKind::StringLiteral(literal) => check(
|
AstKind::StringLiteral(literal) => check(
|
||||||
ctx,
|
ctx,
|
||||||
|
node.id(),
|
||||||
literal.span.start,
|
literal.span.start,
|
||||||
&check_string(literal.span.source_text(ctx.source_text())),
|
&check_string(literal.span.source_text(ctx.source_text())),
|
||||||
),
|
),
|
||||||
|
|
@ -53,6 +56,7 @@ impl Rule for NoUselessEscape {
|
||||||
for template_element in &literal.quasis {
|
for template_element in &literal.quasis {
|
||||||
check(
|
check(
|
||||||
ctx,
|
ctx,
|
||||||
|
node.id(),
|
||||||
template_element.span.start - 1,
|
template_element.span.start - 1,
|
||||||
&check_template(template_element.span.source_text(ctx.source_text())),
|
&check_template(template_element.span.source_text(ctx.source_text())),
|
||||||
);
|
);
|
||||||
|
|
@ -63,8 +67,15 @@ impl Rule for NoUselessEscape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_within_jsx_attribute_item(id: AstNodeId, ctx: &LintContext) -> bool {
|
||||||
|
if matches!(ctx.nodes().parent_kind(id), Some(AstKind::JSXAttributeItem(_))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
fn check(ctx: &LintContext<'_>, start: u32, offsets: &[usize]) {
|
fn check(ctx: &LintContext<'_>, node_id: AstNodeId, start: u32, offsets: &[usize]) {
|
||||||
let source_text = ctx.source_text();
|
let source_text = ctx.source_text();
|
||||||
for offset in offsets {
|
for offset in offsets {
|
||||||
let offset = start as usize + offset;
|
let offset = start as usize + offset;
|
||||||
|
|
@ -72,7 +83,9 @@ fn check(ctx: &LintContext<'_>, start: u32, offsets: &[usize]) {
|
||||||
let offset = offset as u32;
|
let offset = offset as u32;
|
||||||
let len = c.len_utf8() as u32;
|
let len = c.len_utf8() as u32;
|
||||||
|
|
||||||
ctx.diagnostic(NoUselessEscapeDiagnostic(c, Span::new(offset - 1, offset + len)));
|
if !is_within_jsx_attribute_item(node_id, ctx) {
|
||||||
|
ctx.diagnostic(NoUselessEscapeDiagnostic(c, Span::new(offset - 1, offset + len)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ declare_oxc_lint!(
|
||||||
|
|
||||||
impl Rule for JsxNoCommentTextNodes {
|
impl Rule for JsxNoCommentTextNodes {
|
||||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
let AstKind::JSXString(jsx_text) = node.kind() else { return };
|
let AstKind::JSXText(jsx_text) = node.kind() else { return };
|
||||||
|
|
||||||
if control_patterns(&jsx_text.value) {
|
if control_patterns(&jsx_text.value) {
|
||||||
ctx.diagnostic(JsxNoCommentTextNodesDiagnostic(jsx_text.span));
|
ctx.diagnostic(JsxNoCommentTextNodesDiagnostic(jsx_text.span));
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ fn is_literal_ref_attribute(attr: &JSXAttribute, no_template_literals: bool) ->
|
||||||
JSXAttributeValue::ExpressionContainer(expr_container) => {
|
JSXAttributeValue::ExpressionContainer(expr_container) => {
|
||||||
contains_string_literal(expr_container, no_template_literals)
|
contains_string_literal(expr_container, no_template_literals)
|
||||||
}
|
}
|
||||||
JSXAttributeValue::String(_) => true,
|
JSXAttributeValue::StringLiteral(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ declare_oxc_lint!(
|
||||||
|
|
||||||
impl Rule for NoUnescapedEntities {
|
impl Rule for NoUnescapedEntities {
|
||||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
if let AstKind::JSXString(jsx_text) = node.kind() {
|
if let AstKind::JSXText(jsx_text) = node.kind() {
|
||||||
let source = jsx_text.span.source_text(ctx.source_text());
|
let source = jsx_text.span.source_text(ctx.source_text());
|
||||||
|
|
||||||
for (i, char) in source.chars().enumerate() {
|
for (i, char) in source.chars().enumerate() {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ impl Rule for TextEncodingIdentifierCase {
|
||||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||||
let (str, span) = match node.kind() {
|
let (str, span) = match node.kind() {
|
||||||
AstKind::StringLiteral(string_lit) => (&string_lit.value, string_lit.span),
|
AstKind::StringLiteral(string_lit) => (&string_lit.value, string_lit.span),
|
||||||
AstKind::JSXString(jsx_string) => (&jsx_string.value, jsx_string.span),
|
AstKind::JSXText(jsx_text) => (&jsx_text.value, jsx_text.span),
|
||||||
_ => {
|
_ => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ impl<'a> Parser<'a> {
|
||||||
.map(JSXChild::ExpressionContainer)
|
.map(JSXChild::ExpressionContainer)
|
||||||
.map(Some),
|
.map(Some),
|
||||||
// text
|
// text
|
||||||
Kind::JSXText => Ok(Some(JSXChild::Text(self.parse_jsx_string()))),
|
Kind::JSXText => Ok(Some(JSXChild::Text(self.parse_jsx_text()))),
|
||||||
_ => Err(self.unexpected()),
|
_ => Err(self.unexpected()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -333,7 +333,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
fn parse_jsx_attribute_value(&mut self) -> Result<JSXAttributeValue<'a>> {
|
fn parse_jsx_attribute_value(&mut self) -> Result<JSXAttributeValue<'a>> {
|
||||||
match self.cur_kind() {
|
match self.cur_kind() {
|
||||||
Kind::Str => Ok(JSXAttributeValue::String(self.parse_jsx_string())),
|
Kind::Str => self.parse_literal_string().map(JSXAttributeValue::StringLiteral),
|
||||||
Kind::LCurly => {
|
Kind::LCurly => {
|
||||||
let expr = self.parse_jsx_expression_container(false)?;
|
let expr = self.parse_jsx_expression_container(false)?;
|
||||||
Ok(JSXAttributeValue::ExpressionContainer(expr))
|
Ok(JSXAttributeValue::ExpressionContainer(expr))
|
||||||
|
|
@ -365,10 +365,10 @@ impl<'a> Parser<'a> {
|
||||||
Ok(self.ast.jsx_identifier(self.end_span(span), name))
|
Ok(self.ast.jsx_identifier(self.end_span(span), name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_jsx_string(&mut self) -> JSXString {
|
fn parse_jsx_text(&mut self) -> JSXText {
|
||||||
let span = self.start_span();
|
let span = self.start_span();
|
||||||
let value = Atom::from(self.cur_string().unwrap());
|
let value = Atom::from(self.cur_string().unwrap());
|
||||||
self.bump_any();
|
self.bump_any();
|
||||||
self.ast.jsx_string(self.end_span(span), value)
|
self.ast.jsx_text(self.end_span(span), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1871,7 +1871,7 @@ mod jsxattribute {
|
||||||
oxc_ast::ast::JSXExpression::EmptyExpression(_) => None,
|
oxc_ast::ast::JSXExpression::EmptyExpression(_) => None,
|
||||||
},
|
},
|
||||||
JSXAttributeValue::Fragment(_)
|
JSXAttributeValue::Fragment(_)
|
||||||
| JSXAttributeValue::String(_)
|
| JSXAttributeValue::StringLiteral(_)
|
||||||
| JSXAttributeValue::Element(_) => None,
|
| JSXAttributeValue::Element(_) => None,
|
||||||
})
|
})
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::{
|
||||||
|
|
||||||
pub fn jsx_attribute_to_constant_string<'a>(attr: &'a JSXAttribute<'a>) -> Option<String> {
|
pub fn jsx_attribute_to_constant_string<'a>(attr: &'a JSXAttribute<'a>) -> Option<String> {
|
||||||
attr.value.as_ref().and_then(|attr_value| match attr_value {
|
attr.value.as_ref().and_then(|attr_value| match attr_value {
|
||||||
JSXAttributeValue::String(slit) => slit.value.to_string().into(),
|
JSXAttributeValue::StringLiteral(slit) => slit.value.to_string().into(),
|
||||||
JSXAttributeValue::ExpressionContainer(expr) => match &expr.expression {
|
JSXAttributeValue::ExpressionContainer(expr) => match &expr.expression {
|
||||||
oxc_ast::ast::JSXExpression::Expression(expr) => expr_to_maybe_const_string(expr),
|
oxc_ast::ast::JSXExpression::Expression(expr) => expr_to_maybe_const_string(expr),
|
||||||
oxc_ast::ast::JSXExpression::EmptyExpression(_) => None,
|
oxc_ast::ast::JSXExpression::EmptyExpression(_) => None,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ pub enum Vertex<'a> {
|
||||||
JSXOpeningElement(Rc<JSXOpeningElementVertex<'a>>),
|
JSXOpeningElement(Rc<JSXOpeningElementVertex<'a>>),
|
||||||
JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>),
|
JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>),
|
||||||
JSXSpreadChild(&'a JSXSpreadChild<'a>),
|
JSXSpreadChild(&'a JSXSpreadChild<'a>),
|
||||||
JSXText(&'a JSXString),
|
JSXText(&'a JSXText),
|
||||||
ObjectLiteral(Rc<ObjectLiteralVertex<'a>>),
|
ObjectLiteral(Rc<ObjectLiteralVertex<'a>>),
|
||||||
NumberLiteral(Rc<NumberLiteralVertex<'a>>),
|
NumberLiteral(Rc<NumberLiteralVertex<'a>>),
|
||||||
Name(Rc<NameVertex<'a>>),
|
Name(Rc<NameVertex<'a>>),
|
||||||
|
|
|
||||||
|
|
@ -410,8 +410,8 @@ impl<'a> ReactJsx<'a> {
|
||||||
value: Option<&JSXAttributeValue<'a>>,
|
value: Option<&JSXAttributeValue<'a>>,
|
||||||
) -> Expression<'a> {
|
) -> Expression<'a> {
|
||||||
match value {
|
match value {
|
||||||
Some(JSXAttributeValue::String(s)) => {
|
Some(JSXAttributeValue::StringLiteral(s)) => {
|
||||||
let jsx_text = Self::decode_entities(&s.value);
|
let jsx_text = Self::decode_entities(s.value.as_str());
|
||||||
let literal = StringLiteral::new(s.span, jsx_text.into());
|
let literal = StringLiteral::new(s.span, jsx_text.into());
|
||||||
self.ast.literal_string_expression(literal)
|
self.ast.literal_string_expression(literal)
|
||||||
}
|
}
|
||||||
|
|
@ -449,7 +449,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
|
|
||||||
fn transform_jsx_child(&mut self, child: &JSXChild<'a>) -> Option<Expression<'a>> {
|
fn transform_jsx_child(&mut self, child: &JSXChild<'a>) -> Option<Expression<'a>> {
|
||||||
match child {
|
match child {
|
||||||
JSXChild::Text(text) => self.transform_jsx_text(text),
|
JSXChild::Text(text) => self.transform_jsx_text(text.value.as_str()),
|
||||||
JSXChild::ExpressionContainer(e) => match &e.expression {
|
JSXChild::ExpressionContainer(e) => match &e.expression {
|
||||||
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
||||||
JSXExpression::EmptyExpression(_) => None,
|
JSXExpression::EmptyExpression(_) => None,
|
||||||
|
|
@ -463,8 +463,8 @@ impl<'a> ReactJsx<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_jsx_text(&self, text: &JSXString) -> Option<Expression<'a>> {
|
fn transform_jsx_text(&self, text: &str) -> Option<Expression<'a>> {
|
||||||
Self::fixup_whitespace_and_decode_entities(text.value.as_str()).map(|s| {
|
Self::fixup_whitespace_and_decode_entities(text).map(|s| {
|
||||||
let s = StringLiteral::new(SPAN, s.into());
|
let s = StringLiteral::new(SPAN, s.into());
|
||||||
self.ast.literal_string_expression(s)
|
self.ast.literal_string_expression(s)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,23 @@
|
||||||
codegen_typescript Summary:
|
codegen_typescript Summary:
|
||||||
AST Parsed : 5063/5063 (100.00%)
|
AST Parsed : 5063/5063 (100.00%)
|
||||||
Positive Passed: 4996/5063 (98.68%)
|
Positive Passed: 5043/5063 (99.60%)
|
||||||
Expect to Parse: "compiler/binopAssignmentShouldHaveType.ts"
|
Expect to Parse: "compiler/binopAssignmentShouldHaveType.ts"
|
||||||
Expect to Parse: "compiler/castExpressionParentheses.ts"
|
Expect to Parse: "compiler/castExpressionParentheses.ts"
|
||||||
Expect to Parse: "compiler/contextuallyTypedJsxAttribute.ts"
|
|
||||||
Expect to Parse: "compiler/contextuallyTypedJsxChildren.tsx"
|
|
||||||
Expect to Parse: "compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts"
|
Expect to Parse: "compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts"
|
||||||
Expect to Parse: "compiler/identityRelationNeverTypes.ts"
|
Expect to Parse: "compiler/identityRelationNeverTypes.ts"
|
||||||
Expect to Parse: "compiler/jsxFragmentFactoryNoUnusedLocals.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxHasLiteralType.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxInferenceProducesLiteralAsExpected.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxIntrinsicUnions.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxLibraryManagedAttributesUnusedGeneric.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxMultilineAttributeStringValues.tsx"
|
Expect to Parse: "compiler/jsxMultilineAttributeStringValues.tsx"
|
||||||
Expect to Parse: "compiler/jsxMultilineAttributeValuesReact.tsx"
|
Expect to Parse: "compiler/jsxMultilineAttributeValuesReact.tsx"
|
||||||
Expect to Parse: "compiler/jsxNamespacedNameNotComparedToNonMatchingIndexSignature.tsx"
|
Expect to Parse: "compiler/jsxNamespacedNameNotComparedToNonMatchingIndexSignature.tsx"
|
||||||
Expect to Parse: "compiler/jsxSpreadFirstUnionNoErrors.tsx"
|
|
||||||
Expect to Parse: "compiler/jsxSpreadTag.ts"
|
|
||||||
Expect to Parse: "compiler/keywordInJsxIdentifier.tsx"
|
|
||||||
Expect to Parse: "compiler/localClassesInLoop.ts"
|
Expect to Parse: "compiler/localClassesInLoop.ts"
|
||||||
Expect to Parse: "compiler/localClassesInLoop_ES6.ts"
|
Expect to Parse: "compiler/localClassesInLoop_ES6.ts"
|
||||||
Expect to Parse: "compiler/reactReadonlyHOCAssignabilityReal.tsx"
|
|
||||||
Expect to Parse: "compiler/tsxAttributeQuickinfoTypesSameAsObjectLiteral.tsx"
|
|
||||||
Expect to Parse: "compiler/tsxSpreadDoesNotReportExcessProps.tsx"
|
|
||||||
Expect to Parse: "compiler/tsxUnionMemberChecksFilterDataProps.tsx"
|
|
||||||
Expect to Parse: "compiler/typeAliasDeclarationEmit3.ts"
|
Expect to Parse: "compiler/typeAliasDeclarationEmit3.ts"
|
||||||
Expect to Parse: "compiler/typeInferenceWithExcessPropertiesJsx.tsx"
|
|
||||||
Expect to Parse: "conformance/constEnums/constEnum4.ts"
|
Expect to Parse: "conformance/constEnums/constEnum4.ts"
|
||||||
Expect to Parse: "conformance/decorators/legacyDecorators-contextualTypes.ts"
|
Expect to Parse: "conformance/decorators/legacyDecorators-contextualTypes.ts"
|
||||||
Expect to Parse: "conformance/esDecorators/esDecorators-contextualTypes.ts"
|
Expect to Parse: "conformance/esDecorators/esDecorators-contextualTypes.ts"
|
||||||
Expect to Parse: "conformance/expressions/asOperator/asOpEmitParens.ts"
|
Expect to Parse: "conformance/expressions/asOperator/asOpEmitParens.ts"
|
||||||
Expect to Parse: "conformance/expressions/elementAccess/letIdentifierInElementAccess01.ts"
|
Expect to Parse: "conformance/expressions/elementAccess/letIdentifierInElementAccess01.ts"
|
||||||
Expect to Parse: "conformance/jsx/checkJsxChildrenProperty1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/checkJsxChildrenProperty6.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/checkJsxChildrenProperty8.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/checkJsxIntersectionElementPropsType.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/jsxReactTestSuite.tsx"
|
Expect to Parse: "conformance/jsx/jsxReactTestSuite.tsx"
|
||||||
Expect to Parse: "conformance/jsx/jsxs/jsxJsxsCjsTransformKeyProp.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxAttributeResolution16.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxElementResolution.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxElementResolution5.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxEmit1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxGenericAttributesType3.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxGenericAttributesType4.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxGenericAttributesType5.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxGenericAttributesType6.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxGenericAttributesType7.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxInArrowFunction.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName1.tsx"
|
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName1.tsx"
|
||||||
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName2.tsx"
|
Expect to Parse: "conformance/jsx/tsxNamespacedAttributeName2.tsx"
|
||||||
Expect to Parse: "conformance/jsx/tsxReactComponentWithDefaultTypeParameter1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxReactComponentWithDefaultTypeParameter2.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxReactEmit1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxReactEmitEntities.tsx"
|
Expect to Parse: "conformance/jsx/tsxReactEmitEntities.tsx"
|
||||||
Expect to Parse: "conformance/jsx/tsxReactEmitNesting.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxSpreadAttributesResolution11.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxSpreadAttributesResolution13.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxSpreadAttributesResolution15.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxSpreadAttributesResolution3.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxSpreadAttributesResolution8.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentOverload2.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentOverload3.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentOverload6.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentWithDefaultTypeParameter1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments1.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments3.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxStatelessFunctionComponentsWithTypeArguments5.tsx"
|
|
||||||
Expect to Parse: "conformance/jsx/tsxTypeErrors.tsx"
|
|
||||||
Expect to Parse: "conformance/types/thisType/thisTypeInFunctions4.ts"
|
Expect to Parse: "conformance/types/thisType/thisTypeInFunctions4.ts"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue