/ compiler / ast / src / common / identifier.rs
identifier.rs
  1  // Copyright (C) 2019-2025 ADnet Contributors
  2  // This file is part of the ADL library.
  3  
  4  // The ADL library is free software: you can redistribute it and/or modify
  5  // it under the terms of the GNU General Public License as published by
  6  // the Free Software Foundation, either version 3 of the License, or
  7  // (at your option) any later version.
  8  
  9  // The ADL library is distributed in the hope that it will be useful,
 10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 12  // GNU General Public License for more details.
 13  
 14  // You should have received a copy of the GNU General Public License
 15  // along with the ADL library. If not, see <https://www.gnu.org/licenses/>.
 16  
 17  use crate::{Expression, Node, NodeID, Path, simple_node_impl};
 18  
 19  use adl_span::{Span, Symbol};
 20  
 21  use snarkvm::{console::program::Identifier as IdentifierCore, prelude::Network};
 22  use std::{
 23      fmt,
 24      hash::{Hash, Hasher},
 25  };
 26  
 27  use serde::{Deserialize, Serialize};
 28  
 29  /// An identifier in a program.
 30  ///
 31  /// Attention - When adding or removing fields from this struct,
 32  /// please remember to update its Serialize and Deserialize implementation
 33  /// to reflect the new struct instantiation.
 34  #[derive(Clone, Copy, Default, Serialize, Deserialize)]
 35  pub struct Identifier {
 36      /// The symbol that the user wrote, e.g., `foo`.
 37      pub name: Symbol,
 38      /// A span locating where the identifier occurred in the source.
 39      pub span: Span,
 40      /// The ID of the node.
 41      pub id: NodeID,
 42  }
 43  
 44  simple_node_impl!(Identifier);
 45  
 46  impl Identifier {
 47      /// Constructs a new identifier with `name` and `id` and a default span.
 48      pub fn new(name: Symbol, id: NodeID) -> Self {
 49          Self { name, span: Span::default(), id }
 50      }
 51  
 52      /// Check if the Identifier name matches the other name.
 53      pub fn matches(&self, other: &Self) -> bool {
 54          self.name == other.name
 55      }
 56  }
 57  
 58  impl fmt::Display for Identifier {
 59      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 60          self.name.fmt(f)
 61      }
 62  }
 63  impl fmt::Debug for Identifier {
 64      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 65          self.name.fmt(f)
 66      }
 67  }
 68  
 69  impl PartialEq for Identifier {
 70      fn eq(&self, other: &Self) -> bool {
 71          self.name == other.name && self.span == other.span
 72      }
 73  }
 74  
 75  impl Eq for Identifier {}
 76  
 77  impl Hash for Identifier {
 78      fn hash<H: Hasher>(&self, state: &mut H) {
 79          self.name.hash(state);
 80          self.span.hash(state);
 81      }
 82  }
 83  
 84  impl<N: Network> From<&IdentifierCore<N>> for Identifier {
 85      fn from(id: &IdentifierCore<N>) -> Self {
 86          Self { name: Symbol::intern(&id.to_string()), span: Default::default(), id: Default::default() }
 87      }
 88  }
 89  
 90  // Converts an `Identifier` to a `Path` expression
 91  // Note that this sets the `absolute_path` field in `Path` to `None`.
 92  // It's up to the caller of this method to figure out what to do `absolute_path`.
 93  impl From<Identifier> for Expression {
 94      fn from(value: Identifier) -> Self {
 95          Expression::Path(crate::Path::from(value))
 96      }
 97  }
 98  
 99  // Converts an `Identifier` to a `Path`
100  // Note that this sets the `absolute_path` field in `Path` to `None` and `is_absolute` to `false`.
101  // It's up to the caller of this method to figure out what to do with `absolute_path`.
102  impl From<Identifier> for Path {
103      fn from(value: Identifier) -> Self {
104          Path::new(vec![], value, false, None, value.span, value.id)
105      }
106  }