diff --git a/crates/oxc_query/src/adapter.rs b/crates/oxc_query/src/adapter.rs index 1dfd23764..295a4aa2d 100644 --- a/crates/oxc_query/src/adapter.rs +++ b/crates/oxc_query/src/adapter.rs @@ -121,11 +121,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { property_name.as_ref(), resolve_info, ), - "JSXOpeningElement" => super::properties::resolve_jsxopening_element_property( - contexts, - property_name.as_ref(), - resolve_info, - ), + "JSXOpeningElementAST" | "JSXOpeningElement" => { + super::properties::resolve_jsxopening_element_property( + contexts, + property_name.as_ref(), + resolve_info, + ) + } "JSXText" => super::properties::resolve_jsxtext_property( contexts, property_name.as_ref(), @@ -295,12 +297,15 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { parameters, resolve_info, ), - "JSXOpeningElement" => super::edges::resolve_jsxopening_element_edge( - contexts, - edge_name.as_ref(), - parameters, - resolve_info, - ), + "JSXOpeningElementAST" | "JSXOpeningElement" => { + super::edges::resolve_jsxopening_element_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ) + } "JSXSpreadAttribute" => super::edges::resolve_jsxspread_attribute_edge( contexts, edge_name.as_ref(), diff --git a/crates/oxc_query/src/edges.rs b/crates/oxc_query/src/edges.rs index 11665e90f..79033d48e 100644 --- a/crates/oxc_query/src/edges.rs +++ b/crates/oxc_query/src/edges.rs @@ -911,7 +911,7 @@ mod jsxelement { }; use super::{super::vertex::Vertex, get_span}; - use crate::vertex::JSXElementVertex; + use crate::vertex::{JSXElementVertex, JSXOpeningElementVertex}; macro_rules! child_edge_iter { ($contexts: ident, $vertex_type: ident, $jsx_child_type: ident) => { @@ -990,12 +990,17 @@ mod jsxelement { ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { resolve_neighbors_with(contexts, |v| { Box::new(std::iter::once(Vertex::JSXOpeningElement( - &v.as_jsx_element() - .unwrap_or_else(|| { - panic!("expected to have a JSXElement vertex, instead have: {v:#?}") - }) - .element - .opening_element, + JSXOpeningElementVertex { + ast_node: None, + opening_element: &v + .as_jsx_element() + .unwrap_or_else(|| { + panic!("expected to have a JSXElement vertex, instead have: {v:#?}") + }) + .element + .opening_element, + } + .into(), ))) }) } @@ -1073,11 +1078,14 @@ pub(super) fn resolve_jsxopening_element_edge<'a, 'b: 'a>( edge_name: &str, _parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "attribute" => jsxopening_element::attribute(contexts, resolve_info), "span" => jsxopening_element::span(contexts, resolve_info), "spread_attribute" => jsxopening_element::spread_attribute(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), _ => { unreachable!( "attempted to resolve unexpected edge '{edge_name}' on type 'JSXOpeningElement'" @@ -1105,6 +1113,7 @@ mod jsxopening_element { .unwrap_or_else(|| { panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}") }) + .opening_element .attributes .iter() .filter_map(|attr| match attr { @@ -1132,6 +1141,7 @@ mod jsxopening_element { .unwrap_or_else(|| { panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}") }) + .opening_element .attributes .iter() .filter_map(|attr| match attr { diff --git a/crates/oxc_query/src/properties.rs b/crates/oxc_query/src/properties.rs index b07f0e37a..c38bacad6 100644 --- a/crates/oxc_query/src/properties.rs +++ b/crates/oxc_query/src/properties.rs @@ -304,14 +304,14 @@ pub(super) fn resolve_jsxopening_element_property<'a, 'b: 'a>( let jsx = v.as_jsx_opening_element().unwrap_or_else(|| { panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}") }); - (jsx.attributes.len() as u64).into() + (jsx.opening_element.attributes.len() as u64).into() }), "name" => resolve_property_with(contexts, |v| { - let jsx = v.as_jsx_opening_element().unwrap_or_else(|| { + let data = v.as_jsx_opening_element().unwrap_or_else(|| { panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}") }); - jsx_element_name_to_string(&jsx.name).into() + jsx_element_name_to_string(&data.opening_element.name).into() }), _ => { unreachable!( diff --git a/crates/oxc_query/src/vertex.rs b/crates/oxc_query/src/vertex.rs index eb44ad0ec..78fa2666a 100644 --- a/crates/oxc_query/src/vertex.rs +++ b/crates/oxc_query/src/vertex.rs @@ -37,7 +37,7 @@ pub enum Vertex<'a> { JSXElement(Rc>), JSXExpressionContainer(&'a JSXExpressionContainer<'a>), JSXFragment(&'a JSXFragment<'a>), - JSXOpeningElement(&'a JSXOpeningElement<'a>), + JSXOpeningElement(Rc>), JSXSpreadAttribute(&'a JSXSpreadAttribute<'a>), JSXSpreadChild(&'a JSXSpreadChild<'a>), JSXText(&'a JSXText), @@ -73,7 +73,7 @@ impl<'a> Vertex<'a> { Self::JSXElement(data) => data.element.span, Self::JSXExpressionContainer(data) => data.span, Self::JSXFragment(data) => data.span, - Self::JSXOpeningElement(data) => data.span, + Self::JSXOpeningElement(data) => data.opening_element.span, Self::JSXSpreadAttribute(data) => data.span, Self::JSXSpreadChild(data) => data.span, Self::JSXText(data) => data.span, @@ -104,6 +104,7 @@ impl<'a> Vertex<'a> { Vertex::VariableDeclaration(data) => data.ast_node.map(|x| x.id()), Vertex::ObjectLiteral(data) => data.ast_node.map(|x| x.id()), Vertex::ReturnStatementAST(data) => data.ast_node.map(|x| x.id()), + Vertex::JSXOpeningElement(data) => data.ast_node.map(|x| x.id()), Vertex::DefaultImport(_) | Vertex::AssignmentType(_) | Vertex::ClassMethod(_) @@ -116,7 +117,6 @@ impl<'a> Vertex<'a> { | Vertex::JSXText(_) | Vertex::JSXSpreadChild(_) | Vertex::JSXSpreadAttribute(_) - | Vertex::JSXOpeningElement(_) | Vertex::PathPart(_) | Vertex::Url(_) | Vertex::Type(_) @@ -164,7 +164,7 @@ impl Typename for Vertex<'_> { Vertex::JSXElement(jsx) => jsx.typename(), Vertex::JSXExpressionContainer(_) => "JSXExpressionContainer", Vertex::JSXFragment(_) => "JSXFragment", - Vertex::JSXOpeningElement(_) => "JSXOpeningElement", + Vertex::JSXOpeningElement(jsx) => jsx.typename(), Vertex::JSXSpreadAttribute(_) => "JSXSpreadAttribute", Vertex::JSXSpreadChild(_) => "JSXSpreadChild", Vertex::JSXText(_) => "JSXText", @@ -209,6 +209,9 @@ impl<'a> From> for Vertex<'a> { AstKind::ObjectExpression(objexpr) => Self::ObjectLiteral( ObjectLiteralVertex { ast_node: Some(ast_node), object_expression: objexpr }.into(), ), + AstKind::JSXOpeningElement(opening_element) => Self::JSXOpeningElement( + JSXOpeningElementVertex { ast_node: Some(ast_node), opening_element }.into(), + ), _ => Vertex::ASTNode(ast_node), } } @@ -398,3 +401,20 @@ impl<'a> Typename for ObjectLiteralVertex<'a> { } } } + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct JSXOpeningElementVertex<'a> { + pub ast_node: Option>, + pub opening_element: &'a JSXOpeningElement<'a>, +} + +impl<'a> Typename for JSXOpeningElementVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "JSXOpeningElementAST" + } else { + "JSXOpeningElement" + } + } +}