From 3b3babed2e3b8197bd401a281b9bd9fcaa1d8b57 Mon Sep 17 00:00:00 2001 From: u9g Date: Sun, 20 Aug 2023 02:54:25 -0400 Subject: [PATCH] feat(query): Add types and add field to Argument (#765) ```diff + Argument.is_spread + DoWhileStatement + DoWhileStatement implements HasSpan + DoWhileStatement implements Statement + DoWhileStatement.body + DoWhileStatement.condition + DoWhileStatementAST + DoWhileStatementAST implements HasSpan + DoWhileStatementAST implements Statement + DoWhileStatementAST implements DoWhileStatement + DoWhileStatementAST implements ASTNode + ForStatement + ForStatement implements HasSpan + ForStatement implements Statement + ForStatement.body + ForStatement.step + ForStatement.condition + ForStatementAST + ForStatementAST implements HasSpan + ForStatementAST implements Statement + ForStatementAST implements ASTNode + ForStatementAST implements ForStatement + New + New implements Expression + New implements HasSpan + New.callee + New.argument + NewAST + NewAST implements Expression + NewAST implements HasSpan + NewAST implements New + NewAST implements ASTNode + TernaryExpression + TernaryExpression implements HasSpan + TernaryExpression implements Expression + TernaryExpression.condition + TernaryExpression.if_true + TernaryExpression.if_false + TernaryExpressionAST + TernaryExpressionAST implements TernaryExpression + TernaryExpressionAST implements HasSpan + TernaryExpressionAST implements ASTNode + TernaryExpressionAST implements Expression + Throw + Throw implements HasSpan + Throw implements Expression + Throw.to_throw + ThrowAST + ThrowAST implements HasSpan + ThrowAST implements Throw + ThrowAST implements ASTNode + ThrowAST implements Expression ``` --- crates/oxc_query/src/adapter.rs | 61 ++++ crates/oxc_query/src/edges.rs | 453 ++++++++++++++++++++++++++-- crates/oxc_query/src/properties.rs | 74 ++++- crates/oxc_query/src/schema.graphql | 248 +++++++++++++-- crates/oxc_query/src/util.rs | 13 + crates/oxc_query/src/vertex.rs | 135 +++++++++ 6 files changed, 926 insertions(+), 58 deletions(-) diff --git a/crates/oxc_query/src/adapter.rs b/crates/oxc_query/src/adapter.rs index 1b77357c3..1f7ada1f0 100644 --- a/crates/oxc_query/src/adapter.rs +++ b/crates/oxc_query/src/adapter.rs @@ -71,6 +71,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { return resolve_property_with(contexts, |v| v.typename().into()); } match type_name.as_ref() { + "ArgumentAST" | "Argument" => super::properties::resolve_argument_property( + contexts, + property_name.as_ref(), + resolve_info, + ), "ArrowFunctionAST" | "ArrowFunction" => { super::properties::resolve_arrow_function_property( contexts, @@ -174,6 +179,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { property_name.as_ref(), resolve_info, ), + "NewAST" | "New" => super::properties::resolve_new_property( + contexts, + property_name.as_ref(), + resolve_info, + ), "NumberLiteralAST" | "NumberLiteral" => { super::properties::resolve_number_literal_property( contexts, @@ -220,6 +230,18 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { property_name.as_ref(), resolve_info, ), + "ThrowAST" | "Throw" => super::properties::resolve_throw_property( + contexts, + property_name.as_ref(), + resolve_info, + ), + "TernaryExpressionAST" | "TernaryExpression" => { + super::properties::resolve_ternary_expression_property( + contexts, + property_name.as_ref(), + resolve_info, + ) + } "UnaryExpressionAST" | "UnaryExpression" => { super::properties::resolve_unary_expression_property( contexts, @@ -316,6 +338,15 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { parameters, resolve_info, ), + "DoWhileStatementAST" | "DoWhileStatement" => { + super::edges::resolve_do_while_statement_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ) + } "Expression" => super::edges::resolve_expression_edge( contexts, edge_name.as_ref(), @@ -365,6 +396,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { resolve_info, self, ), + "ForStatementAST" | "ForStatement" => super::edges::resolve_for_statement_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ), "HasSpan" => super::edges::resolve_has_span_edge( contexts, edge_name.as_ref(), @@ -472,6 +510,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { resolve_info, self, ), + "NewAST" | "New" => super::edges::resolve_new_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ), "NumberLiteralAST" | "NumberLiteral" => super::edges::resolve_number_literal_edge( contexts, edge_name.as_ref(), @@ -554,6 +599,22 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { parameters, resolve_info, ), + "TernaryExpression" | "TernaryExpressionAST" => { + super::edges::resolve_ternary_expression_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ) + } + "Throw" | "ThrowAST" => super::edges::resolve_throw_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ), "TypeAnnotation" | "TypeAnnotationAST" => super::edges::resolve_type_annotation_edge( contexts, edge_name.as_ref(), diff --git a/crates/oxc_query/src/edges.rs b/crates/oxc_query/src/edges.rs index 681994eef..6c3287c44 100644 --- a/crates/oxc_query/src/edges.rs +++ b/crates/oxc_query/src/edges.rs @@ -4,19 +4,19 @@ use trustfall::provider::{ }; use super::vertex::Vertex; -use crate::Adapter; +use crate::{util::strip_parens_from_expr, Adapter}; pub(super) fn resolve_arrow_function_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "span" => arrow_function::span(contexts, resolve_info), "parameter" => arrow_function::parameter(contexts, resolve_info), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), _ => { @@ -158,10 +158,14 @@ fn parents<'a, 'b: 'a>( fn strip_parens<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, + parameters: &EdgeParameters, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { - trustfall::provider::resolve_neighbors_with(contexts, |v| { + let strip_all = parameters["strip_all"].as_bool().unwrap_or(true); + trustfall::provider::resolve_neighbors_with(contexts, move |v| { Box::new(std::iter::once(match v { - Vertex::Expression(Expression::ParenthesizedExpression(e)) => (&e.expression).into(), + Vertex::Expression(Expression::ParenthesizedExpression(e)) => { + strip_parens_from_expr(&e.expression, strip_all).into() + } _ => v.clone(), })) }) @@ -555,12 +559,83 @@ mod default_import { } } -pub(super) fn resolve_dot_property_edge<'a, 'b: 'a>( +pub(super) fn resolve_do_while_statement_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, _parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, +) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + match edge_name { + "condition" => do_while_statement::condition(contexts, resolve_info), + "body" => do_while_statement::body(contexts, resolve_info), + "span" => do_while_statement::span(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), + _ => { + unreachable!( + "attempted to resolve unexpected edge '{edge_name}' on type 'DoWhileStatement'" + ) + } + } +} + +mod do_while_statement { + use trustfall::provider::{ + resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, + VertexIterator, + }; + + use super::super::vertex::Vertex; + + pub(super) fn condition<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_do_while_statement() + .unwrap_or_else(|| { + panic!("expected to have a dowhilestatement vertex, instead have: {v:#?}") + }) + .do_while_statement + .test) + .into(), + )) + }) + } + + pub(super) fn body<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_do_while_statement() + .unwrap_or_else(|| { + panic!("expected to have a dowhilestatement vertex, instead have: {v:#?}") + }) + .do_while_statement + .body) + .into(), + )) + }) + } + + pub(super) fn span<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + super::get_span(contexts) + } +} + +pub(super) fn resolve_dot_property_edge<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + edge_name: &str, + parameters: &EdgeParameters, + resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "span" => dot_property::span(contexts, resolve_info), @@ -568,11 +643,9 @@ pub(super) fn resolve_dot_property_edge<'a, 'b: 'a>( "accessed_property" => dot_property::accessed_property(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { - unreachable!( - "attempted to resolve unexpected edge '{edge_name}' on type 'ClassProperty'" - ) + unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'DotProperty'") } } } @@ -636,12 +709,12 @@ mod dot_property { pub(super) fn resolve_expression_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "span" => expression::span(contexts, resolve_info), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Expression'") } @@ -721,13 +794,13 @@ mod expression_statement { pub(super) fn resolve_function_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "parameter" => function::parameter(contexts, resolve_info), "span" => function::span(contexts, resolve_info), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Function'") } @@ -814,14 +887,14 @@ mod function_body { pub(super) fn resolve_fn_declaration_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { match edge_name { "span" => fn_declaration::span(contexts, resolve_info), "parameter" => fn_declaration::parameter(contexts, resolve_info), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), _ => { @@ -1019,7 +1092,7 @@ mod file { pub(super) fn resolve_fn_call_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -1029,7 +1102,7 @@ pub(super) fn resolve_fn_call_edge<'a, 'b: 'a>( "argument" => fn_call::argument(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'FnCall'") } @@ -1091,6 +1164,101 @@ mod fn_call { } } +pub(super) fn resolve_for_statement_edge<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + edge_name: &str, + _parameters: &EdgeParameters, + resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, +) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + match edge_name { + "span" => for_statement::span(contexts, resolve_info), + "condition" => for_statement::condition(contexts, resolve_info), + "step" => for_statement::step(contexts, resolve_info), + "body" => for_statement::body(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), + _ => { + unreachable!( + "attempted to resolve unexpected edge '{edge_name}' on type 'ForStatement'" + ) + } + } +} + +mod for_statement { + use std::convert::Into; + + use trustfall::provider::{ + resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, + VertexIterator, + }; + + use super::super::vertex::Vertex; + + pub(super) fn condition<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new( + v.as_for_statement() + .unwrap_or_else(|| { + panic!("expected to have a forstatement vertex, instead have: {v:#?}") + }) + .for_statement + .test + .as_ref() + .map(Into::into) + .into_iter(), + ) + }) + } + + pub(super) fn step<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new( + v.as_for_statement() + .unwrap_or_else(|| { + panic!("expected to have a forstatement vertex, instead have: {v:#?}") + }) + .for_statement + .update + .as_ref() + .map(Into::into) + .into_iter(), + ) + }) + } + + pub(super) fn body<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_for_statement() + .unwrap_or_else(|| { + panic!("expected to have a forstatement vertex, instead have: {v:#?}") + }) + .for_statement + .body) + .into(), + )) + }) + } + + pub(super) fn span<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + super::get_span(contexts) + } +} + pub(super) fn resolve_has_span_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, @@ -1462,7 +1630,7 @@ mod jsxattribute { pub(super) fn resolve_jsxelement_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -1478,7 +1646,7 @@ pub(super) fn resolve_jsxelement_edge<'a, 'b: 'a>( "span" => jsxelement::span(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'JSXElement'") } @@ -1831,7 +1999,7 @@ mod jsxtext { pub(super) fn resolve_logical_expression_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -1841,7 +2009,7 @@ pub(super) fn resolve_logical_expression_edge<'a, 'b: 'a>( "right" => logical_expression::right(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!( "attempted to resolve unexpected edge '{edge_name}' on type 'LogicalExpression'" @@ -1963,10 +2131,85 @@ mod name { } } +pub(super) fn resolve_new_edge<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + edge_name: &str, + parameters: &EdgeParameters, + resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, +) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + match edge_name { + "span" => new::span(contexts, resolve_info), + "callee" => new::callee(contexts, resolve_info), + "argument" => new::argument(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), + "strip_parens" => strip_parens(contexts, parameters), + _ => { + unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'New'") + } + } +} + +mod new { + use trustfall::provider::{ + resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, + VertexIterator, + }; + + use crate::vertex::ArgumentVertex; + + use super::{super::vertex::Vertex, get_span}; + + pub(super) fn callee<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_new() + .unwrap_or_else(|| { + panic!("expected to have a new vertex, instead have: {v:#?}") + }) + .new_expression + .callee) + .into(), + )) + }) + } + + pub(super) fn argument<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new( + v.as_new() + .unwrap_or_else(|| { + panic!("expected to have a new vertex, instead have: {v:#?}") + }) + .new_expression + .arguments + .iter() + .map(|argument| { + Vertex::Argument(ArgumentVertex { ast_node: None, argument }.into()) + }), + ) + }) + } + + pub(super) fn span<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + get_span(contexts) + } +} + pub(super) fn resolve_number_literal_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -1974,7 +2217,7 @@ pub(super) fn resolve_number_literal_edge<'a, 'b: 'a>( "span" => number_literal::span(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!( "attempted to resolve unexpected edge '{edge_name}' on type 'NumberLiteral'" @@ -2095,7 +2338,7 @@ pub(super) fn resolve_object_literal_edge<'a, 'b: 'a>( "entry" => object_literal::entry(contexts, parameters, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!( "attempted to resolve unexpected edge '{edge_name}' on type 'ObjectLiteral'" @@ -2353,7 +2596,7 @@ mod parameter { pub(super) fn resolve_reassignment_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -2363,7 +2606,7 @@ pub(super) fn resolve_reassignment_edge<'a, 'b: 'a>( "right" => reassignment::right(contexts, resolve_info), "parent" => parents(contexts, adapter), "ancestor" => ancestors(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!( "attempted to resolve unexpected edge '{edge_name}' on type 'Reassignment'" @@ -2635,6 +2878,148 @@ mod resolve_spread_into_object_edge { } } +pub(super) fn resolve_ternary_expression_edge<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + edge_name: &str, + parameters: &EdgeParameters, + resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, +) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + match edge_name { + "span" => ternary_expression::span(contexts, resolve_info), + "condition" => ternary_expression::condition(contexts, resolve_info), + "if_true" => ternary_expression::if_true(contexts, resolve_info), + "if_false" => ternary_expression::if_false(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), + "strip_parens" => strip_parens(contexts, parameters), + _ => { + unreachable!( + "attempted to resolve unexpected edge '{edge_name}' on type 'TernaryExpression'" + ) + } + } +} + +mod ternary_expression { + use trustfall::provider::{ + resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, + VertexIterator, + }; + + use super::{super::vertex::Vertex, get_span}; + + pub(super) fn condition<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_ternary_expression() + .unwrap_or_else(|| { + panic!("expected to have a ternaryexpression vertex, instead have: {v:#?}") + }) + .conditional_expression + .test) + .into(), + )) + }) + } + + pub(super) fn if_true<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_ternary_expression() + .unwrap_or_else(|| { + panic!("expected to have a ternaryexpression vertex, instead have: {v:#?}") + }) + .conditional_expression + .consequent) + .into(), + )) + }) + } + + pub(super) fn if_false<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_ternary_expression() + .unwrap_or_else(|| { + panic!("expected to have a ternaryexpression vertex, instead have: {v:#?}") + }) + .conditional_expression + .alternate) + .into(), + )) + }) + } + + pub(super) fn span<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + get_span(contexts) + } +} + +pub(super) fn resolve_throw_edge<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + edge_name: &str, + parameters: &EdgeParameters, + resolve_info: &ResolveEdgeInfo, + adapter: &'a Adapter<'b>, +) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + match edge_name { + "span" => throw::span(contexts, resolve_info), + "to_throw" => throw::to_throw(contexts, resolve_info), + "ancestor" => ancestors(contexts, adapter), + "parent" => parents(contexts, adapter), + "strip_parens" => strip_parens(contexts, parameters), + _ => { + unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Throw'") + } + } +} + +mod throw { + use trustfall::provider::{ + resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, + VertexIterator, + }; + + use super::{super::vertex::Vertex, get_span}; + + pub(super) fn to_throw<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + resolve_neighbors_with(contexts, |v| { + Box::new(std::iter::once( + (&v.as_throw() + .unwrap_or_else(|| { + panic!("expected to have a throw vertex, instead have: {v:#?}") + }) + .throw_statement + .argument) + .into(), + )) + }) + } + + pub(super) fn span<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + _resolve_info: &ResolveEdgeInfo, + ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { + get_span(contexts) + } +} + pub(super) fn resolve_type_annotation_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, @@ -2748,7 +3133,7 @@ mod type_ { pub(super) fn resolve_unary_expression_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -2757,9 +3142,11 @@ pub(super) fn resolve_unary_expression_edge<'a, 'b: 'a>( "value" => unary_expression::value(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { - unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Type_'") + unreachable!( + "attempted to resolve unexpected edge '{edge_name}' on type 'UnaryExpression'" + ) } } } @@ -2932,7 +3319,7 @@ mod variable_declaration { pub(super) fn resolve_var_ref_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, - _parameters: &EdgeParameters, + parameters: &EdgeParameters, resolve_info: &ResolveEdgeInfo, adapter: &'a Adapter<'b>, ) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> { @@ -2940,7 +3327,7 @@ pub(super) fn resolve_var_ref_edge<'a, 'b: 'a>( "span" => var_ref::span(contexts, resolve_info), "ancestor" => ancestors(contexts, adapter), "parent" => parents(contexts, adapter), - "strip_parens" => strip_parens(contexts), + "strip_parens" => strip_parens(contexts, parameters), _ => { unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'VarRef'") } @@ -2977,7 +3364,7 @@ pub(super) fn resolve_while_statement_edge<'a, 'b: 'a>( "parent" => parents(contexts, adapter), _ => { unreachable!( - "attempted to resolve unexpected edge '{edge_name}' on type 'WhileStateent'" + "attempted to resolve unexpected edge '{edge_name}' on type 'WhileStatement'" ) } } diff --git a/crates/oxc_query/src/properties.rs b/crates/oxc_query/src/properties.rs index 7de7a1929..d11f5b68d 100644 --- a/crates/oxc_query/src/properties.rs +++ b/crates/oxc_query/src/properties.rs @@ -17,6 +17,31 @@ use crate::{ Adapter, }; +pub(super) fn resolve_argument_property<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + property_name: &str, + _resolve_info: &ResolveInfo, +) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> { + match property_name { + "is_spread" => resolve_property_with(contexts, |v| { + matches!( + v.as_argument() + .unwrap_or_else(|| { + panic!("expected to have an argument vertex, instead have: {v:#?}") + }) + .argument, + oxc_ast::ast::Argument::SpreadElement(_) + ) + .into() + }), + _ => { + unreachable!( + "attempted to read unexpected property '{property_name}' on type 'Argument'" + ) + } + } +} + pub(super) fn resolve_arrow_function_property<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, property_name: &str, @@ -30,7 +55,7 @@ pub(super) fn resolve_arrow_function_property<'a, 'b: 'a>( }), _ => { unreachable!( - "attempted to read unexpected property '{property_name}' on type 'AssignmentType'" + "attempted to read unexpected property '{property_name}' on type 'ArrowFunction'" ) } } @@ -459,6 +484,21 @@ pub(super) fn resolve_name_property<'a, 'b: 'a>( } } +pub(super) fn resolve_new_property<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + property_name: &str, + _resolve_info: &ResolveInfo, +) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> { + match property_name { + "as_constant_string" => resolve_property_with(contexts, |v| { + v.as_constant_string().map_or(FieldValue::Null, Into::into) + }), + _ => { + unreachable!("attempted to read unexpected property '{property_name}' on type 'New'") + } + } +} + pub(super) fn resolve_number_literal_property<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, property_name: &str, @@ -682,6 +722,38 @@ pub(super) fn resolve_specific_import_property<'a, 'b: 'a>( } } +pub(super) fn resolve_throw_property<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + property_name: &str, + _resolve_info: &ResolveInfo, +) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> { + match property_name { + "as_constant_string" => resolve_property_with(contexts, |v| { + v.as_constant_string().map_or(FieldValue::Null, Into::into) + }), + _ => { + unreachable!("attempted to read unexpected property '{property_name}' on type 'Throw'") + } + } +} + +pub(super) fn resolve_ternary_expression_property<'a, 'b: 'a>( + contexts: ContextIterator<'a, Vertex<'b>>, + property_name: &str, + _resolve_info: &ResolveInfo, +) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> { + match property_name { + "as_constant_string" => resolve_property_with(contexts, |v| { + v.as_constant_string().map_or(FieldValue::Null, Into::into) + }), + _ => { + unreachable!( + "attempted to read unexpected property '{property_name}' on type 'TernaryExpression'" + ) + } + } +} + pub(super) fn resolve_unary_expression_property<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, property_name: &str, diff --git a/crates/oxc_query/src/schema.graphql b/crates/oxc_query/src/schema.graphql index d785c98e3..dd6c3744c 100644 --- a/crates/oxc_query/src/schema.graphql +++ b/crates/oxc_query/src/schema.graphql @@ -287,7 +287,10 @@ interface NumberLiteral implements HasSpan & Expression { # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression } type NumberLiteralAST implements HasSpan & ASTNode & Expression & NumberLiteral { @@ -301,7 +304,10 @@ type NumberLiteralAST implements HasSpan & ASTNode & Expression & NumberLiteral ancestor: [ASTNode!]! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression } # Expression @@ -320,7 +326,10 @@ interface JSXElement implements Expression & HasSpan { child_count: Int! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -374,7 +383,10 @@ interface ObjectLiteral implements Expression & HasSpan { # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -385,7 +397,10 @@ type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! @@ -394,12 +409,17 @@ type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode } interface Argument implements HasSpan { + is_spread: Boolean! + """ + Will be VarRef if `is_spread` is `true` + """ value: Expression! # HasSpan span: Span! } type ArgumentAST implements Argument & HasSpan & ASTNode { + is_spread: Boolean! value: Expression! # ASTNode parent: ASTNode @@ -414,7 +434,10 @@ interface FnCall implements Expression & HasSpan { # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -425,7 +448,10 @@ type FnCallAST implements FnCall & Expression & HasSpan & ASTNode { # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! @@ -446,7 +472,10 @@ interface Reassignment implements HasSpan & Expression { right: Expression! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -464,7 +493,10 @@ type ReassignmentAST implements HasSpan & ASTNode & Reassignment & Expression { right: Expression! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! # ASTNode @@ -508,7 +540,10 @@ interface Function implements Expression & HasSpan { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -528,7 +563,10 @@ interface UnaryExpression implements HasSpan & Expression { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -552,7 +590,10 @@ type UnaryExpressionAST implements UnaryExpression & ASTNode & HasSpan & Express ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -573,7 +614,10 @@ interface LogicalExpression implements HasSpan & Expression { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -598,7 +642,10 @@ type LogicalExpressionAST implements LogicalExpression & ASTNode & HasSpan & Exp ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -637,7 +684,10 @@ interface ArrowFunction implements Function & HasSpan & Expression { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -656,7 +706,10 @@ type ArrowFunctionAST implements Function & HasSpan & ArrowFunction & ASTNode & ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! # ASTNode @@ -687,7 +740,10 @@ interface FnDeclaration implements Function & HasSpan & Expression { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -714,7 +770,10 @@ type FnDeclarationAST implements Function & ASTNode & FnDeclaration & HasSpan & ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -723,7 +782,10 @@ interface VarRef implements HasSpan & Expression { name: String! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -735,7 +797,10 @@ type VarRefAST implements HasSpan & Expression & VarRef & ASTNode { ancestor: [ASTNode!]! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -766,7 +831,10 @@ interface DotProperty implements HasSpan & Expression { accessed_property: Name! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -785,7 +853,10 @@ type DotPropertyAST implements DotProperty & ASTNode & HasSpan & Expression { ancestor: [ASTNode!]! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! } @@ -796,7 +867,10 @@ interface Expression implements HasSpan { ie: const a = "apple"; const b = `blueberry` """ as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # HasSpan span: Span! @@ -834,6 +908,42 @@ type WhileStatementAST implements Statement & HasSpan & ASTNode & WhileStatement span: Span! } +interface DoWhileStatement implements Statement & HasSpan { + condition: Expression! + body: Statement! + # HasSpan + span: Span! +} + +type DoWhileStatementAST implements Statement & HasSpan & ASTNode & DoWhileStatement { + condition: Expression! + body: Statement! + # ASTNode + parent: ASTNode + ancestor: [ASTNode!]! + # HasSpan + span: Span! +} + +interface ForStatement implements Statement & HasSpan { + condition: Expression + step: Expression! + body: Statement! + # HasSpan + span: Span! +} + +type ForStatementAST implements Statement & HasSpan & ForStatement & ASTNode { + condition: Expression + step: Expression! + body: Statement! + # ASTNode + parent: ASTNode + ancestor: [ASTNode!]! + # HasSpan + span: Span! +} + interface BlockStatement implements Statement & HasSpan { statement: [Statement!] # HasSpan @@ -849,6 +959,93 @@ type BlockStatementAST implements Statement & HasSpan & ASTNode & BlockStatement span: Span! } +interface TernaryExpression implements Expression & HasSpan { + condition: Expression! + if_true: Expression! + if_false: Expression! + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + +type TernaryExpressionAST implements Expression & HasSpan & ASTNode & TernaryExpression { + condition: Expression! + if_true: Expression! + if_false: Expression! + # ASTNode + parent: ASTNode + ancestor: [ASTNode!]! + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + +interface New implements Expression & HasSpan { + callee: Expression! + argument: [Argument!] + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + +type NewAST implements Expression & HasSpan & New & ASTNode { + callee: Expression! + argument: [Argument!] + # ASTNode + parent: ASTNode + ancestor: [ASTNode!]! + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + +interface Throw implements Expression & HasSpan { + to_throw: Expression! + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + +type ThrowAST implements Expression & HasSpan & Throw & ASTNode { + to_throw: Expression! + # ASTNode + parent: ASTNode + ancestor: [ASTNode!]! + # Expression + as_constant_string: String + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression + # HasSpan + span: Span! +} + """ A single VariableDeclarator. (const/let/var)! If you have multiple variables assigned at once with commas, @@ -917,7 +1114,10 @@ type JSXElementAST implements JSXElement & Expression & ASTNode & HasSpan { child_count: Int! # Expression as_constant_string: String - strip_parens: Expression! + """ + Strips infinite levels of parens unless `strip_all` is `false`. + """ + strip_parens(strip_all: Boolean): Expression # ASTNode parent: ASTNode ancestor: [ASTNode!]! diff --git a/crates/oxc_query/src/util.rs b/crates/oxc_query/src/util.rs index ef67ebd42..df69f0789 100644 --- a/crates/oxc_query/src/util.rs +++ b/crates/oxc_query/src/util.rs @@ -85,3 +85,16 @@ pub fn jsx_attribute_name_to_string(jsx_attribute_name: &JSXAttributeName) -> St JSXAttributeName::NamespacedName(nsn) => jsx_namespaced_name_to_string(nsn), } } + +pub fn strip_parens_from_expr<'a, 'b: 'a>( + to_strip: &'b Expression<'a>, + strip_all: bool, +) -> &'b Expression<'a> { + match to_strip { + Expression::ParenthesizedExpression(paren_expr) if strip_all => { + strip_parens_from_expr(&paren_expr.expression, true) + } + Expression::ParenthesizedExpression(paren_expr) => &paren_expr.expression, + _ => to_strip, + } +} diff --git a/crates/oxc_query/src/vertex.rs b/crates/oxc_query/src/vertex.rs index c19047aa1..f65f505b3 100644 --- a/crates/oxc_query/src/vertex.rs +++ b/crates/oxc_query/src/vertex.rs @@ -62,6 +62,11 @@ pub enum Vertex<'a> { WhileStatement(Rc>), BlockStatement(Rc>), VarRef(Rc>), + DoWhileStatement(Rc>), + ForStatement(Rc>), + TernaryExpression(Rc>), + New(Rc>), + Throw(Rc>), } impl<'a> Vertex<'a> { @@ -112,8 +117,13 @@ impl<'a> Vertex<'a> { Self::UnaryExpression(data) => data.unary_expression.span, Self::ExpressionStatement(data) => data.expression_statement.span, Self::WhileStatement(data) => data.while_statement.span, + Self::DoWhileStatement(data) => data.do_while_statement.span, Self::BlockStatement(data) => data.block_statement.span, Self::VarRef(data) => data.identifier_reference.span, + Self::ForStatement(data) => data.for_statement.span, + Self::TernaryExpression(data) => data.conditional_expression.span, + Self::New(data) => data.new_expression.span, + Self::Throw(data) => data.throw_statement.span, Self::File | Self::Url(_) | Self::PathPart(_) @@ -155,6 +165,11 @@ impl<'a> Vertex<'a> { Vertex::WhileStatement(data) => data.ast_node.map(|x| x.id()), Vertex::BlockStatement(data) => data.ast_node.map(|x| x.id()), Vertex::VarRef(data) => data.ast_node.map(|x| x.id()), + Vertex::DoWhileStatement(data) => data.ast_node.map(|x| x.id()), + Vertex::ForStatement(data) => data.ast_node.map(|x| x.id()), + Vertex::TernaryExpression(data) => data.ast_node.map(|x| x.id()), + Vertex::New(data) => data.ast_node.map(|x| x.id()), + Vertex::Throw(data) => data.ast_node.map(|x| x.id()), Vertex::DefaultImport(_) | Vertex::Statement(_) | Vertex::AssignmentType(_) @@ -296,8 +311,13 @@ impl Typename for Vertex<'_> { Vertex::Statement(_) => "Statement", Vertex::ExpressionStatement(expr_stmt) => expr_stmt.typename(), Vertex::WhileStatement(expr_stmt) => expr_stmt.typename(), + Vertex::DoWhileStatement(expr_stmt) => expr_stmt.typename(), Vertex::BlockStatement(blk_stmt) => blk_stmt.typename(), Vertex::VarRef(var_ref) => var_ref.typename(), + Vertex::ForStatement(for_stmt) => for_stmt.typename(), + Vertex::TernaryExpression(ternary_expr) => ternary_expr.typename(), + Vertex::New(new) => new.typename(), + Vertex::Throw(throw) => throw.typename(), } } } @@ -406,6 +426,21 @@ impl<'a> From> for Vertex<'a> { AstKind::IdentifierReference(identifier_reference) => Vertex::VarRef( VarRefVertex { ast_node: Some(ast_node), identifier_reference }.into(), ), + AstKind::DoWhileStatement(do_while_statement) => Vertex::DoWhileStatement( + DoWhileStatementVertex { ast_node: Some(ast_node), do_while_statement }.into(), + ), + AstKind::ForStatement(for_statement) => Vertex::ForStatement( + ForStatementVertex { ast_node: Some(ast_node), for_statement }.into(), + ), + AstKind::ConditionalExpression(conditional_expression) => Vertex::TernaryExpression( + TernaryExpressionVertex { ast_node: Some(ast_node), conditional_expression }.into(), + ), + AstKind::NewExpression(new_expression) => { + Vertex::New(NewVertex { ast_node: Some(ast_node), new_expression }.into()) + } + AstKind::ThrowStatement(throw_statement) => { + Vertex::Throw(ThrowVertex { ast_node: Some(ast_node), throw_statement }.into()) + } _ => Vertex::ASTNode(ast_node), } } @@ -423,9 +458,18 @@ impl<'a> From<&'a Statement<'a>> for Vertex<'a> { Statement::WhileStatement(while_statement) => Vertex::WhileStatement( WhileStatementVertex { ast_node: None, while_statement }.into(), ), + Statement::DoWhileStatement(do_while_statement) => Vertex::DoWhileStatement( + DoWhileStatementVertex { ast_node: None, do_while_statement }.into(), + ), Statement::BlockStatement(block_statement) => Vertex::BlockStatement( BlockStatementVertex { ast_node: None, block_statement }.into(), ), + Statement::ForStatement(for_statement) => { + Vertex::ForStatement(ForStatementVertex { ast_node: None, for_statement }.into()) + } + Statement::ThrowStatement(throw_statement) => { + Vertex::Throw(ThrowVertex { ast_node: None, throw_statement }.into()) + } _ => Vertex::Statement(stmt), } } @@ -472,6 +516,12 @@ impl<'a> From<&'a Expression<'a>> for Vertex<'a> { Expression::Identifier(identifier_reference) => { Vertex::VarRef(VarRefVertex { ast_node: None, identifier_reference }.into()) } + Expression::ConditionalExpression(conditional_expression) => Vertex::TernaryExpression( + TernaryExpressionVertex { ast_node: None, conditional_expression }.into(), + ), + Expression::NewExpression(new_expression) => { + Vertex::New(NewVertex { ast_node: None, new_expression }.into()) + } _ => Vertex::Expression(expr), } } @@ -984,3 +1034,88 @@ impl<'a> Typename for VarRefVertex<'a> { } } } + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct DoWhileStatementVertex<'a> { + pub ast_node: Option>, + pub do_while_statement: &'a DoWhileStatement<'a>, +} + +impl<'a> Typename for DoWhileStatementVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "DoWhileStatementAST" + } else { + "DoWhileStatement" + } + } +} + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct ForStatementVertex<'a> { + pub ast_node: Option>, + pub for_statement: &'a ForStatement<'a>, +} + +impl<'a> Typename for ForStatementVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "ForStatementAST" + } else { + "ForStatement" + } + } +} + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct TernaryExpressionVertex<'a> { + pub ast_node: Option>, + pub conditional_expression: &'a ConditionalExpression<'a>, +} + +impl<'a> Typename for TernaryExpressionVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "TernaryExpressionAST" + } else { + "TernaryExpression" + } + } +} + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct NewVertex<'a> { + pub ast_node: Option>, + pub new_expression: &'a NewExpression<'a>, +} + +impl<'a> Typename for NewVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "NewAST" + } else { + "New" + } + } +} + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct ThrowVertex<'a> { + pub ast_node: Option>, + pub throw_statement: &'a ThrowStatement<'a>, +} + +impl<'a> Typename for ThrowVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "ThrowAST" + } else { + "Throw" + } + } +}