feat(query): Add fields and new ArrayElement types (#787)

```diff
- Array.elements
+ Array.element

+ ElidedArrayElement
+ ElidedArrayElement implements ArrayElement
+ ElidedArrayElement implements HasSpan

+ ElidedArrayElementAST
+ ElidedArrayElementAST implements ArrayElement
+ ElidedArrayElementAST implements HasSpan
+ ElidedArrayElementAST implements ElidedArrayElement

+ SpreadArrayElement
+ SpreadArrayElement implements ArrayElement
+ SpreadArrayElement implements HasSpan
+ SpreadArrayElement.spread

+ SpreadArrayElementAST
+ SpreadArrayElementAST implements ArrayElement
+ SpreadArrayElementAST implements HasSpan
+ SpreadArrayElementAST implements SpreadArrayElement

+ VariableDeclarationAST.kind

```
This commit is contained in:
u9g 2023-08-24 23:46:00 -04:00 committed by GitHub
parent 741aa8df1f
commit e0a85eec01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 237 additions and 9 deletions

View file

@ -281,6 +281,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
resolve_info,
)
}
"VariableDeclarationAST" | "VariableDeclaration" => {
super::properties::resolve_variable_declaration_property(
contexts,
property_name.as_ref(),
resolve_info,
)
}
"VarRefAST" | "VarRef" => super::properties::resolve_var_ref_property(
contexts,
property_name.as_ref(),
@ -393,6 +400,14 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
self,
)
}
"ElidedArrayElementAST" | "ElidedArrayElement" => {
super::edges::resolve_elided_array_element_edge(
contexts,
edge_name.as_ref(),
parameters,
resolve_info,
)
}
"Expression" => super::edges::resolve_expression_edge(
contexts,
edge_name.as_ref(),
@ -646,6 +661,14 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
parameters,
resolve_info,
),
"SpreadArrayElementAST" | "SpreadArrayElement" => {
super::edges::resolve_spread_array_element_edge(
contexts,
edge_name.as_ref(),
parameters,
resolve_info,
)
}
"SpreadIntoObjectAST" | "SpreadIntoObject" => {
super::edges::resolve_spread_into_object_edge(
contexts,

View file

@ -15,7 +15,7 @@ pub(super) fn resolve_array_edge<'a, 'b: 'a>(
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
match edge_name {
"span" => array::span(contexts, resolve_info),
"elements" => array::elements(contexts, resolve_info),
"element" => array::element(contexts, resolve_info),
"strip_parens" => strip_parens(contexts, parameters),
"ancestor" => ancestors(contexts, adapter),
"parent" => parents(contexts, adapter),
@ -31,11 +31,11 @@ mod array {
VertexIterator,
};
use crate::vertex::ArrayElementVertex;
use crate::vertex::{ArrayElementVertex, ElidedArrayElementVertex, SpreadArrayElementVertex};
use super::super::vertex::Vertex;
pub(super) fn elements<'a, 'b: 'a>(
pub(super) fn element<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
_resolve_info: &ResolveEdgeInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
@ -48,11 +48,27 @@ mod array {
.array_expression
.elements
.iter()
.map(|x| {
Vertex::ArrayElement(
ArrayElementVertex { array_expression_element: x, ast_node: None }
.map(|x| match x {
oxc_ast::ast::ArrayExpressionElement::SpreadElement(spread) => {
Vertex::SpreadArrayElement(
SpreadArrayElementVertex {
ast_node: None,
spread: &spread.argument,
}
.into(),
)
)
}
oxc_ast::ast::ArrayExpressionElement::Elision(span) => {
Vertex::ElidedArrayElement(
ElidedArrayElementVertex { ast_node: None, span: *span }.into(),
)
}
oxc_ast::ast::ArrayExpressionElement::Expression(_) => {
Vertex::ArrayElement(
ArrayElementVertex { array_expression_element: x, ast_node: None }
.into(),
)
}
}),
)
})
@ -802,6 +818,37 @@ mod dot_property {
}
}
pub(super) fn resolve_elided_array_element_edge<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
edge_name: &str,
_parameters: &EdgeParameters,
resolve_info: &ResolveEdgeInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
match edge_name {
"span" => elided_array_element::span(contexts, resolve_info),
_ => {
unreachable!(
"attempted to resolve unexpected edge '{edge_name}' on type 'ElidedArrayElement'"
)
}
}
}
mod elided_array_element {
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_expression_edge<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
edge_name: &str,
@ -3046,6 +3093,55 @@ mod specific_import {
}
}
pub(super) fn resolve_spread_array_element_edge<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
edge_name: &str,
_parameters: &EdgeParameters,
resolve_info: &ResolveEdgeInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
match edge_name {
"span" => spread_array_element::span(contexts, resolve_info),
"spread" => spread_array_element::spread(contexts, resolve_info),
_ => {
unreachable!(
"attempted to resolve unexpected edge '{edge_name}' on type 'SpreadArrayElement'"
)
}
}
}
mod spread_array_element {
use trustfall::provider::{
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
VertexIterator,
};
use super::{super::vertex::Vertex, get_span};
pub(super) fn spread<'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_spread_array_element()
.unwrap_or_else(|| {
panic!("expected to have a spreadarrayelement vertex, instead have: {v:#?}")
})
.spread)
.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_spread_into_object_edge<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
edge_name: &str,

View file

@ -885,6 +885,34 @@ pub(super) fn resolve_unary_expression_property<'a, 'b: 'a>(
}
}
pub(super) fn resolve_variable_declaration_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"kind" => resolve_property_with(contexts, |v| {
match v
.as_variable_declaration()
.unwrap_or_else(|| {
panic!("expected to have a variabledeclaration vertex, instead have: {v:#?}",)
})
.variable_declaration
.kind
{
oxc_ast::ast::VariableDeclarationKind::Var => "var".into(),
oxc_ast::ast::VariableDeclarationKind::Const => "const".into(),
oxc_ast::ast::VariableDeclarationKind::Let => "let".into(),
}
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'LogicalExpression'"
)
}
}
}
pub(super) fn resolve_var_ref_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,

