mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
feat(query): add many types to oxc_query (#724)
Adds `Name(AST)?`, `IfStatementAST`, `SpreadIntoObject(AST)?`, `ObjectEntry(AST)?`, `DotProperty(AST)?` types Fixes `ObjectLiteral`'s value field's output type Added `entry` field to `ObjectLiteral(AST)?`
This commit is contained in:
parent
7daab49ca5
commit
9566378119
5 changed files with 689 additions and 12 deletions
|
|
@ -96,6 +96,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"DotPropertyAST" | "DotProperty" => super::properties::resolve_dot_property_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"Expression" => super::properties::resolve_expression_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
|
|
@ -143,6 +148,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"NameAST" | "Name" => super::properties::resolve_name_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"NumberLiteralAST" | "NumberLiteral" => {
|
||||
super::properties::resolve_number_literal_property(
|
||||
contexts,
|
||||
|
|
@ -239,6 +249,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"DotPropertyAST" | "DotProperty" => super::edges::resolve_dot_property_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"DefaultImport" => super::edges::resolve_default_import_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -264,6 +281,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"IfStatementAST" => super::edges::resolve_if_statement_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"Import" | "ImportAST" => super::edges::resolve_import_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -342,6 +366,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"NameAST" | "Name" => super::edges::resolve_name_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"NumberLiteralAST" | "NumberLiteral" => super::edges::resolve_number_literal_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -349,6 +380,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ObjectEntryAST" | "ObjectEntry" => super::edges::resolve_object_entry_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ObjectLiteral" | "ObjectLiteralAST" => super::edges::resolve_object_literal_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -356,6 +394,12 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ObjectProperty" => super::edges::resolve_object_property_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"PathPart" => super::edges::resolve_path_part_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -382,6 +426,15 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"SpreadIntoObjectAST" | "SpreadIntoObject" => {
|
||||
super::edges::resolve_spread_into_object_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
)
|
||||
}
|
||||
"TypeAnnotation" | "TypeAnnotationAST" => super::edges::resolve_type_annotation_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
|
|||
|
|
@ -391,6 +391,83 @@ mod default_import {
|
|||
}
|
||||
}
|
||||
|
||||
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),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
"called_on" => dot_property::called_on(contexts, resolve_info),
|
||||
"accessed_property" => dot_property::accessed_property(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to resolve unexpected edge '{edge_name}' on type 'ClassProperty'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod dot_property {
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use crate::vertex::NameVertex;
|
||||
|
||||
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 called_on<'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_dot_property()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a dotproperty vertex, instead have: {v:#?}")
|
||||
})
|
||||
.static_member_expr
|
||||
.object)
|
||||
.into(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn accessed_property<'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(Vertex::Name(
|
||||
NameVertex {
|
||||
ast_node: None,
|
||||
name: &v
|
||||
.as_dot_property()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a dotproperty vertex, instead have: {v:#?}")
|
||||
})
|
||||
.static_member_expr
|
||||
.property,
|
||||
}
|
||||
.into(),
|
||||
)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_expression_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
@ -592,6 +669,59 @@ mod has_span {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_if_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" => if_statement::span(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
"condition" => if_statement::condition(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to resolve unexpected edge '{edge_name}' on type 'IfStatementAST'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod if_statement {
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, 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 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_if_statement_ast()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have an if_statement_ast vertex, instead have: {v:#?}")
|
||||
})
|
||||
.return_statement
|
||||
.test)
|
||||
.into(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_import_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
@ -1277,6 +1407,38 @@ mod member_extend {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_name_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" => name::span(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Name'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod name {
|
||||
use trustfall::provider::{
|
||||
ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator,
|
||||
};
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
|
||||
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,
|
||||
|
|
@ -1290,7 +1452,7 @@ pub(super) fn resolve_number_literal_edge<'a, 'b: 'a>(
|
|||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to resolve unexpected edge '{edge_name}' on type 'MemberExtend'"
|
||||
"attempted to resolve unexpected edge '{edge_name}' on type 'NumberLiteral'"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1311,6 +1473,83 @@ mod number_literal {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_object_entry_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" => object_entry::span(contexts, resolve_info),
|
||||
"key" => object_entry::key(contexts, resolve_info),
|
||||
"value" => object_entry::value(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'ObjectEntry'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod object_entry {
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
|
||||
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 key<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| {
|
||||
let key = &v
|
||||
.as_object_entry()
|
||||
.map_or_else(
|
||||
|| panic!("expected to have a objectentry vertex, instead have: {v:#?}"),
|
||||
|x| &x.property,
|
||||
)
|
||||
.key;
|
||||
|
||||
let vertex: Vertex<'_> = match &key {
|
||||
oxc_ast::ast::PropertyKey::Identifier(_) => return Box::new(std::iter::empty()), // TODO: FINISH
|
||||
oxc_ast::ast::PropertyKey::PrivateIdentifier(_) => unreachable!(
|
||||
"private identifiers don't exist in objects, so this should never be called"
|
||||
),
|
||||
oxc_ast::ast::PropertyKey::Expression(expr) => expr.into(),
|
||||
};
|
||||
|
||||
Box::new(std::iter::once(vertex))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn value<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| {
|
||||
let value = &v
|
||||
.as_object_entry()
|
||||
.map_or_else(
|
||||
|| panic!("expected to have a objectentry vertex, instead have: {v:#?}"),
|
||||
|x| &x.property,
|
||||
)
|
||||
.value;
|
||||
|
||||
Box::new(std::iter::once(value.into()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_object_literal_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
@ -1328,6 +1567,7 @@ pub(super) fn resolve_object_literal_edge<'a, 'b: 'a>(
|
|||
.expect("unexpected null or other incorrect datatype for Trustfall type 'String!'");
|
||||
object_literal::value(contexts, key, resolve_info)
|
||||
}
|
||||
"entry" => object_literal::entry(contexts, parameters, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
|
|
@ -1343,12 +1583,15 @@ mod object_literal {
|
|||
|
||||
use oxc_ast::ast::ObjectPropertyKind;
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, EdgeParameters,
|
||||
ResolveEdgeInfo, VertexIterator,
|
||||
};
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
use crate::util::expr_to_maybe_const_string;
|
||||
use crate::{
|
||||
util::expr_to_maybe_const_string,
|
||||
vertex::{ObjectEntryVertex, SpreadIntoObjectVertex},
|
||||
};
|
||||
|
||||
pub(super) fn span<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
|
|
@ -1389,6 +1632,58 @@ mod object_literal {
|
|||
}))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn entry<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_parameters: &EdgeParameters,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| {
|
||||
let obj = v.as_object_literal().unwrap_or_else(|| {
|
||||
panic!("expected to have an objectliteral vertex, instead have: {v:#?}")
|
||||
});
|
||||
|
||||
Box::new(obj.object_expression.properties.iter().map(|property| match property {
|
||||
oxc_ast::ast::ObjectPropertyKind::ObjectProperty(property) => {
|
||||
Vertex::ObjectEntry(ObjectEntryVertex { property, ast_node: None }.into())
|
||||
}
|
||||
oxc_ast::ast::ObjectPropertyKind::SpreadProperty(property) => {
|
||||
Vertex::SpreadIntoObject(
|
||||
SpreadIntoObjectVertex { property, ast_node: None }.into(),
|
||||
)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_object_property_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" => object_property::span(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Name'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod object_property {
|
||||
use trustfall::provider::{
|
||||
ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator,
|
||||
};
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
|
||||
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_path_part_edge<'a, 'b: 'a>(
|
||||
|
|
@ -1584,6 +1879,59 @@ mod specific_import {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_spread_into_object_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" => resolve_spread_into_object_edge::span(contexts, resolve_info),
|
||||
"value" => resolve_spread_into_object_edge::value(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to resolve unexpected edge '{edge_name}' on type 'SpreadIntoObject'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod resolve_spread_into_object_edge {
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
|
||||
pub(super) fn value<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| {
|
||||
let argument = &v
|
||||
.as_spread_into_object()
|
||||
.map_or_else(
|
||||
|| panic!("expected to have a spreadintoobject vertex, instead have: {v:#?}"),
|
||||
|x| &x.property,
|
||||
)
|
||||
.argument;
|
||||
|
||||
Box::new(std::iter::once(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,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,23 @@ pub(super) fn resolve_default_import_property<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_dot_property_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 'DotProperty'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_expression_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
@ -384,6 +401,26 @@ pub(super) fn resolve_member_extend_property<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_name_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
_resolve_info: &ResolveInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
|
||||
match property_name {
|
||||
"name" => resolve_property_with(contexts, |v| {
|
||||
v.as_name()
|
||||
.unwrap_or_else(|| panic!("expected to have a name vertex, instead have: {v:#?}"))
|
||||
.name
|
||||
.name
|
||||
.to_string()
|
||||
.into()
|
||||
}),
|
||||
_ => {
|
||||
unreachable!("attempted to read unexpected property '{property_name}' on type 'Name'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_number_literal_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
@ -410,7 +447,7 @@ pub(super) fn resolve_number_literal_property<'a, 'b: 'a>(
|
|||
}),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to read unexpected property '{property_name}' on type 'MemberExtend'"
|
||||
"attempted to read unexpected property '{property_name}' on type 'NumberLiteral'"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,8 +326,52 @@ interface JSXElement implements Expression & HasSpan {
|
|||
span: Span!
|
||||
}
|
||||
|
||||
interface ObjectProperty implements HasSpan {
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface SpreadIntoObject implements ObjectProperty & HasSpan {
|
||||
value: Expression!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type SpreadIntoObjectAST implements ASTNode & SpreadIntoObject & ObjectProperty & HasSpan {
|
||||
value: Expression!
|
||||
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface ObjectEntry implements ObjectProperty & HasSpan {
|
||||
key: Expression!
|
||||
value: Expression!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ObjectEntryAST implements ASTNode & ObjectEntry & ObjectProperty & HasSpan {
|
||||
key: Expression!
|
||||
value: Expression!
|
||||
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface ObjectLiteral implements Expression & HasSpan {
|
||||
value(key: String!): [Expression!]!
|
||||
value(key: String!): Expression
|
||||
entry: [ObjectProperty!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
|
|
@ -336,7 +380,8 @@ interface ObjectLiteral implements Expression & HasSpan {
|
|||
}
|
||||
|
||||
type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode {
|
||||
value(key: String!): [Expression!]!
|
||||
value(key: String!): Expression
|
||||
entry: [ObjectProperty!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
|
|
@ -347,6 +392,54 @@ type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode
|
|||
span: Span!
|
||||
}
|
||||
|
||||
interface Name implements HasSpan {
|
||||
name: String!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type NameAST implements ASTNode & Name & HasSpan {
|
||||
name: String!
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface DotProperty implements HasSpan & Expression {
|
||||
"""
|
||||
In "data.user.name", this would be "data.user"
|
||||
"""
|
||||
called_on: Expression!
|
||||
"""
|
||||
In "data.user.name", this would be "name"
|
||||
"""
|
||||
accessed_property: Name!
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type DotPropertyAST implements DotProperty & ASTNode & HasSpan & Expression {
|
||||
"""
|
||||
In "data.user.name", this would be "data.user"
|
||||
"""
|
||||
called_on: Expression!
|
||||
"""
|
||||
In "data.user.name", this would be "name"
|
||||
"""
|
||||
accessed_property: Name!
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface Expression implements HasSpan {
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
|
|
@ -464,6 +557,17 @@ type ClassAST implements ASTNode & Class & HasSpan {
|
|||
span: Span!
|
||||
}
|
||||
|
||||
type IfStatementAST implements ASTNode & HasSpan {
|
||||
condition: Expression!
|
||||
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ReturnStatementAST implements ASTNode & HasSpan {
|
||||
expression: Expression
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ use std::rc::Rc;
|
|||
use enum_as_inner::EnumAsInner;
|
||||
use oxc_ast::{
|
||||
ast::{
|
||||
BindingPatternKind, Class, Expression, IdentifierReference, ImportDeclaration,
|
||||
ImportDefaultSpecifier, ImportSpecifier, JSXAttribute, JSXElement, JSXExpressionContainer,
|
||||
JSXFragment, JSXOpeningElement, JSXSpreadAttribute, JSXSpreadChild, JSXText,
|
||||
MemberExpression, MethodDefinition, ModuleDeclaration, NumberLiteral, ObjectExpression,
|
||||
PropertyDefinition, ReturnStatement, TSInterfaceDeclaration, TSType, TSTypeAnnotation,
|
||||
BindingPatternKind, Class, Expression, IdentifierName, IdentifierReference, IfStatement,
|
||||
ImportDeclaration, ImportDefaultSpecifier, ImportSpecifier, JSXAttribute, JSXElement,
|
||||
JSXExpressionContainer, JSXFragment, JSXOpeningElement, JSXSpreadAttribute, JSXSpreadChild,
|
||||
JSXText, MemberExpression, MethodDefinition, ModuleDeclaration, NumberLiteral,
|
||||
ObjectExpression, ObjectProperty, PropertyDefinition, ReturnStatement, SpreadElement,
|
||||
StaticMemberExpression, TSInterfaceDeclaration, TSType, TSTypeAnnotation,
|
||||
VariableDeclarator,
|
||||
},
|
||||
AstKind,
|
||||
|
|
@ -43,6 +44,7 @@ pub enum Vertex<'a> {
|
|||
JSXText(&'a JSXText),
|
||||
ObjectLiteral(Rc<ObjectLiteralVertex<'a>>),
|
||||
NumberLiteral(Rc<NumberLiteralVertex<'a>>),
|
||||
Name(Rc<NameVertex<'a>>),
|
||||
PathPart(usize),
|
||||
SearchParameter(Rc<SearchParameterVertex>),
|
||||
Span(Span),
|
||||
|
|
@ -52,6 +54,10 @@ pub enum Vertex<'a> {
|
|||
Url(Rc<Url>),
|
||||
VariableDeclaration(Rc<VariableDeclarationVertex<'a>>),
|
||||
ReturnStatementAST(Rc<ReturnStatementVertex<'a>>),
|
||||
IfStatementAST(Rc<IfStatementVertex<'a>>),
|
||||
SpreadIntoObject(Rc<SpreadIntoObjectVertex<'a>>),
|
||||
ObjectEntry(Rc<ObjectEntryVertex<'a>>),
|
||||
DotProperty(Rc<DotPropertyVertex<'a>>),
|
||||
}
|
||||
|
||||
impl<'a> Vertex<'a> {
|
||||
|
|
@ -75,16 +81,21 @@ impl<'a> Vertex<'a> {
|
|||
Self::JSXExpressionContainer(data) => data.span,
|
||||
Self::JSXFragment(data) => data.span,
|
||||
Self::JSXOpeningElement(data) => data.opening_element.span,
|
||||
Self::DotProperty(data) => data.static_member_expr.span,
|
||||
Self::JSXSpreadAttribute(data) => data.span,
|
||||
Self::JSXSpreadChild(data) => data.span,
|
||||
Self::JSXText(data) => data.span,
|
||||
Self::ObjectLiteral(data) => data.object_expression.span,
|
||||
Self::SpreadIntoObject(data) => data.property.span,
|
||||
Self::ObjectEntry(data) => data.property.span,
|
||||
Self::SpecificImport(data) => data.span,
|
||||
Self::TypeAnnotation(data) => data.type_annotation.span,
|
||||
Self::Type(data) => data.span(),
|
||||
Self::VariableDeclaration(data) => data.variable_declaration.span,
|
||||
Self::ReturnStatementAST(data) => data.return_statement.span,
|
||||
Self::IfStatementAST(data) => data.return_statement.span,
|
||||
Self::NumberLiteral(data) => data.number_literal.span,
|
||||
Self::Name(data) => data.name.span,
|
||||
Self::File
|
||||
| Self::Url(_)
|
||||
| Self::PathPart(_)
|
||||
|
|
@ -106,8 +117,13 @@ 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::IfStatementAST(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::JSXOpeningElement(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::NumberLiteral(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::Name(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::SpreadIntoObject(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::ObjectEntry(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::DotProperty(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::DefaultImport(_)
|
||||
| Vertex::AssignmentType(_)
|
||||
| Vertex::ClassMethod(_)
|
||||
|
|
@ -160,6 +176,7 @@ impl Typename for Vertex<'_> {
|
|||
Vertex::Import(import) => import.typename(),
|
||||
Vertex::Interface(iface) => iface.typename(),
|
||||
Vertex::NumberLiteral(nlit) => nlit.typename(),
|
||||
Vertex::DotProperty(dot_property) => dot_property.typename(),
|
||||
Vertex::InterfaceExtend(iex) => match **iex {
|
||||
InterfaceExtendVertex::Identifier(_) => "SimpleExtend",
|
||||
InterfaceExtendVertex::MemberExpression(_) => "MemberExtend",
|
||||
|
|
@ -181,7 +198,11 @@ impl Typename for Vertex<'_> {
|
|||
Vertex::Type(_) => "Type",
|
||||
Vertex::Url(_) => "URL",
|
||||
Vertex::VariableDeclaration(vd) => vd.typename(),
|
||||
Vertex::Name(name) => name.typename(),
|
||||
Vertex::ReturnStatementAST(_) => "ReturnStatementAST",
|
||||
Vertex::IfStatementAST(_) => "IfStatementAST",
|
||||
Vertex::SpreadIntoObject(obj) => obj.typename(),
|
||||
Vertex::ObjectEntry(entry) => entry.typename(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,6 +213,10 @@ impl<'a> From<AstNode<'a>> for Vertex<'a> {
|
|||
AstKind::ReturnStatement(return_statement) => Self::ReturnStatementAST(
|
||||
ReturnStatementVertex { ast_node: Some(ast_node), return_statement }.into(),
|
||||
),
|
||||
AstKind::IfStatement(if_statement) => Self::IfStatementAST(
|
||||
IfStatementVertex { ast_node: Some(ast_node), return_statement: if_statement }
|
||||
.into(),
|
||||
),
|
||||
AstKind::JSXElement(element) => {
|
||||
Self::JSXElement(JSXElementVertex { ast_node: Some(ast_node), element }.into())
|
||||
}
|
||||
|
|
@ -219,6 +244,29 @@ impl<'a> From<AstNode<'a>> for Vertex<'a> {
|
|||
AstKind::NumberLiteral(number_literal) => Self::NumberLiteral(
|
||||
NumberLiteralVertex { ast_node: Some(ast_node), number_literal }.into(),
|
||||
),
|
||||
AstKind::IdentifierName(identifier_name) => {
|
||||
Self::Name(NameVertex { ast_node: Some(ast_node), name: identifier_name }.into())
|
||||
}
|
||||
AstKind::ObjectProperty(property) => {
|
||||
Self::ObjectEntry(ObjectEntryVertex { ast_node: Some(ast_node), property }.into())
|
||||
}
|
||||
AstKind::SpreadElement(property) => Self::SpreadIntoObject(
|
||||
SpreadIntoObjectVertex { ast_node: Some(ast_node), property }.into(),
|
||||
),
|
||||
AstKind::MemberExpression(member_expr)
|
||||
if matches!(member_expr, MemberExpression::StaticMemberExpression(_)) =>
|
||||
{
|
||||
match member_expr {
|
||||
MemberExpression::StaticMemberExpression(member_expr) => Self::DotProperty(
|
||||
DotPropertyVertex {
|
||||
ast_node: Some(ast_node),
|
||||
static_member_expr: member_expr,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
_ => unreachable!("we should only ever have StaticMemberExpression"),
|
||||
}
|
||||
}
|
||||
_ => Vertex::ASTNode(ast_node),
|
||||
}
|
||||
}
|
||||
|
|
@ -239,6 +287,18 @@ impl<'a> From<&'a Expression<'a>> for Vertex<'a> {
|
|||
Expression::NumberLiteral(number_literal) => {
|
||||
Vertex::NumberLiteral(NumberLiteralVertex { ast_node: None, number_literal }.into())
|
||||
}
|
||||
Expression::MemberExpression(member_expr)
|
||||
if matches!(**member_expr, MemberExpression::StaticMemberExpression(_)) =>
|
||||
{
|
||||
match &**member_expr {
|
||||
MemberExpression::StaticMemberExpression(static_member_expr) => {
|
||||
Vertex::DotProperty(
|
||||
DotPropertyVertex { ast_node: None, static_member_expr }.into(),
|
||||
)
|
||||
}
|
||||
_ => unreachable!("we should only ever have StaticMemberExpression"),
|
||||
}
|
||||
}
|
||||
_ => Vertex::Expression(expr),
|
||||
}
|
||||
}
|
||||
|
|
@ -347,6 +407,13 @@ impl<'a> Typename for JSXElementVertex<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IfStatementVertex<'a> {
|
||||
ast_node: Option<AstNode<'a>>,
|
||||
pub return_statement: &'a IfStatement<'a>,
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReturnStatementVertex<'a> {
|
||||
|
|
@ -445,3 +512,71 @@ impl<'a> Typename for NumberLiteralVertex<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NameVertex<'a> {
|
||||
pub ast_node: Option<AstNode<'a>>,
|
||||
pub name: &'a IdentifierName,
|
||||
}
|
||||
|
||||
impl<'a> Typename for NameVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"NameAST"
|
||||
} else {
|
||||
"Name"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ObjectEntryVertex<'a> {
|
||||
pub ast_node: Option<AstNode<'a>>,
|
||||
pub property: &'a ObjectProperty<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for ObjectEntryVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"ObjectEntryAST"
|
||||
} else {
|
||||
"ObjectEntry"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpreadIntoObjectVertex<'a> {
|
||||
pub ast_node: Option<AstNode<'a>>,
|
||||
pub property: &'a SpreadElement<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for SpreadIntoObjectVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"SpreadIntoObjectAST"
|
||||
} else {
|
||||
"SpreadIntoObject"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DotPropertyVertex<'a> {
|
||||
ast_node: Option<AstNode<'a>>,
|
||||
pub static_member_expr: &'a StaticMemberExpression<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for DotPropertyVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"DotPropertyAST"
|
||||
} else {
|
||||
"DotProperty"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue