oxc/crates/oxc_semantic/tests/conformance/test_identifier_reference.rs
overlookmotel 843bce4d92 refactor(ast)!: IdentifierReference::reference_id return ReferenceId (#7126)
Alter `IdentifierReference::reference_id` to return `ReferenceId`, instead of `Option<ReferenceId>`.

This method is only useful on a post-semantic AST, where it will never return `None`. Returning `ReferenceId` discourages the anti-pattern of treating the result as if it could be either `Some` or `None`, and shortens code.
2024-11-05 02:25:27 +00:00

77 lines
2.6 KiB
Rust

use oxc_ast::{ast::IdentifierReference, AstKind};
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::{NodeId, Reference};
use oxc_span::GetSpan;
use oxc_syntax::reference::ReferenceId;
use super::{ConformanceTest, TestResult};
use crate::Semantic;
/// Tests reflexivity between [`IdentifierReference`] AST nodes and their corresponding
/// [`Reference`]s.
///
/// Performs the following checks:
/// 1. All [`IdentifierReference`]s have been populated with a [`ReferenceId`], even if the
/// referenced symbol could not be resolved.
///
/// 2. When an [`IdentifierReference`] is used to find a [`Reference`] in the symbol table, the AST
/// node id associated with that [`Reference`] should be the [`IdentifierReference`]'s AST node
/// id.
#[derive(Debug, Clone, Default)]
pub struct IdentifierReferenceTest;
/// [`IdentifierReference::reference_id`] returned [`None`].
fn missing_reference_id(reference: &IdentifierReference) -> TestResult {
OxcDiagnostic::error("After semantic analysis, all IdentifierReferences should have a reference_id, even if a symbol could not be resolved.")
.with_label(reference.span().label("This reference's reference_id is None"))
.into()
}
/// The [`NodeId`] of the [`IdentifierReference`] did not match the [`NodeId`] of the
/// [`Reference`].
fn node_id_mismatch(
identifier_reference_id: NodeId,
identifier_reference: &IdentifierReference,
reference_id: ReferenceId,
reference: &Reference,
) -> TestResult {
OxcDiagnostic::error(
"NodeId mismatch between an IdentifierReference and its corresponding Reference",
)
.with_label(
identifier_reference
.span
.label(format!("This IdentifierReference's NodeId is {identifier_reference_id:?}")),
)
.with_help(format!(
"The Reference with id {reference_id:?} has a NodeId of {:?}",
reference.node_id()
))
.into()
}
impl ConformanceTest for IdentifierReferenceTest {
fn name(&self) -> &'static str {
"identifier-reference"
}
fn run_on_node<'a>(
&self,
node: &oxc_semantic::AstNode<'a>,
semantic: &Semantic<'a>,
) -> TestResult {
let AstKind::IdentifierReference(id) = node.kind() else {
return TestResult::Pass;
};
let Some(reference_id) = id.reference_id.get() else {
return missing_reference_id(id);
};
let reference = semantic.symbols().get_reference(reference_id);
if reference.node_id() != node.id() {
return node_id_mismatch(node.id(), id, reference_id, reference);
}
TestResult::Pass
}
}