mirror of
https://github.com/danbulant/oxc
synced 2026-05-20 12:48:38 +00:00
feat(query): Add is_getter, is_setter, is_constructor to all Function implementors (#1526)
--- <details open="true"><summary>Generated summary (powered by <a href="https://app.graphite.dev">Graphite</a>)</summary> > # TL;DR > This pull request adds new properties to the `ArrowFunction`, `FnDeclaration`, and `Function` interfaces in the Trustfall schema. It also adds implementation for resolving these properties in the `adapter.rs` and `properties.rs` files. Additionally, it adds a new method `function_scope_flag` to the `Vertex` struct in the `vertex.rs` file. > > # What changed > - Added new properties (`is_getter`, `is_setter`, `is_constructor`) to the `ArrowFunction`, `FnDeclaration`, and `Function` interfaces in the Trustfall schema. > - Implemented the resolution of these properties in the `resolve_arrow_function_property`, `resolve_fn_declaration_property`, and `resolve_function_property` functions in the `properties.rs` file. > - Added a new method `function_scope_flag` to the `Vertex` struct in the `vertex.rs` file. > > # How to test > 1. Run the test suite to ensure that all existing tests pass. > 2. Add new tests to cover the newly added properties and the `function_scope_flag` method. > 3. Run the test suite again and ensure that all tests pass. > > # Why make this change > - The new properties (`is_getter`, `is_setter`, `is_constructor`) provide additional information about functions in the Trustfall schema, allowing clients to query for these properties. > - The `function_scope_flag` method in the `Vertex` struct provides a convenient way to access the scope flags of a function node, which can be useful for various analysis and processing tasks. </details>
This commit is contained in:
parent
8251a343aa
commit
9a5bb008e7
4 changed files with 81 additions and 1 deletions
|
|
@ -86,6 +86,7 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
self,
|
||||
)
|
||||
}
|
||||
"AssignmentType" => super::properties::resolve_assignment_type_property(
|
||||
|
|
@ -128,6 +129,7 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
self,
|
||||
)
|
||||
}
|
||||
"FnCallAST" | "FnCall" => super::properties::resolve_fn_call_property(
|
||||
|
|
@ -139,6 +141,7 @@ impl<'a, 'b: 'a> trustfall::provider::Adapter<'a> for &'a Adapter<'b> {
|
|||
contexts,
|
||||
property_name.as_ref(),
|
||||
resolve_info,
|
||||
self,
|
||||
),
|
||||
"ImportAST" | "Import" => super::properties::resolve_import_property(
|
||||
contexts,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use oxc_ast::ast::{BindingPatternKind, Expression};
|
||||
use oxc_semantic::ScopeFlags;
|
||||
use trustfall::{
|
||||
provider::{
|
||||
field_property, resolve_property_with, ContextIterator, ContextOutcomeIterator, ResolveInfo,
|
||||
|
|
@ -73,6 +74,7 @@ pub(super) fn resolve_arrow_function_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_async" => resolve_property_with(contexts, |v| v.function_is_async().into()),
|
||||
|
|
@ -80,6 +82,15 @@ pub(super) fn resolve_arrow_function_property<'a, 'b: 'a>(
|
|||
"as_constant_string" => resolve_property_with(contexts, |v| {
|
||||
v.as_constant_string().map_or(FieldValue::Null, Into::into)
|
||||
}),
|
||||
"is_getter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::GetAccessor).into()
|
||||
}),
|
||||
"is_setter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::SetAccessor).into()
|
||||
}),
|
||||
"is_constructor" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::Constructor).into()
|
||||
}),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to read unexpected property '{property_name}' on type 'ArrowFunction'"
|
||||
|
|
@ -264,6 +275,7 @@ pub(super) fn resolve_fn_declaration_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 {
|
||||
"name" => resolve_property_with(contexts, |v| {
|
||||
|
|
@ -281,6 +293,15 @@ pub(super) fn resolve_fn_declaration_property<'a, 'b: 'a>(
|
|||
"as_constant_string" => resolve_property_with(contexts, |v| {
|
||||
v.as_constant_string().map_or(FieldValue::Null, Into::into)
|
||||
}),
|
||||
"is_getter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::GetAccessor).into()
|
||||
}),
|
||||
"is_setter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::SetAccessor).into()
|
||||
}),
|
||||
"is_constructor" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::Constructor).into()
|
||||
}),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to read unexpected property '{property_name}' on type 'FnDeclaration'"
|
||||
|
|
@ -308,6 +329,7 @@ pub(super) fn resolve_function_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_async" => resolve_property_with(contexts, |v| v.function_is_async().into()),
|
||||
|
|
@ -315,6 +337,15 @@ pub(super) fn resolve_function_property<'a, 'b: 'a>(
|
|||
"as_constant_string" => resolve_property_with(contexts, |v| {
|
||||
v.as_constant_string().map_or(FieldValue::Null, Into::into)
|
||||
}),
|
||||
"is_getter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::GetAccessor).into()
|
||||
}),
|
||||
"is_setter" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::SetAccessor).into()
|
||||
}),
|
||||
"is_constructor" => resolve_property_with(contexts, |v| {
|
||||
v.function_scope_flag(adapter).contains(ScopeFlags::Constructor).into()
|
||||
}),
|
||||
_ => {
|
||||
unreachable!(
|
||||
"attempted to read unexpected property '{property_name}' on type 'Function'"
|
||||
|
|
|
|||
|
|
@ -661,6 +661,11 @@ type FunctionBodyAST implements HasSpan & ASTNode & FunctionBody {
|
|||
interface Function implements Expression & HasSpan {
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
|
||||
is_getter: Boolean!
|
||||
is_setter: Boolean!
|
||||
is_constructor: Boolean!
|
||||
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
|
|
@ -832,6 +837,9 @@ interface ArrowFunction implements Function & HasSpan & Expression {
|
|||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
is_getter: Boolean!
|
||||
is_setter: Boolean!
|
||||
is_constructor: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
|
|
@ -860,6 +868,9 @@ type ArrowFunctionAST implements Function & HasSpan & ArrowFunction & ASTNode &
|
|||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
is_getter: Boolean!
|
||||
is_setter: Boolean!
|
||||
is_constructor: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
|
|
@ -900,6 +911,9 @@ interface FnDeclaration implements Function & HasSpan & Expression {
|
|||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
is_getter: Boolean!
|
||||
is_setter: Boolean!
|
||||
is_constructor: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
|
|
@ -933,6 +947,9 @@ type FnDeclarationAST implements Function & ASTNode & FnDeclaration & HasSpan &
|
|||
# Function
|
||||
is_async: Boolean!
|
||||
is_generator: Boolean!
|
||||
is_getter: Boolean!
|
||||
is_setter: Boolean!
|
||||
is_constructor: Boolean!
|
||||
"""
|
||||
Does not include rest parameter if it exists.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use enum_as_inner::EnumAsInner;
|
|||
use oxc_ast::ast::ArrayExpressionElement;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::{ast::*, AstKind};
|
||||
use oxc_semantic::{AstNode, AstNodeId};
|
||||
use oxc_semantic::{AstNode, AstNodeId, ScopeFlags};
|
||||
use oxc_span::{GetSpan, Span};
|
||||
use trustfall::provider::{Typename, VertexIterator};
|
||||
use url::Url;
|
||||
|
|
@ -278,6 +278,35 @@ impl<'a> Vertex<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn function_scope_flag(&self, adapter: &Adapter<'_>) -> ScopeFlags {
|
||||
let (wanted_node_hash, wanted_node_span) = match &self {
|
||||
Vertex::ArrowFunction(data) => (calculate_hash(data.arrow_expression), data.arrow_expression.span),
|
||||
Vertex::FnDeclaration(data) => (calculate_hash(data.function), data.function.span),
|
||||
_ => unreachable!(
|
||||
"'function_scope_flag' function should only ever be called with an ArrowFunction or FnDeclaration"
|
||||
),
|
||||
};
|
||||
|
||||
let found = adapter.semantic.nodes().iter().find(|x| {
|
||||
let span = x.kind().span();
|
||||
|
||||
if span.start != wanted_node_span.start || span.end != wanted_node_span.end {
|
||||
return false;
|
||||
}
|
||||
|
||||
let hash_of_node = match x.kind() {
|
||||
AstKind::ArrowExpression(ae) => calculate_hash(ae),
|
||||
AstKind::Function(fn_) => calculate_hash(fn_),
|
||||
_ => return false,
|
||||
};
|
||||
hash_of_node == wanted_node_hash
|
||||
});
|
||||
|
||||
adapter.semantic.scopes().get_flags(
|
||||
found.expect("an arrowexpression or function should always be in the ast if we can have the struct of it").scope_id(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn function_parameter(&self) -> VertexIterator<'a, Vertex<'a>> {
|
||||
let parameter = match &self {
|
||||
Vertex::ArrowFunction(data) => &data.arrow_expression.params.items,
|
||||
|
|
|
|||
Loading…
Reference in a new issue