mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(query): add FnCall and Argument types (#737)
This commit is contained in:
parent
a041fbd96b
commit
99a7ad4319
5 changed files with 203 additions and 6 deletions
|
|
@ -106,6 +106,11 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"FnCallAST" | "FnCall" => super::properties::resolve_fn_call_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
),
|
||||
"ImportAST" | "Import" => super::properties::resolve_import_property(
|
||||
contexts,
|
||||
property_name.as_ref(),
|
||||
|
|
@ -209,6 +214,12 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"Argument" => super::edges::resolve_argument_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
),
|
||||
"AssignmentType" => super::edges::resolve_assignment_type_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
@ -260,6 +271,13 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"FnCallAST" | "FnCall" => super::edges::resolve_fn_call_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
parameters,
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"HasSpan" => super::edges::resolve_has_span_edge(
|
||||
contexts,
|
||||
edge_name.as_ref(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,35 @@ use trustfall::provider::{
|
|||
use super::vertex::Vertex;
|
||||
use crate::Adapter;
|
||||
|
||||
pub(super) fn resolve_argument_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" => argument::span(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'Argument'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod argument {
|
||||
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_astnode_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
@ -640,6 +669,83 @@ mod file {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_fn_call_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" => fn_call::span(contexts, resolve_info),
|
||||
"ancestor" => ancestors(contexts, adapter),
|
||||
"parent" => parents(contexts, adapter),
|
||||
"callee" => fn_call::callee(contexts, resolve_info),
|
||||
"arguments" => fn_call::arguments(contexts, resolve_info),
|
||||
_ => {
|
||||
unreachable!("attempted to resolve unexpected edge '{edge_name}' on type 'FnCall'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod fn_call {
|
||||
use oxc_ast::ast::Argument;
|
||||
use oxc_span::GetSpan;
|
||||
use trustfall::provider::{
|
||||
resolve_neighbors_with, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
|
||||
VertexIterator,
|
||||
};
|
||||
|
||||
use super::super::vertex::Vertex;
|
||||
|
||||
pub(super) fn callee<'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_fn_call()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a fncall vertex, instead have: {v:#?}")
|
||||
})
|
||||
.call_expression
|
||||
.callee)
|
||||
.into(),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn arguments<'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_fn_call()
|
||||
.unwrap_or_else(|| {
|
||||
panic!("expected to have a fncall vertex, instead have: {v:#?}")
|
||||
})
|
||||
.call_expression
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|x| {
|
||||
Vertex::Argument(match x {
|
||||
Argument::SpreadElement(spread) => spread.span,
|
||||
Argument::Expression(expr) => expr.span(),
|
||||
})
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
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_has_span_edge<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
edge_name: &str,
|
||||
|
|
|
|||
|
|
@ -189,6 +189,21 @@ pub(super) fn resolve_expression_property<'a, 'b: 'a>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_fn_call_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 'FnCall'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_import_property<'a, 'b: 'a>(
|
||||
contexts: ContextIterator<'a, Vertex<'b>>,
|
||||
property_name: &str,
|
||||
|
|
|
|||
|
|
@ -386,6 +386,33 @@ type ObjectLiteralAST implements ObjectLiteral & Expression & HasSpan & ASTNode
|
|||
span: Span!
|
||||
}
|
||||
|
||||
interface Argument {
|
||||
span: Span!
|
||||
}
|
||||
|
||||
interface FnCall implements Expression & HasSpan {
|
||||
callee: Expression!
|
||||
arguments: [Argument!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
type FnCallAST implements FnCall & Expression & HasSpan & ASTNode {
|
||||
callee: Expression!
|
||||
arguments: [Argument!]!
|
||||
|
||||
# Expression
|
||||
as_constant_string: String
|
||||
# ASTNode
|
||||
parent: ASTNode
|
||||
ancestor: [ASTNode!]!
|
||||
# HasSpan
|
||||
span: Span!
|
||||
}
|
||||
|
||||
"""
|
||||
Any assignment that isn't a variable declaration, which means no const/let/var.
|
||||
ie: "a = 1;", "a /= 1;", "a += 1;", etc.
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ use std::rc::Rc;
|
|||
use enum_as_inner::EnumAsInner;
|
||||
use oxc_ast::{
|
||||
ast::{
|
||||
AssignmentExpression, 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,
|
||||
AssignmentExpression, BindingPatternKind, CallExpression, 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,
|
||||
|
|
@ -59,6 +59,8 @@ pub enum Vertex<'a> {
|
|||
ObjectEntry(Rc<ObjectEntryVertex<'a>>),
|
||||
DotProperty(Rc<DotPropertyVertex<'a>>),
|
||||
Reassignment(Rc<ReassignmentVertex<'a>>),
|
||||
FnCall(Rc<FnCallVertex<'a>>),
|
||||
Argument(Span),
|
||||
}
|
||||
|
||||
impl<'a> Vertex<'a> {
|
||||
|
|
@ -98,6 +100,8 @@ impl<'a> Vertex<'a> {
|
|||
Self::NumberLiteral(data) => data.number_literal.span,
|
||||
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::File
|
||||
| Self::Url(_)
|
||||
| Self::PathPart(_)
|
||||
|
|
@ -127,6 +131,7 @@ impl<'a> Vertex<'a> {
|
|||
Vertex::ObjectEntry(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::DotProperty(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::Reassignment(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::FnCall(data) => data.ast_node.map(|x| x.id()),
|
||||
Vertex::DefaultImport(_)
|
||||
| Vertex::AssignmentType(_)
|
||||
| Vertex::ClassMethod(_)
|
||||
|
|
@ -145,6 +150,7 @@ impl<'a> Vertex<'a> {
|
|||
| Vertex::SpecificImport(_)
|
||||
| Vertex::Span(_)
|
||||
| Vertex::SearchParameter(_)
|
||||
| Vertex::Argument(_)
|
||||
| Vertex::ClassProperty(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +231,9 @@ impl Typename for Vertex<'_> {
|
|||
Vertex::IfStatementAST(_) => "IfStatementAST",
|
||||
Vertex::SpreadIntoObject(obj) => obj.typename(),
|
||||
Vertex::ObjectEntry(entry) => entry.typename(),
|
||||
Vertex::FnCall(fncall) => fncall.typename(),
|
||||
Vertex::Reassignment(reassignment) => reassignment.typename(),
|
||||
Vertex::Argument(_) => "Argument",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -293,6 +301,9 @@ impl<'a> From<AstNode<'a>> for Vertex<'a> {
|
|||
AstKind::AssignmentExpression(assignment_expression) => Vertex::Reassignment(
|
||||
ReassignmentVertex { ast_node: Some(ast_node), assignment_expression }.into(),
|
||||
),
|
||||
AstKind::CallExpression(call_expression) => {
|
||||
Vertex::FnCall(FnCallVertex { ast_node: Some(ast_node), call_expression }.into())
|
||||
}
|
||||
_ => Vertex::ASTNode(ast_node),
|
||||
}
|
||||
}
|
||||
|
|
@ -321,6 +332,9 @@ impl<'a> From<&'a Expression<'a>> for Vertex<'a> {
|
|||
Expression::AssignmentExpression(assignment_expression) => Vertex::Reassignment(
|
||||
ReassignmentVertex { ast_node: None, assignment_expression }.into(),
|
||||
),
|
||||
Expression::CallExpression(call_expression) => {
|
||||
Vertex::FnCall(FnCallVertex { ast_node: None, call_expression }.into())
|
||||
}
|
||||
_ => Vertex::Expression(expr),
|
||||
}
|
||||
}
|
||||
|
|
@ -619,3 +633,20 @@ impl<'a> Typename for ReassignmentVertex<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FnCallVertex<'a> {
|
||||
ast_node: Option<AstNode<'a>>,
|
||||
pub call_expression: &'a CallExpression<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Typename for FnCallVertex<'a> {
|
||||
fn typename(&self) -> &'static str {
|
||||
if self.ast_node.is_some() {
|
||||
"FnCallAST"
|
||||
} else {
|
||||
"FnCall"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue