use serde::Deserialize;
use serde::Serialize;
use mago_interner::StringIdentifier;
use mago_interner::ThreadedInterner;
use mago_names::ResolvedNames;
use mago_span::HasSpan;
use mago_span::Span;
use mago_syntax::ast::Program;
use mago_syntax::walker::Walker;
use crate::internal::context::Context;
use crate::internal::walker::ReferenceFindingWalker;
use crate::query::Query;
pub mod query;
mod internal;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub enum ReferenceKind {
Import,
Usage,
Definition,
Implementation,
Extension,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct Reference {
pub value: StringIdentifier,
pub kind: ReferenceKind,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct ReferenceFinder<'a> {
interner: &'a ThreadedInterner,
}
impl<'a> ReferenceFinder<'a> {
pub fn new(interner: &'a ThreadedInterner) -> Self {
Self { interner }
}
pub fn find(&self, program: &Program, resolved_names: &ResolvedNames, query: Query) -> Vec<Reference> {
let mut context = Context::new(self.interner, &query, resolved_names);
ReferenceFindingWalker.walk_program(program, &mut context);
context.take_references()
}
}
impl HasSpan for Reference {
fn span(&self) -> Span {
self.span
}
}