mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
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.
77 lines
2.6 KiB
Rust
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
|
|
}
|
|
}
|