Track all read references in semantic model (#4610)

This commit is contained in:
Charlie Marsh 2023-05-24 10:14:27 -04:00 committed by GitHub
parent 31bddef98f
commit 8961d8eb6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 382 additions and 209 deletions

View file

@ -0,0 +1,70 @@
use ruff_text_size::TextRange;
use ruff_index::{newtype_index, IndexVec};
use crate::scope::ScopeId;
#[derive(Debug, Clone)]
pub struct Reference {
/// The scope in which the reference is defined.
scope_id: ScopeId,
/// The range of the reference in the source code.
range: TextRange,
/// The context in which the reference occurs.
context: ReferenceContext,
}
impl Reference {
pub const fn scope_id(&self) -> ScopeId {
self.scope_id
}
pub const fn range(&self) -> TextRange {
self.range
}
pub const fn context(&self) -> &ReferenceContext {
&self.context
}
}
#[derive(Debug, Clone, is_macro::Is)]
pub enum ReferenceContext {
/// The reference occurs in a runtime context.
Runtime,
/// The reference occurs in a typing-only context.
Typing,
/// The reference occurs in a synthetic context, used for `__future__` imports, explicit
/// re-exports, and other bindings that should be considered used even if they're never
/// "referenced".
Synthetic,
}
/// Id uniquely identifying a read reference in a program.
#[newtype_index]
pub struct ReferenceId;
/// The references of a program indexed by [`ReferenceId`].
#[derive(Debug, Default)]
pub struct References(IndexVec<ReferenceId, Reference>);
impl References {
/// Pushes a new read reference and returns its unique id.
pub fn push(
&mut self,
scope_id: ScopeId,
range: TextRange,
context: ReferenceContext,
) -> ReferenceId {
self.0.push(Reference {
scope_id,
range,
context,
})
}
/// Returns the [`Reference`] with the given id.
pub fn resolve(&self, id: ReferenceId) -> &Reference {
&self.0[id]
}
}