deimos-lang/src/ast/node/names.rs
2025-05-26 08:30:15 -05:00

147 lines
3.5 KiB
Rust

use std::borrow::Cow;
use crate::name_analysis::symbol::Symbol;
use std::range::Range;
use crate::ast::node::named::Named;
#[derive(Debug)]
pub struct Identifier {
name: String,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl Identifier {
pub fn new(name: &str, file_id: usize, range: Range<usize>) -> Self {
Self {
name: name.to_string(),
file_id,
range,
scope_id: None,
saved_symbol: None,
}
}
}
impl Named for Identifier {
fn name(&self) -> Cow<'_, str> {
Cow::Borrowed(&self.name)
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
self.saved_symbol = Some(saved_symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}
#[derive(Debug)]
pub struct FullyQualifiedName {
identifiers: Vec<Box<Identifier>>,
file_id: usize,
range: Range<usize>,
scope_id: Option<usize>,
saved_symbol: Option<Symbol>,
}
impl FullyQualifiedName {
pub fn new(identifiers: Vec<Box<Identifier>>, file_id: usize, range: Range<usize>) -> Self {
Self {
identifiers,
range,
file_id,
scope_id: None,
saved_symbol: None,
}
}
pub fn identifiers(&self) -> Vec<&Identifier> {
self.identifiers.iter().map(Box::as_ref).collect()
}
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
self.identifiers.iter_mut().map(Box::as_mut).collect()
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn last(&self) -> &Identifier {
&self.identifiers[self.identifiers.len() - 1]
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn last_mut(&mut self) -> &mut Identifier {
let last_index = self.identifiers.len() - 1;
&mut self.identifiers[last_index]
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn len(&self) -> usize {
self.identifiers.len()
}
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
pub fn is_single_identifier(&self) -> bool {
self.identifiers.len() == 1
}
}
impl Named for FullyQualifiedName {
fn name(&self) -> Cow<'_, str> {
if self.identifiers.len() == 1 {
self.identifiers[0].name()
} else {
let mut acc = String::new();
for (i, identifier) in self.identifiers.iter().enumerate() {
acc += &identifier.name();
if i < self.identifiers.len() - 1 {
acc += "::";
}
}
Cow::Owned(acc)
}
}
fn file_id(&self) -> usize {
self.file_id
}
fn range(&self) -> Range<usize> {
self.range
}
fn set_scope_id(&mut self, id: usize) {
self.scope_id = Some(id);
}
fn scope_id(&self) -> Option<usize> {
self.scope_id
}
fn set_saved_symbol(&mut self, symbol: Symbol) {
self.saved_symbol = Some(symbol);
}
fn saved_symbol(&self) -> Option<Symbol> {
self.saved_symbol.clone()
}
}