From 89d115704b2f674717672d17d4182389714f6c90 Mon Sep 17 00:00:00 2001 From: u9g Date: Wed, 23 Aug 2023 09:27:49 -0400 Subject: [PATCH] feat(query): Add types & Visit Array in AST for ArrayAST type (#777) ```diff + RegExpLiteral + RegExpLiteral implements HasSpan + RegExpLiteral implements Expression + RegExpLiteral.pattern + RegExpLiteralAST + RegExpLiteralAST implements ASTNode + RegExpLiteralAST implements RegExpLiteral + RegExpLiteralAST implements HasSpan + RegExpLiteralAST implements Expression ``` --- crates/oxc_query/src/adapter.rs | 14 ++++++++++++ crates/oxc_query/src/edges.rs | 35 +++++++++++++++++++++++++++++ crates/oxc_query/src/properties.rs | 28 +++++++++++++++++++++++ crates/oxc_query/src/schema.graphql | 27 ++++++++++++++++++++++ crates/oxc_query/src/vertex.rs | 31 +++++++++++++++++++++++++ 5 files changed, 135 insertions(+) diff --git a/crates/oxc_query/src/adapter.rs b/crates/oxc_query/src/adapter.rs index 4ed04926a..73662aef6 100644 --- a/crates/oxc_query/src/adapter.rs +++ b/crates/oxc_query/src/adapter.rs @@ -219,6 +219,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { property_name.as_ref(), resolve_info, ), + "RegExpLiteralAST" | "RegExpLiteral" => { + super::properties::resolve_regexp_literal_property( + contexts, + property_name.as_ref(), + resolve_info, + ) + } "SearchParameter" => super::properties::resolve_search_parameter_property( contexts, property_name.as_ref(), @@ -596,6 +603,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> { resolve_info, self, ), + "RegExpLiteralAST" | "RegExpLiteral" => super::edges::resolve_regexp_literal_edge( + contexts, + edge_name.as_ref(), + parameters, + resolve_info, + self, + ), "ReturnAST" | "ReturnStatement" => super::edges::resolve_return_edge( contexts, edge_name.as_ref(), diff --git a/crates/oxc_query/src/edges.rs b/crates/oxc_query/src/edges.rs index 46ae0d1d2..a3d044459 100644 --- a/crates/oxc_query/src/edges.rs +++ b/crates/oxc_query/src/edges.rs @@ -2804,6 +2804,41 @@ mod reassignment { } } +pub(super) fn resolve_regexp_literal_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" => regexp_literal::span(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 'RegExpLiteral'" + ) + } + } +} + +mod regexp_literal { + use trustfall::provider::{ + ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator, + }; + + use super::super::vertex::Vertex; + + 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_return_edge<'a, 'b: 'a>( contexts: ContextIterator<'a, Vertex<'b>>, edge_name: &str, diff --git a/crates/oxc_query/src/properties.rs b/crates/oxc_query/src/properties.rs index 9c6c74fb0..56fc01655 100644 --- a/crates/oxc_query/src/properties.rs +++ b/crates/oxc_query/src/properties.rs @@ -640,6 +640,34 @@ pub(super) fn resolve_reassignment_property<'a, 'b: 'a>( } } +pub(super) fn resolve_regexp_literal_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) + }), + "pattern" => resolve_property_with(contexts, |v| { + v.as_reg_exp_literal() + .unwrap_or_else(|| { + panic!("expected to have a regexpliteral vertex, instead have: {v:#?}") + }) + .regexp + .regex + .pattern + .to_string() + .into() + }), + _ => { + unreachable!( + "attempted to read unexpected property '{property_name}' on type 'RegExpLiteral'" + ) + } + } +} + pub(super) fn resolve_search_parameter_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 e8edd8f24..8b5e3882e 100644 --- a/crates/oxc_query/src/schema.graphql +++ b/crates/oxc_query/src/schema.graphql @@ -906,6 +906,33 @@ type TemplateLiteralAST implements HasSpan & Expression & TemplateLiteral & ASTN span: Span! } +interface RegExpLiteral implements HasSpan & Expression { + pattern: String! + # 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 RegExpLiteralAST implements HasSpan & Expression & RegExpLiteral & ASTNode { + pattern: String! + # 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 Name implements HasSpan { name: String! # HasSpan diff --git a/crates/oxc_query/src/vertex.rs b/crates/oxc_query/src/vertex.rs index 173ac5461..b074bbfc6 100644 --- a/crates/oxc_query/src/vertex.rs +++ b/crates/oxc_query/src/vertex.rs @@ -73,6 +73,7 @@ pub enum Vertex<'a> { ArrayElement(Rc>), StringLiteral(Rc>), TemplateLiteral(Rc>), + RegExpLiteral(Rc>), } impl<'a> Vertex<'a> { @@ -134,6 +135,7 @@ impl<'a> Vertex<'a> { Self::ArrayElement(data) => data.array_expression_element.span(), Self::StringLiteral(data) => data.string.span, Self::TemplateLiteral(data) => data.template.span, + Self::RegExpLiteral(data) => data.regexp.span, Self::File | Self::Url(_) | Self::PathPart(_) @@ -184,6 +186,7 @@ impl<'a> Vertex<'a> { Vertex::ArrayElement(data) => data.ast_node.map(|x| x.id()), Vertex::StringLiteral(data) => data.ast_node.map(|x| x.id()), Vertex::TemplateLiteral(data) => data.ast_node.map(|x| x.id()), + Vertex::RegExpLiteral(data) => data.ast_node.map(|x| x.id()), Vertex::DefaultImport(_) | Vertex::Statement(_) | Vertex::AssignmentType(_) @@ -291,6 +294,7 @@ impl<'a> Vertex<'a> { | Vertex::New(..) | Vertex::StringLiteral(..) | Vertex::TemplateLiteral(..) + | Vertex::RegExpLiteral(..) | Vertex::Array(..) => true, Vertex::ASTNode(..) | Vertex::AssignmentType(..) @@ -402,6 +406,7 @@ impl Typename for Vertex<'_> { Vertex::ArrayElement(data) => data.typename(), Vertex::StringLiteral(data) => data.typename(), Vertex::TemplateLiteral(data) => data.typename(), + Vertex::RegExpLiteral(data) => data.typename(), } } } @@ -535,6 +540,12 @@ impl<'a> From> for Vertex<'a> { TemplateLiteralVertex { ast_node: Some(ast_node), template: template_literal } .into(), ), + AstKind::RegExpLiteral(regexp_literal) => Vertex::RegExpLiteral( + RegExpLiteralVertex { ast_node: Some(ast_node), regexp: regexp_literal }.into(), + ), + AstKind::ArrayExpression(array_expression) => { + Vertex::Array(ArrayVertex { ast_node: Some(ast_node), array_expression }.into()) + } _ => Vertex::ASTNode(ast_node), } } @@ -622,6 +633,9 @@ impl<'a> From<&'a Expression<'a>> for Vertex<'a> { Expression::TemplateLiteral(template_literal) => Vertex::TemplateLiteral( TemplateLiteralVertex { ast_node: None, template: template_literal }.into(), ), + Expression::RegExpLiteral(regexp_literal) => Vertex::RegExpLiteral( + RegExpLiteralVertex { ast_node: None, regexp: regexp_literal }.into(), + ), _ => Vertex::Expression(expr), } } @@ -1287,3 +1301,20 @@ impl<'a> Typename for TemplateLiteralVertex<'a> { } } } + +#[non_exhaustive] +#[derive(Debug, Clone)] +pub struct RegExpLiteralVertex<'a> { + pub ast_node: Option>, + pub regexp: &'a RegExpLiteral, +} + +impl<'a> Typename for RegExpLiteralVertex<'a> { + fn typename(&self) -> &'static str { + if self.ast_node.is_some() { + "RegExpLiteralAST" + } else { + "RegExpLiteral" + } + } +}