View file

@ -276,6 +276,36 @@ type JSXText {
span: Span!
}
interface SpreadArrayElement implements ArrayElement & HasSpan {
spread: Expression!
# HasSpan
span: Span!
}
type SpreadArrayElementAST implements ArrayElement & HasSpan & SpreadArrayElement {
spread: Expression!
# HasSpan
span: Span!
}
"""
The element in this array would be elided: [,]
The element in the middle of this array is elided: [1,,3]
"""
interface ElidedArrayElement implements ArrayElement & HasSpan {
# HasSpan
span: Span!
}
"""
The element in this array would be elided: [,]
The element in the middle of this array is elided: [1,,3]
"""
type ElidedArrayElementAST implements ArrayElement & HasSpan & ElidedArrayElement {
# HasSpan
span: Span!
}
interface ArrayElement implements HasSpan {
# HasSpan
span: Span!
@ -290,7 +320,7 @@ type ArrayElementAST implements HasSpan & ASTNode {
}
interface Array implements HasSpan & Expression {
elements: [ArrayElement!]
element: [ArrayElement!]
# Expression
as_constant_string: String
"""
@ -303,7 +333,7 @@ interface Array implements HasSpan & Expression {
}
type ArrayAST implements HasSpan & Expression & Array & ASTNode {
elements: [ArrayElement!]
element: [ArrayElement!]
# ASTNode
parent: ASTNode
ancestor: [ASTNode!]!
@ -1217,6 +1247,10 @@ this will fire once per assignment.
type VariableDeclarationAST implements VariableDeclaration & ASTNode & HasSpan {
left: AssignmentType!
right: Expression
"""
'let' | 'var' | 'const'
"""
kind: String!
# ASTNode
parent: ASTNode
ancestor: [ASTNode!]!

View file

@ -79,6 +79,8 @@ pub enum Vertex<'a> {
TemplateLiteral(Rc<TemplateLiteralVertex<'a>>),
RegExpLiteral(Rc<RegExpLiteralVertex<'a>>),
ParenthesizedExpression(Rc<ParenthesizedExpressionVertex<'a>>),
ElidedArrayElement(Rc<ElidedArrayElementVertex<'a>>),
SpreadArrayElement(Rc<SpreadArrayElementVertex<'a>>),
}
impl<'a> Vertex<'a> {
@ -142,6 +144,8 @@ impl<'a> Vertex<'a> {
Self::TemplateLiteral(data) => data.template.span,
Self::RegExpLiteral(data) => data.regexp.span,
Self::ParenthesizedExpression(data) => data.parenthesized_expression.span,
Self::ElidedArrayElement(data) => data.span,
Self::SpreadArrayElement(data) => data.spread.span(),
Self::File
| Self::Url(_)
| Self::PathPart(_)
@ -197,6 +201,8 @@ impl<'a> Vertex<'a> {
Vertex::TemplateLiteral(data) => data.ast_node.map(|x| x.id()),
Vertex::RegExpLiteral(data) => data.ast_node.map(|x| x.id()),
Vertex::ParenthesizedExpression(data) => data.ast_node.map(|x| x.id()),
Vertex::ElidedArrayElement(data) => data.ast_node.map(|x| x.id()),
Vertex::SpreadArrayElement(data) => data.ast_node.map(|x| x.id()),
Vertex::DefaultImport(_)
| Vertex::Statement(_)
| Vertex::AssignmentType(_)
@ -309,6 +315,8 @@ impl<'a> Vertex<'a> {
| Vertex::Array(..) => true,
Vertex::ASTNode(..)
| Vertex::AssignmentType(..)
| Vertex::ElidedArrayElement(..)
| Vertex::SpreadArrayElement(..)
| Vertex::Class(..)
| Vertex::ClassMethod(..)
| Vertex::ClassProperty(..)
@ -419,6 +427,8 @@ impl Typename for Vertex<'_> {
Vertex::TemplateLiteral(data) => data.typename(),
Vertex::RegExpLiteral(data) => data.typename(),
Vertex::ParenthesizedExpression(data) => data.typename(),
Vertex::ElidedArrayElement(data) => data.typename(),
Vertex::SpreadArrayElement(data) => data.typename(),
}
}
}
@ -567,6 +577,9 @@ impl<'a> From<AstNode<'a>> for Vertex<'a> {
.into(),
)
}
AstKind::Elision(span) => Vertex::ElidedArrayElement(
ElidedArrayElementVertex { span, ast_node: Some(ast_node) }.into(),
),
_ => Vertex::ASTNode(ast_node),
}
}
@ -1400,3 +1413,37 @@ impl<'a> Typename for ParenthesizedExpressionVertex<'a> {
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct ElidedArrayElementVertex<'a> {
pub ast_node: Option<AstNode<'a>>,
pub span: Span,
}
impl<'a> Typename for ElidedArrayElementVertex<'a> {
fn typename(&self) -> &'static str {
if self.ast_node.is_some() {
"ElidedArrayElementAST"
} else {
"ElidedArrayElement"
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct SpreadArrayElementVertex<'a> {
pub ast_node: Option<AstNode<'a>>,
pub spread: &'a Expression<'a>,
}
impl<'a> Typename for SpreadArrayElementVertex<'a> {
fn typename(&self) -> &'static str {
if self.ast_node.is_some() {
"SpreadArrayElementAST"
} else {
"SpreadArrayElement"
}
}
}