mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(query): New types and new fields for existing types (#746)
```diff + Argument.value + Argument implements HasSpan + ArgumentAST - FnCall.arguments + FnCall.argument - FnCallAST.arguments + FnCallAST.argument + interface Function + Function.is_async + Function.is_generator + Function.parameter + Function implements Expression + Function implements HasSpan + Parameter + Parameter.is_readonly + Parameter.assignment + Parameter.type_annotation + Parameter implements HasSpan + ParameterAST + ArrowFunction implements Function + ArrowFunction implements Expression + ArrowFunctionAST implements Function + ArrowFunctionAST implements Expression + FnDeclaration implements Function + FnDeclaration implements Expression + FnDeclarationAST implements Function + FnDeclarationAST implements Expression ```
This commit is contained in:
parent
f4d16c2166
commit
b346a9ad6d
5 changed files with 487 additions and 26 deletions
|
|
@ -71,6 +71,13 @@ 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() {
|
||||
"ArrowFunctionAST" | "ArrowFunction" => {
|
||||
super::properties::resolve_arrow_function_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
)
|
||||
}
|
||||
"AssignmentType" => super::properties::resolve_assignment_type_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
|
|
@ -118,6 +125,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"Function" => super::properties::resolve_function_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"ImportAST" | "Import" => super::properties::resolve_import_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
|
|
@ -169,6 +181,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
)
|
||||
}
|
||||
"ParameterAST" | "Parameter" => super::properties::resolve_parameter_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"PathPart" => super::properties::resolve_path_part_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
|
|
@ -228,11 +245,12 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"Argument" => super::edges::resolve_argument_edge(
|
||||
"ArgumentAST" | "Argument" => super::edges::resolve_argument_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"AssignmentType" => super::edges::resolve_assignment_type_edge(
|
||||
contexts,
|
||||
|
|
@ -278,6 +296,12 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"Function" => super::edges::resolve_function_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"FunctionBodyAST" | "FunctionBody" => super::edges::resolve_function_body_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -438,6 +462,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ParameterAST" | "Parameter" => super::edges::resolve_parameter_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ReassignmentAST" | "Reassignment" => super::edges::resolve_reassignment_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ pub(super) fn resolve_arrow_function_edge<'a, 'b: 'a>(
|
|||
) -> 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),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
|
|
@ -27,11 +29,19 @@ pub(super) fn resolve_arrow_function_edge<'a, 'b: 'a>(
|
|||
|
||||
mod arrow_function {
|
||||
use trustfall::provider::{
|
||||
ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator,
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::super::vertex::Vertex;
|
||||
|
||||
pub(super) fn parameter<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| v.function_parameter())
|
||||
}
|
||||
|
||||
pub(super) fn span<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
|
|
@ -44,9 +54,13 @@ pub(super) fn resolve_argument_edge<'a, 'b: 'a>(
|
|||
edge_name: &str,
|
||||
_parameters: &EdgeParameters,
|
||||
resolve_info: &ResolveEdgeInfo,
|
||||
adapter: &'a Adapter<'b>,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
match edge_name {
|
||||
"span" => argument::span(contexts, resolve_info),
|
||||
"value" => argument::value(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Argument'")
|
||||
}
|
||||
|
|
@ -54,12 +68,34 @@ pub(super) fn resolve_argument_edge<'a, 'b: 'a>(
|
|||
}
|
||||
|
||||
mod argument {
|
||||
use oxc_ast::ast::Argument;
|
||||
use trustfall::provider::{
|
||||
ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator,
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::super::vertex::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 expr = match v
|
||||
.as_argument()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have an argument vertex, instead have: {v:#?}")
|
||||
})
|
||||
.argument
|
||||
{
|
||||
Argument::SpreadElement(spread) => &spread.argument,
|
||||
Argument::Expression(expr) => expr,
|
||||
};
|
||||
|
||||
Box::new(std::iter::once(expr.into()))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn span<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
|
|
@ -573,6 +609,45 @@ mod expression {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_function_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 {
|
||||
"parameter" => function::parameter(contexts, resolve_info),
|
||||
"span" => function::span(contexts, resolve_info),
|
||||
"strip_parens" => strip_parens(contexts),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Function'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod function {
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::super::vertex::Vertex;
|
||||
|
||||
pub(super) fn parameter<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| v.function_parameter())
|
||||
}
|
||||
|
||||
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_function_body_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
@ -636,6 +711,8 @@ pub(super) fn resolve_fn_declaration_edge<'a, 'b: 'a>(
|
|||
) -> 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),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
_ => {
|
||||
|
|
@ -648,11 +725,19 @@ pub(super) fn resolve_fn_declaration_edge<'a, 'b: 'a>(
|
|||
|
||||
mod fn_declaration {
|
||||
use trustfall::provider::{
|
||||
ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo, VertexIterator,
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::super::vertex::Vertex;
|
||||
|
||||
pub(super) fn parameter<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |v| v.function_parameter())
|
||||
}
|
||||
|
||||
pub(super) fn span<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
|
|
@ -671,6 +756,7 @@ pub(super) fn resolve_file_edge<'a, 'b: 'a>(
|
|||
match edge_name {
|
||||
"ast_node" => file::ast_node(contexts, resolve_info, adapter),
|
||||
"class" => file::class(contexts, resolve_info, adapter),
|
||||
"function" => file::function(contexts, resolve_info, adapter),
|
||||
"import" => file::import(contexts, resolve_info, adapter),
|
||||
"interface" => file::interface(contexts, resolve_info, adapter),
|
||||
"jsx_element" => file::jsx_element(contexts, resolve_info, adapter),
|
||||
|
|
@ -717,6 +803,23 @@ mod file {
|
|||
})
|
||||
}
|
||||
|
||||
pub(super) fn function<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
adapter: &'a Adapter<'b>,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
resolve_neighbors_with(contexts, |_| {
|
||||
Box::new(
|
||||
adapter
|
||||
.semantic
|
||||
.nodes()
|
||||
.iter()
|
||||
.map(|node| (*node).into())
|
||||
.filter(|x: &Vertex<'_>| x.is_arrow_function() || x.is_fn_declaration()),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn import<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
|
|
@ -814,7 +917,7 @@ pub(super) fn resolve_fn_call_edge<'a, 'b: 'a>(
|
|||
match edge_name {
|
||||
"span" => fn_call::span(contexts, resolve_info),
|
||||
"callee" => fn_call::callee(contexts, resolve_info),
|
||||
"arguments" => fn_call::arguments(contexts, resolve_info),
|
||||
"argument" => fn_call::argument(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
"strip_parens" => strip_parens(contexts),
|
||||
|
|
@ -825,13 +928,13 @@ pub(super) fn resolve_fn_call_edge<'a, 'b: 'a>(
|
|||
}
|
||||
|
||||
mod fn_call {
|
||||
use oxc_ast::ast::Argument;
|
||||
use oxc_span::GetSpan;
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use crate::vertex::ArgumentVertex;
|
||||
|
||||
use super::super::vertex::Vertex;
|
||||
|
||||
pub(super) fn callee<'a, 'b: 'a>(
|
||||
|
|
@ -851,7 +954,7 @@ mod fn_call {
|
|||
})
|
||||
}
|
||||
|
||||
pub(super) fn arguments<'a, 'b: 'a>(
|
||||
pub(super) fn argument<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
_resolve_info: &ResolveEdgeInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, VertexIterator<'a, Vertex<'b>>> {
|
||||
|
|
@ -864,11 +967,8 @@ mod fn_call {
|
|||
.call_expression
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|x| {
|
||||
Vertex::Argument(match x {
|
||||
Argument::SpreadElement(spread) => spread.span,
|
||||
Argument::Expression(expr) => expr.span(),
|
||||
})
|
||||
.map(|argument| {
|
||||
Vertex::Argument(ArgumentVertex { ast_node: None, argument }.into())
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
|
@ -1990,6 +2090,85 @@ mod path_part {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_parameter_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 {
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
"span" => parameter::span(contexts, resolve_info),
|
||||
"assignment" => parameter::assignment(contexts, resolve_info),
|
||||
"type_annotation" => parameter::type_annotation(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Parameter'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod parameter {
|
||||
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use crate::vertex::TypeAnnotationVertex;
|
||||
|
||||
use super::{super::vertex::Vertex, get_span};
|
||||
|
||||
pub(super) fn assignment<'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::AssignmentType(
|
||||
&v.as_parameter()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a parameter vertex, instead have: {v:#?}")
|
||||
})
|
||||
.parameter
|
||||
.pattern
|
||||
.kind,
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn type_annotation<'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_parameter()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a parameter vertex, instead have: {v:#?}")
|
||||
})
|
||||
.parameter
|
||||
.pattern
|
||||
.type_annotation
|
||||
.as_ref()
|
||||
.map(|type_annotation| {
|
||||
Vertex::TypeAnnotation(
|
||||
TypeAnnotationVertex { type_annotation, ast_node: None }.into(),
|
||||
)
|
||||
})
|
||||
.into_iter(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
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_reassignment_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,25 @@ use crate::{
|
|||
Adapter,
|
||||
};
|
||||
|
||||
pub(super) fn resolve_arrow_function_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
_resolve_info: &ResolveInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
|
||||
match property_name {
|
||||
"is_async" => resolve_property_with(contexts, |v| v.function_is_async().into()),
|
||||
"is_generator" => resolve_property_with(contexts, |v| v.function_is_generator().into()),
|
||||
"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 'AssignmentType'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_assignment_type_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
@ -205,6 +224,11 @@ pub(super) fn resolve_fn_declaration_property<'a, 'b: 'a>(
|
|||
.as_ref()
|
||||
.map_or_else(|| FieldValue::Null, |f| f.name.to_string().into())
|
||||
}),
|
||||
"is_async" => resolve_property_with(contexts, |v| v.function_is_async().into()),
|
||||
"is_generator" => resolve_property_with(contexts, |v| v.function_is_generator().into()),
|
||||
"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 'FnDeclaration'"
|
||||
|
|
@ -228,6 +252,25 @@ pub(super) fn resolve_fn_call_property<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_function_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
_resolve_info: &ResolveInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
|
||||
match property_name {
|
||||
"is_async" => resolve_property_with(contexts, |v| v.function_is_async().into()),
|
||||
"is_generator" => resolve_property_with(contexts, |v| v.function_is_generator().into()),
|
||||
"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 'Function'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_import_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
@ -438,6 +481,29 @@ pub(super) fn resolve_object_literal_property<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_parameter_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
_resolve_info: &ResolveInfo,
|
||||
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
|
||||
match property_name {
|
||||
"is_readonly" => resolve_property_with(contexts, |v| {
|
||||
v.as_parameter()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a parameter vertex, instead have: {v:#?}")
|
||||
})
|
||||
.parameter
|
||||
.readonly
|
||||
.into()
|
||||
}),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to read unexpected property '{property_name}' on type 'Parameter'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_path_part_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ type File {
|
|||
import: [ImportAST!]!
|
||||
variable_declaration: [VariableDeclarationAST!]!
|
||||
|
||||
function: [Function!]!
|
||||
|
||||
ast_node: [ASTNode!]!
|
||||
}
|
||||
|
||||
|
|
@ -391,13 +393,24 @@ type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode
|
|||
span: Span!
|
||||
}
|
||||
|
||||
interface Argument {
|
||||
interface Argument implements HasSpan {
|
||||
value: Expression!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ArgumentAST implements Argument & HasSpan & ASTNode {
|
||||
value: Expression!
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface FnCall implements Expression & HasSpan {
|
||||
callee: Expression!
|
||||
arguments: [Argument!]!
|
||||
argument: [Argument!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
|
|
@ -408,7 +421,7 @@ interface FnCall implements Expression & HasSpan {
|
|||
|
||||
type FnCallAST implements FnCall & Expression & HasSpan & ASTNode {
|
||||
callee: Expression!
|
||||
arguments: [Argument!]!
|
||||
argument: [Argument!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
|
|
@ -481,12 +494,79 @@ type FunctionBodyAST implements HasSpan & ASTNode & FunctionBody {
|
|||
ancestor: [ASTNode!]!
|
||||
}
|
||||
|
||||
interface ArrowFunction implements HasSpan {
|
||||
interface Function implements Expression & HasSpan {
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
parameter: [Parameter]!
|
||||
|
||||
# Expression
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
ie: const a = "apple"; const b = `blueberry`
|
||||
"""
|
||||
as_constant_string: String
|
||||
strip_parens: Expression!
|
||||
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ArrowFunctionAST implements HasSpan & ArrowFunction & ASTNode {
|
||||
type Parameter {
|
||||
is_readonly: Boolean!
|
||||
assignment: AssignmentType!
|
||||
type_annotation: TypeAnnotation!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ParameterAST implements ASTNode & HasSpan {
|
||||
is_readonly: Boolean!
|
||||
assignment: AssignmentType!
|
||||
type_annotation: TypeAnnotation!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
}
|
||||
|
||||
interface ArrowFunction implements Function & HasSpan & Expression {
|
||||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
parameter: [Parameter]!
|
||||
# Expression
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
ie: const a = "apple"; const b = `blueberry`
|
||||
"""
|
||||
as_constant_string: String
|
||||
strip_parens: Expression!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type ArrowFunctionAST implements Function & HasSpan & ArrowFunction & ASTNode & Expression {
|
||||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
parameter: [Parameter]!
|
||||
# Expression
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
ie: const a = "apple"; const b = `blueberry`
|
||||
"""
|
||||
as_constant_string: String
|
||||
strip_parens: Expression!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
# ASTNode
|
||||
|
|
@ -497,13 +577,27 @@ type ArrowFunctionAST implements HasSpan & ArrowFunction & ASTNode {
|
|||
"""
|
||||
A function defined in the sourcecode.
|
||||
"""
|
||||
interface FnDeclaration implements HasSpan {
|
||||
interface FnDeclaration implements Function & HasSpan & Expression {
|
||||
"""
|
||||
If this function is used an an expression, the name can be omitted.
|
||||
ie: "const a = function() {};"
|
||||
"""
|
||||
name: String
|
||||
|
||||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
parameter: [Parameter]!
|
||||
# Expression
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
ie: const a = "apple"; const b = `blueberry`
|
||||
"""
|
||||
as_constant_string: String
|
||||
strip_parens: Expression!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
|
@ -511,12 +605,26 @@ interface FnDeclaration implements HasSpan {
|
|||
"""
|
||||
A function defined in the sourcecode.
|
||||
"""
|
||||
type FnDeclarationAST implements ASTNode & FnDeclaration & HasSpan {
|
||||
type FnDeclarationAST implements Function & ASTNode & FnDeclaration & HasSpan & Expression {
|
||||
name: String
|
||||
|
||||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
parameter: [Parameter]!
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
# Expression
|
||||
"""
|
||||
Only non-null if the string can be trivially coerced to a constant string
|
||||
ie: const a = "apple"; const b = `blueberry`
|
||||
"""
|
||||
as_constant_string: String
|
||||
strip_parens: Expression!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use enum_as_inner::EnumAsInner;
|
|||
use oxc_ast::{ast::*, AstKind};
|
||||
use oxc_semantic::{AstNode, AstNodeId};
|
||||
use oxc_span::{GetSpan, Span};
|
||||
use trustfall::provider::Typename;
|
||||
use trustfall::provider::{Typename, VertexIterator};
|
||||
use url::Url;
|
||||
|
||||
use crate::util::{expr_to_maybe_const_string, jsx_attribute_to_constant_string};
|
||||
|
|
@ -52,9 +52,10 @@ pub enum Vertex<'a> {
|
|||
FnCall(Rc<FnCallVertex<'a>>),
|
||||
FnDeclaration(Rc<FnDeclarationVertex<'a>>),
|
||||
ArrowFunction(Rc<ArrowFunctionVertex<'a>>),
|
||||
Argument(Span),
|
||||
Argument(Rc<ArgumentVertex<'a>>),
|
||||
FunctionBody(Rc<FunctionBodyVertex<'a>>),
|
||||
Statement(&'a Statement<'a>),
|
||||
Parameter(Rc<ParameterVertex<'a>>),
|
||||
}
|
||||
|
||||
impl<'a> Vertex<'a> {
|
||||
|
|
@ -95,11 +96,12 @@ impl<'a> Vertex<'a> {
|
|||
Self::Reassignment(data) => data.assignment_expression.span,
|
||||
Self::Name(data) => data.name.span,
|
||||
Self::FnCall(data) => data.call_expression.span,
|
||||
Self::Argument(data) => *data,
|
||||
Self::Argument(data) => data.argument.span(),
|
||||
Self::FnDeclaration(data) => data.function.span,
|
||||
Self::ArrowFunction(data) => data.arrow_expression.span,
|
||||
Self::FunctionBody(data) => data.function_body.span,
|
||||
Self::Statement(data) => data.span(),
|
||||
Self::Parameter(data) => data.parameter.span,
|
||||
Self::File
|
||||
| Self::Url(_)
|
||||
| Self::PathPart(_)
|
||||
|
|
@ -133,6 +135,8 @@ impl<'a> Vertex<'a> {
|
|||
Vertex::FnDeclaration(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::ArrowFunction(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::FunctionBody(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::Parameter(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::Argument(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::DefaultImport(_)
|
||||
| Vertex::Statement(_)
|
||||
| Vertex::AssignmentType(_)
|
||||
|
|
@ -152,7 +156,6 @@ impl<'a> Vertex<'a> {
|
|||
| Vertex::SpecificImport(_)
|
||||
| Vertex::Span(_)
|
||||
| Vertex::SearchParameter(_)
|
||||
| Vertex::Argument(_)
|
||||
| Vertex::ClassProperty(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -190,6 +193,39 @@ impl<'a> Vertex<'a> {
|
|||
) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn function_is_async(&self) -> bool {
|
||||
match &self {
|
||||
Vertex::ArrowFunction(data) => data.arrow_expression.r#async,
|
||||
Vertex::FnDeclaration(data) => data.function.r#async,
|
||||
_ => unreachable!(
|
||||
"'function_is_async' function should only ever be called with an ArrowFunction or FnDeclaration"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn function_is_generator(&self) -> bool {
|
||||
match &self {
|
||||
Vertex::ArrowFunction(data) => data.arrow_expression.generator,
|
||||
Vertex::FnDeclaration(data) => data.function.generator,
|
||||
_ => unreachable!(
|
||||
"'function_is_generator' function should only ever be called with an ArrowFunction or FnDeclaration"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn function_parameter(&self) -> VertexIterator<'a, Vertex<'a>> {
|
||||
let parameter = match &self {
|
||||
Vertex::ArrowFunction(data) => &data.arrow_expression.params.items,
|
||||
Vertex::FnDeclaration(data) => &data.function.params.items,
|
||||
_ => unreachable!(
|
||||
"'function_parameter' function should only ever be called with an ArrowFunction or FnDeclaration"
|
||||
),
|
||||
};
|
||||
Box::new(parameter.iter().map(|parameter| {
|
||||
Vertex::Parameter(ParameterVertex { ast_node: None, parameter }.into())
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl Typename for Vertex<'_> {
|
||||
|
|
@ -235,10 +271,11 @@ impl Typename for Vertex<'_> {
|
|||
Vertex::ObjectEntry(entry) => entry.typename(),
|
||||
Vertex::FnCall(fncall) => fncall.typename(),
|
||||
Vertex::Reassignment(reassignment) => reassignment.typename(),
|
||||
Vertex::Argument(_) => "Argument",
|
||||
Vertex::Argument(arg) => arg.typename(),
|
||||
Vertex::FnDeclaration(fndecl) => fndecl.typename(),
|
||||
Vertex::ArrowFunction(arrow_fn) => arrow_fn.typename(),
|
||||
Vertex::FunctionBody(fn_body) => fn_body.typename(),
|
||||
Vertex::Parameter(param) => param.typename(),
|
||||
Vertex::Statement(_) => "Statement",
|
||||
}
|
||||
}
|
||||
|
|
@ -319,6 +356,12 @@ impl<'a> From<AstNode<'a>> for Vertex<'a> {
|
|||
AstKind::FunctionBody(function_body) => Vertex::FunctionBody(
|
||||
FunctionBodyVertex { ast_node: Some(ast_node), function_body }.into(),
|
||||
),
|
||||
AstKind::FormalParameter(parameter) => {
|
||||
Vertex::Parameter(ParameterVertex { ast_node: Some(ast_node), parameter }.into())
|
||||
}
|
||||
AstKind::Argument(argument) => {
|
||||
Vertex::Argument(ArgumentVertex { ast_node: Some(ast_node), argument }.into())
|
||||
}
|
||||
_ => Vertex::ASTNode(ast_node),
|
||||
}
|
||||
}
|
||||
|
|
@ -502,7 +545,7 @@ impl<'a> Typename for ReturnVertex<'a> {
|
|||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TypeAnnotationVertex<'a> {
|
||||
ast_node: Option<AstNode<'a>>,
|
||||
pub ast_node: Option<AstNode<'a>>,
|
||||
pub type_annotation: &'a TSTypeAnnotation<'a>,
|
||||
}
|
||||
|
||||
|
|
@ -743,3 +786,37 @@ impl<'a> Typename for FunctionBodyVertex<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParameterVertex<'a> {
|
||||
ast_node: Option<AstNode<'a>>,
|
||||
pub parameter: &'a FormalParameter<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for ParameterVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"ParameterAST"
|
||||
} else {
|
||||
"Parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArgumentVertex<'a> {
|
||||
pub ast_node: Option<AstNode<'a>>,
|
||||
pub argument: &'a Argument<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for ArgumentVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"ArgumentAST"
|
||||
} else {
|
||||
"Argument"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue