mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
527 lines
18 KiB
Rust
527 lines
18 KiB
Rust
use std::{
|
|
rc::Rc,
|
|
sync::{Arc, OnceLock},
|
|
};
|
|
|
|
use oxc_semantic::Semantic;
|
|
use trustfall::{
|
|
provider::{
|
|
resolve_coercion_using_schema, resolve_property_with, ContextIterator,
|
|
ContextOutcomeIterator, EdgeParameters, ResolveEdgeInfo, ResolveInfo, Typename,
|
|
VertexIterator,
|
|
},
|
|
FieldValue, Schema,
|
|
};
|
|
|
|
use super::vertex::Vertex;
|
|
|
|
static SCHEMA: OnceLock<Schema> = OnceLock::new();
|
|
|
|
#[non_exhaustive]
|
|
pub struct Adapter<'a> {
|
|
pub semantic: Rc<Semantic<'a>>,
|
|
pub path_components: Vec<Option<String>>,
|
|
}
|
|
|
|
pub const SCHEMA_TEXT: &str = include_str!("./schema.graphql");
|
|
|
|
/// Returns the schema from a OnceLock
|
|
///
|
|
/// # Panics
|
|
/// If the schema parse returns an error, which will not happen unless the schema get's corrupted.
|
|
pub fn schema() -> &'static Schema {
|
|
// internal note: this might not parser correctly due to making an incorrect schema during development
|
|
SCHEMA.get_or_init(|| Schema::parse(SCHEMA_TEXT).unwrap_or_else(|e| panic!("{}", e)))
|
|
}
|
|
|
|
impl<'a> Adapter<'a> {
|
|
pub fn new(semantic: Rc<Semantic<'a>>, path_components: Vec<Option<String>>) -> Self {
|
|
Self { semantic, path_components }
|
|
}
|
|
}
|
|
|
|
impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|
type Vertex = Vertex<'b>;
|
|
|
|
fn resolve_starting_vertices(
|
|
&self,
|
|
edge_name: &Arc<str>,
|
|
_parameters: &EdgeParameters,
|
|
resolve_info: &ResolveInfo,
|
|
) -> VertexIterator<'a, Self::Vertex> {
|
|
match edge_name.as_ref() {
|
|
"File" => super::entrypoints::file(resolve_info),
|
|
_ => {
|
|
unreachable!(
|
|
"attempted to resolve starting vertices for unexpected edge name: {edge_name}"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
fn resolve_property(
|
|
&self,
|
|
contexts: ContextIterator<'a, Self::Vertex>,
|
|
type_name: &Arc<str>,
|
|
property_name: &Arc<str>,
|
|
resolve_info: &ResolveInfo,
|
|
) -> ContextOutcomeIterator<'a, Self::Vertex, FieldValue> {
|
|
if property_name.as_ref() == "__typename" {
|
|
return resolve_property_with(contexts, |v| v.typename().into());
|
|
}
|
|
match type_name.as_ref() {
|
|
"AssignmentType" => super::properties::resolve_assignment_type_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"ClassAST" | "Class" => super::properties::resolve_class_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"ClassMethod" => super::properties::resolve_class_method_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"ClassProperty" => super::properties::resolve_class_property_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"DefaultImport" => super::properties::resolve_default_import_property(
|
|
contexts,
|
|
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(),
|
|
resolve_info,
|
|
),
|
|
"FnDeclarationAST" | "FnDeclaration" => {
|
|
super::properties::resolve_fn_declaration_property(
|
|
contexts,
|
|
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(),
|
|
resolve_info,
|
|
),
|
|
"InterfaceAST" | "Interface" => super::properties::resolve_interface_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"JSXAttribute" => super::properties::resolve_jsxattribute_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"JSXElementAST" | "JSXElement" => super::properties::resolve_jsxelement_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"JSXOpeningElementAST" | "JSXOpeningElement" => {
|
|
super::properties::resolve_jsxopening_element_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
)
|
|
}
|
|
"JSXText" => super::properties::resolve_jsxtext_property(
|
|
contexts,
|
|
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,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
)
|
|
}
|
|
"ObjectLiteralAST" | "ObjectLiteral" => {
|
|
super::properties::resolve_object_literal_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
)
|
|
}
|
|
"PathPart" => super::properties::resolve_path_part_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"ReassignmentAST" | "Reassignment" => super::properties::resolve_reassignment_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"SearchParameter" => super::properties::resolve_search_parameter_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
"Span" => super::properties::resolve_span_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"SpecificImport" => super::properties::resolve_specific_import_property(
|
|
contexts,
|
|
property_name.as_ref(),
|
|
resolve_info,
|
|
),
|
|
_ => {
|
|
unreachable!(
|
|
"attempted to read property '{property_name}' on unexpected type: {type_name}"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
fn resolve_neighbors(
|
|
&self,
|
|
contexts: ContextIterator<'a, Self::Vertex>,
|
|
type_name: &Arc<str>,
|
|
edge_name: &Arc<str>,
|
|
parameters: &EdgeParameters,
|
|
resolve_info: &ResolveEdgeInfo,
|
|
) -> ContextOutcomeIterator<'a, Self::Vertex, VertexIterator<'a, Self::Vertex>> {
|
|
match type_name.as_ref() {
|
|
"ArrowFunctionAST" | "ArrowFunction" => super::edges::resolve_arrow_function_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"ASTNode" => super::edges::resolve_astnode_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
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(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"Class" | "ClassAST" => super::edges::resolve_class_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"ClassMethod" => super::edges::resolve_class_method_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"ClassProperty" => super::edges::resolve_class_property_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
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(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"Expression" => super::edges::resolve_expression_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"FunctionBodyAST" | "FunctionBody" => super::edges::resolve_function_body_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"FnDeclarationAST" | "FnDeclaration" => super::edges::resolve_fn_declaration_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"File" => super::edges::resolve_file_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
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(),
|
|
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(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"Interface" | "InterfaceAST" => super::edges::resolve_interface_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"InterfaceExtend" => super::edges::resolve_interface_extend_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXAttribute" => super::edges::resolve_jsxattribute_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXElement" | "JSXElementAST" => super::edges::resolve_jsxelement_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"JSXExpressionContainer" => super::edges::resolve_jsxexpression_container_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXFragment" => super::edges::resolve_jsxfragment_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXOpeningElementAST" | "JSXOpeningElement" => {
|
|
super::edges::resolve_jsxopening_element_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
)
|
|
}
|
|
"JSXSpreadAttribute" => super::edges::resolve_jsxspread_attribute_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXSpreadChild" => super::edges::resolve_jsxspread_child_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"JSXText" => super::edges::resolve_jsxtext_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"MemberExtend" => super::edges::resolve_member_extend_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
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(),
|
|
parameters,
|
|
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(),
|
|
parameters,
|
|
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(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"ReassignmentAST" | "Reassignment" => super::edges::resolve_reassignment_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"ReturnAST" | "ReturnStatement" => super::edges::resolve_return_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"SimpleExtend" => super::edges::resolve_simple_extend_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"SpecificImport" => super::edges::resolve_specific_import_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"SpreadIntoObjectAST" | "SpreadIntoObject" => {
|
|
super::edges::resolve_spread_into_object_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
)
|
|
}
|
|
"Statement" => super::edges::resolve_statement_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"TypeAnnotation" | "TypeAnnotationAST" => super::edges::resolve_type_annotation_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
),
|
|
"Type" => super::edges::resolve_type_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"URL" => super::edges::resolve_url_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
),
|
|
"VariableDeclaration" | "VariableDeclarationAST" => {
|
|
super::edges::resolve_variable_declaration_edge(
|
|
contexts,
|
|
edge_name.as_ref(),
|
|
parameters,
|
|
resolve_info,
|
|
self,
|
|
)
|
|
}
|
|
_ => {
|
|
unreachable!(
|
|
"attempted to resolve edge '{edge_name}' on unexpected type: {type_name}"
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn resolve_coercion(
|
|
&self,
|
|
contexts: ContextIterator<'a, Self::Vertex>,
|
|
_type_name: &Arc<str>,
|
|
coerce_to_type: &Arc<str>,
|
|
_resolve_info: &ResolveInfo,
|
|
) -> ContextOutcomeIterator<'a, Self::Vertex, bool> {
|
|
resolve_coercion_using_schema(contexts, schema(), coerce_to_type.as_ref())
|
|
}
|
|
}
|