refactor(semantic): rename ancestors to ancestor_ids (#7215)

pure refactor, renaming this method to make it more clear that it returns only IDs, not nodes. in preparation for the next PR.
This commit is contained in:
camchenry 2024-11-09 07:00:15 +00:00
parent 846711cf41
commit 42171eba94
14 changed files with 28 additions and 25 deletions

View file

@ -67,7 +67,7 @@ fn is_constructor(node: &AstNode<'_>) -> bool {
fn is_definitely_in_constructor(ctx: &LintContext, node_id: NodeId) -> bool {
ctx.nodes()
.ancestors(node_id)
.ancestor_ids(node_id)
.map(|id| ctx.nodes().get_node(id))
.skip_while(|node| !node.kind().is_function_like())
.nth(1)

View file

@ -36,7 +36,7 @@ impl Rule for NoNew {
return;
};
let mut ancestors = ctx.nodes().ancestors(node.id()).skip(1);
let mut ancestors = ctx.nodes().ancestor_ids(node.id()).skip(1);
let Some(node_id) = ancestors.next() else { return };
let kind = ctx.nodes().kind(node_id);

View file

@ -69,7 +69,7 @@ impl Rule for NoUnsafeFinally {
let nodes = ctx.nodes();
let mut label_inside = false;
for node_id in nodes.ancestors(node.id()) {
for node_id in nodes.ancestor_ids(node.id()) {
let ast_kind = nodes.kind(node_id);
if sentinel_node_type.test(ast_kind) {

View file

@ -143,7 +143,7 @@ impl NoDuplicateHooks {
let hook_name = jest_fn_call.name.to_string();
let parent_node_id =
match ctx.nodes().ancestors(node.id()).find(|n| hook_contexts.contains_key(n)) {
match ctx.nodes().ancestor_ids(node.id()).find(|n| hook_contexts.contains_key(n)) {
Some(n) => Some(n),
_ => Some(root_node_id),
};

View file

@ -79,7 +79,7 @@ impl Rule for NoDuplicateHead {
}
if !matches!(
nodes.ancestors(reference.node_id()).nth(2).map(|node_id| nodes.kind(node_id)),
nodes.ancestor_ids(reference.node_id()).nth(2).map(|node_id| nodes.kind(node_id)),
Some(AstKind::JSXOpeningElement(_))
) {
continue;

View file

@ -48,7 +48,7 @@ fn has_no_bad_comparison_in_parents<'a, 'b>(
node: &'b AstNode<'a>,
ctx: &'b LintContext<'a>,
) -> bool {
for node_id in ctx.nodes().ancestors(node.id()).skip(1) {
for node_id in ctx.nodes().ancestor_ids(node.id()).skip(1) {
let kind = ctx.nodes().kind(node_id);
// `a === b === c === d === e` only produce one error, since `(a === b === c) === d === e` will produce two errors.

View file

@ -44,7 +44,7 @@ impl Rule for MissingThrow {
impl MissingThrow {
fn has_missing_throw<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> bool {
let mut node_ancestors = ctx.nodes().ancestors(node.id()).skip(1);
let mut node_ancestors = ctx.nodes().ancestor_ids(node.id()).skip(1);
let Some(node_id) = node_ancestors.next() else {
return false;

View file

@ -53,7 +53,7 @@ impl Rule for PreferAwaitToThen {
// Already inside a yield or await
if ctx
.nodes()
.ancestors(node.id())
.ancestor_ids(node.id())
.any(|node_id| is_inside_yield_or_await(ctx.nodes().get_node(node_id)))
{
return;

View file

@ -60,7 +60,7 @@ impl Rule for NoIsMounted {
return;
}
for ancestor in ctx.nodes().ancestors(node.id()).skip(1) {
for ancestor in ctx.nodes().ancestor_ids(node.id()).skip(1) {
if matches!(
ctx.nodes().kind(ancestor),
AstKind::ObjectProperty(_) | AstKind::MethodDefinition(_)

View file

@ -324,7 +324,10 @@ fn has_conditional_path_accept_throw(
}
fn parent_func<'a>(nodes: &'a AstNodes<'a>, node: &AstNode) -> Option<&'a AstNode<'a>> {
nodes.ancestors(node.id()).map(|id| nodes.get_node(id)).find(|it| it.kind().is_function_like())
nodes
.ancestor_ids(node.id())
.map(|id| nodes.get_node(id))
.find(|it| it.kind().is_function_like())
}
/// Checks if the `node_id` is a callback argument,
@ -346,7 +349,7 @@ fn is_non_react_func_arg(nodes: &AstNodes, node_id: NodeId) -> bool {
fn is_somewhere_inside_component_or_hook(nodes: &AstNodes, node_id: NodeId) -> bool {
nodes
.ancestors(node_id)
.ancestor_ids(node_id)
.map(|id| nodes.get_node(id))
.filter(|node| node.kind().is_function_like())
.map(|node| {
@ -372,7 +375,7 @@ fn get_declaration_identifier<'a>(
nodes: &'a AstNodes<'a>,
node_id: NodeId,
) -> Option<Cow<'a, str>> {
nodes.ancestors(node_id).map(|id| nodes.kind(id)).find_map(|kind| {
nodes.ancestor_ids(node_id).map(|id| nodes.kind(id)).find_map(|kind| {
match kind {
// const useHook = () => {};
AstKind::VariableDeclaration(decl) if decl.declarations.len() == 1 => {
@ -399,7 +402,7 @@ fn get_declaration_identifier<'a>(
fn is_export_default<'a>(nodes: &'a AstNodes<'a>, node_id: NodeId) -> bool {
nodes
.ancestors(node_id)
.ancestor_ids(node_id)
.map(|id| nodes.get_node(id))
.nth(1)
.is_some_and(|node| matches!(node.kind(), AstKind::ExportDefaultDeclaration(_)))
@ -408,7 +411,7 @@ fn is_export_default<'a>(nodes: &'a AstNodes<'a>, node_id: NodeId) -> bool {
/// # Panics
/// `node_id` should always point to a valid `Function`.
fn is_memo_or_forward_ref_callback(nodes: &AstNodes, node_id: NodeId) -> bool {
nodes.ancestors(node_id).map(|id| nodes.get_node(id)).any(|node| {
nodes.ancestor_ids(node_id).map(|id| nodes.get_node(id)).any(|node| {
if let AstKind::CallExpression(call) = node.kind() {
call.callee_name().is_some_and(|name| matches!(name, "forwardRef" | "memo"))
} else {

View file

@ -618,7 +618,7 @@ fn ancestor_has_return_type<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> bo
return false;
}
for ancestor in ctx.nodes().ancestors(node.id()).skip(1) {
for ancestor in ctx.nodes().ancestor_ids(node.id()).skip(1) {
match ctx.nodes().kind(ancestor) {
AstKind::ArrowFunctionExpression(func) => {
if func.return_type.is_some() {

View file

@ -195,7 +195,7 @@ pub fn get_parent_component<'a, 'b>(
node: &'b AstNode<'a>,
ctx: &'b LintContext<'a>,
) -> Option<&'b AstNode<'a>> {
for node_id in ctx.nodes().ancestors(node.id()) {
for node_id in ctx.nodes().ancestor_ids(node.id()) {
let node = ctx.nodes().get_node(node_id);
if is_es5_component(node) || is_es6_component(node) {
return Some(node);

View file

@ -171,7 +171,7 @@ pub fn check_binding_identifier<'a>(
// LexicalDeclaration : LetOrConst BindingList ;
// * It is a Syntax Error if the BoundNames of BindingList contains "let".
if !strict_mode && ident.name == "let" {
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::VariableDeclaration(decl) if decl.kind.is_lexical() => {
return ctx.error(invalid_let_declaration(decl.kind.as_str(), ident.span));
@ -197,7 +197,7 @@ pub fn check_identifier_reference<'a>(
// Static Semantics: AssignmentTargetType
// 1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is "eval" or "arguments", return invalid.
if ctx.strict_mode() && matches!(ident.name.as_str(), "arguments" | "eval") {
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::AssignmentTarget(_) | AstKind::SimpleAssignmentTarget(_) => {
return ctx.error(unexpected_identifier_assign(&ident.name, ident.span));
@ -214,7 +214,7 @@ pub fn check_identifier_reference<'a>(
// It is a Syntax Error if ContainsArguments of ClassStaticBlockStatementList is true.
if ident.name == "arguments" {
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::Function(_) => break,
AstKind::PropertyDefinition(_) => {
@ -567,7 +567,7 @@ pub fn check_break_statement<'a>(
ctx: &SemanticBuilder<'a>,
) {
// It is a Syntax Error if this BreakStatement is not nested, directly or indirectly (but not crossing function or static initialization block boundaries), within an IterationStatement or a SwitchStatement.
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::Program(_) => {
return stmt.label.as_ref().map_or_else(
@ -613,7 +613,7 @@ pub fn check_continue_statement<'a>(
ctx: &SemanticBuilder<'a>,
) {
// It is a Syntax Error if this ContinueStatement is not nested, directly or indirectly (but not crossing function or static initialization block boundaries), within an IterationStatement.
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::Program(_) => {
return stmt.label.as_ref().map_or_else(
@ -666,7 +666,7 @@ pub fn check_labeled_statement<'a>(
node: &AstNode<'a>,
ctx: &SemanticBuilder<'a>,
) {
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
// label cannot cross boundary on function or static block
AstKind::Function(_) | AstKind::StaticBlock(_) | AstKind::Program(_) => break,
@ -863,7 +863,7 @@ pub fn check_super<'a>(sup: &Super, node: &AstNode<'a>, ctx: &SemanticBuilder<'a
// skip(1) is the self `Super`
// skip(2) is the parent `CallExpression` or `NewExpression`
for node_id in ctx.nodes.ancestors(node.id()).skip(2) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(2) {
match ctx.nodes.kind(node_id) {
AstKind::MethodDefinition(def) => {
// ClassElement : MethodDefinition
@ -1094,7 +1094,7 @@ pub fn check_unary_expression<'a>(
}
fn is_in_formal_parameters<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) -> bool {
for node_id in ctx.nodes.ancestors(node.id()).skip(1) {
for node_id in ctx.nodes.ancestor_ids(node.id()).skip(1) {
match ctx.nodes.kind(node_id) {
AstKind::FormalParameter(_) => return true,
AstKind::Program(_) | AstKind::Function(_) | AstKind::ArrowFunctionExpression(_) => {

View file

@ -220,7 +220,7 @@ impl<'a> AstNodes<'a> {
/// pointed to by `node_id`. The last node will always be a [`Program`].
///
/// [`Program`]: oxc_ast::ast::Program
pub fn ancestors(&self, node_id: NodeId) -> impl Iterator<Item = NodeId> + '_ {
pub fn ancestor_ids(&self, node_id: NodeId) -> impl Iterator<Item = NodeId> + '_ {
let parent_ids = &self.parent_ids;
std::iter::successors(Some(node_id), |&node_id| parent_ids[node_id])
}