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
```
This commit is contained in:
u9g 2023-08-23 09:27:49 -04:00 committed by GitHub
parent 28544e1d59
commit 89d115704b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 135 additions and 0 deletions

View file

@ -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(),

View file

@ -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,

View file

@ -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,

View file

@ -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

View file

@ -73,6 +73,7 @@ pub enum Vertex<'a> {
ArrayElement(Rc<ArrayElementVertex<'a>>),
StringLiteral(Rc<StringLiteralVertex<'a>>),
TemplateLiteral(Rc<TemplateLiteralVertex<'a>>),
RegExpLiteral(Rc<RegExpLiteralVertex<'a>>),
}
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<AstNode<'a>> 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<AstNode<'a>>,
pub regexp: &'a RegExpLiteral,
}
impl<'a> Typename for RegExpLiteralVertex<'a> {
fn typename(&self) -> &'static str {
if self.ast_node.is_some() {
"RegExpLiteralAST"
} else {
"RegExpLiteral"
}
}
}