oxc/crates/oxc_query/src/properties.rs
2023-08-15 03:30:59 -04:00

590 lines
20 KiB
Rust

use std::convert::Into;
use oxc_ast::ast::{BindingPatternKind, Expression};
use trustfall::{
provider::{
field_property, resolve_property_with, ContextIterator, ContextOutcomeIterator, ResolveInfo,
},
FieldValue,
};
use super::vertex::Vertex;
use crate::{
util::{
accessibility_to_string, jsx_attribute_name_to_string, jsx_attribute_to_constant_string,
jsx_element_name_to_string,
},
Adapter,
};
pub(super) fn resolve_assignment_type_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"assignment_to_variable_name" => resolve_property_with(contexts, |v| {
let Vertex::AssignmentType(BindingPatternKind::BindingIdentifier(ident)) = v else {
return FieldValue::Null;
};
ident.name.to_string().into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'AssignmentType'"
)
}
}
}
pub(super) fn resolve_class_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"extended_class_name" => resolve_property_with(contexts, |v| {
v.as_class()
.unwrap_or_else(|| panic!("expected to have a class vertex, instead have: {v:#?}"))
.class
.super_class
.as_ref()
.and_then(|expr| match expr {
Expression::Identifier(ident) => Some(ident.name.to_string().into()),
_ => None,
})
.unwrap_or(FieldValue::Null)
}),
"name" => resolve_property_with(contexts, |v| {
v.as_class()
.unwrap_or_else(|| panic!("expected to have a class vertex, instead have: {v:#?}"))
.class
.id
.as_ref()
.map_or_else(|| FieldValue::Null, |x| x.name.to_string().into())
}),
"is_abstract" => resolve_property_with(contexts, |v| {
v.as_class()
.unwrap_or_else(|| panic!("expected to have a class vertex, instead have: {v:#?}"))
.class
.modifiers
.contains(oxc_ast::ast::ModifierKind::Abstract)
.into()
}),
_ => {
unreachable!("attempted to read unexpected property '{property_name}' on type 'Class'")
}
}
}
pub(super) fn resolve_class_method_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"accessibility" => resolve_property_with(contexts, |v| {
v.as_class_method()
.unwrap_or_else(|| {
panic!("expected to have a classmethod vertex, instead have: {v:#?}")
})
.method
.accessibility
.map(accessibility_to_string)
.map_or(FieldValue::Null, Into::into)
}),
"is_abstract" => {
resolve_property_with(contexts, field_property!(as_class_method, is_abstract))
}
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'ClassMethod'"
)
}
}
}
pub(super) fn resolve_class_property_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"accessibility" => resolve_property_with(contexts, |v| {
v.as_class_property()
.unwrap_or_else(|| {
panic!("expected to have a classproperty vertex, instead have: {v:#?}")
})
.property
.accessibility
.map(accessibility_to_string)
.map_or(FieldValue::Null, Into::into)
}),
"is_abstract" => {
resolve_property_with(contexts, field_property!(as_class_method, is_abstract))
}
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'ClassProperty'"
)
}
}
}
pub(super) fn resolve_default_import_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"local_name" => resolve_property_with(contexts, |v| {
v.as_default_import()
.unwrap_or_else(|| {
panic!("expected to have a defaultimport vertex, instead have: {v:#?}")
})
.local
.name
.to_string()
.into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'DefaultImport'"
)
}
}
}
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,
_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 'Expression'"
)
}
}
}
pub(super) fn resolve_fn_declaration_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_fn_declaration()
.unwrap_or_else(|| {
panic!("expected to have a fndeclaration vertex, instead have: {v:#?}")
})
.function
.id
.as_ref()
.map_or_else(|| FieldValue::Null, |f| f.name.to_string().into())
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'FnDeclaration'"
)
}
}
}
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,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"from_path" => resolve_property_with(contexts, |v| {
v.as_import()
.unwrap_or_else(|| {
panic!("expected to have an import vertex, instead have: {v:#?}")
})
.import
.source
.value
.to_string()
.into()
}),
_ => {
unreachable!("attempted to read unexpected property '{property_name}' on type 'Import'")
}
}
}
pub(super) fn resolve_interface_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_interface().unwrap().interface.id.name.to_string().into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'InterfaceExtend'"
)
}
}
}
pub(super) fn resolve_jsxattribute_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| {
jsx_attribute_name_to_string(
&v.as_jsx_attribute()
.unwrap_or_else(|| {
panic!("expected to have a jsxattribute vertex, instead have: {v:#?}")
})
.name,
)
.into()
}),
"value_as_constant_string" => resolve_property_with(contexts, |v| {
let attr = v.as_jsx_attribute().unwrap_or_else(|| {
panic!("expected to have a jsxattribute vertex, instead have: {v:#?}")
});
jsx_attribute_to_constant_string(attr).map_or_else(|| FieldValue::Null, Into::into)
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'JSXAttribute'"
)
}
}
}
pub(super) fn resolve_jsxelement_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)
}),
"child_count" => resolve_property_with(
contexts,
field_property!(as_jsx_element, element, { (element.children.len() as u64).into() }),
),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'JSXElement'"
)
}
}
}
pub(super) fn resolve_jsxopening_element_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"attribute_count" => resolve_property_with(contexts, |v| {
let jsx = v.as_jsx_opening_element().unwrap_or_else(|| {
panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}")
});
(jsx.opening_element.attributes.len() as u64).into()
}),
"name" => resolve_property_with(contexts, |v| {
let data = v.as_jsx_opening_element().unwrap_or_else(|| {
panic!("expected to have a jsxopeningelement vertex, instead have: {v:#?}")
});
jsx_element_name_to_string(&data.opening_element.name).into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'JSXOpeningElement'"
)
}
}
}
pub(super) fn resolve_jsxtext_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"text" => resolve_property_with(contexts, |v| {
v.as_jsx_text()
.unwrap_or_else(|| {
panic!("expected to have a jsxtext vertex, instead have: {v:#?}")
})
.value
.to_string()
.into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'JSXText'"
)
}
}
}
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,
_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)
}),
"number" => resolve_property_with(contexts, |v| {
let number = v
.as_number_literal()
.unwrap_or_else(|| {
panic!("expected to have a numberliteral vertex, instead have: {v:#?}")
})
.number_literal
.value;
if number.is_finite() {
FieldValue::Float64(number)
} else {
FieldValue::Null
}
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'NumberLiteral'"
)
}
}
}
pub(super) fn resolve_object_literal_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 'ObjectLiteral'"
)
}
}
}
pub(super) fn resolve_path_part_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
adapter: &'a Adapter<'b>,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"is_first" => resolve_property_with(contexts, |v| {
(*v.as_path_part().unwrap_or_else(|| {
panic!("expected to have a pathpart vertex, instead have: {v:#?}")
}) == 0)
.into()
}),
"is_last" => {
let len = adapter.path_components.len();
resolve_property_with(contexts, move |v| {
(*v.as_path_part().unwrap_or_else(|| {
panic!("expected to have a pathpart vertex, instead have: {v:#?}")
}) == len - 1)
.into()
})
}
"name" => resolve_property_with(contexts, |v| {
adapter.path_components[*v.as_path_part().unwrap_or_else(|| {
panic!("expected to have a pathpart vertex, instead have: {v:#?}")
})]
.as_ref()
.map_or(FieldValue::Null, Into::into)
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'PathPart'"
)
}
}
}
pub(super) fn resolve_reassignment_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 'Reassignment'"
)
}
}
}
pub(super) fn resolve_search_parameter_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"key" => resolve_property_with(contexts, |v| {
v.as_search_parameter()
.unwrap_or_else(|| {
panic!("expected to have a searchparameter vertex, instead have: {v:#?}")
})
.key
.clone()
.into()
}),
"value" => resolve_property_with(contexts, |v| {
v.as_search_parameter()
.unwrap_or_else(|| {
panic!("expected to have a searchparameter vertex, instead have: {v:#?}")
})
.value
.clone()
.into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'SearchParameter'"
)
}
}
}
pub(super) fn resolve_span_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
adapter: &'a Adapter<'b>,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"str" => resolve_property_with(contexts, |v| {
let span = v
.as_span()
.unwrap_or_else(|| panic!("expected to have a span vertex, instead have: {v:#?}"));
adapter.semantic.source_text()[span.start as usize..span.end as usize].into()
}),
"end" => resolve_property_with(contexts, |v| {
v.as_span()
.unwrap_or_else(|| panic!("expected to have a span vertex, instead have: {v:#?}"))
.end
.into()
}),
"start" => resolve_property_with(contexts, |v| {
v.as_span()
.unwrap_or_else(|| panic!("expected to have a span vertex, instead have: {v:#?}"))
.start
.into()
}),
_ => {
unreachable!("attempted to read unexpected property '{property_name}' on type 'Span'")
}
}
}
pub(super) fn resolve_specific_import_property<'a, 'b: 'a>(
contexts: ContextIterator<'a, Vertex<'b>>,
property_name: &str,
_resolve_info: &ResolveInfo,
) -> ContextOutcomeIterator<'a, Vertex<'b>, FieldValue> {
match property_name {
"local_name" => resolve_property_with(contexts, |v| {
v.as_specific_import()
.unwrap_or_else(|| {
panic!("expected to have a specificimport vertex, instead have: {v:#?}")
})
.local
.name
.to_string()
.into()
}),
"original_name" => resolve_property_with(contexts, |v| {
v.as_specific_import()
.unwrap_or_else(|| {
panic!("expected to have a specificimport vertex, instead have: {v:#?}")
})
.imported
.name()
.to_string()
.into()
}),
_ => {
unreachable!(
"attempted to read unexpected property '{property_name}' on type 'SpecificImport'"
)
}
}
}