leo_ast/common/
identifier.rs

1// Copyright (C) 2019-2025 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo 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 Leo 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 Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17use crate::{Expression, Node, NodeID, Path, simple_node_impl};
18
19use leo_span::{Span, Symbol};
20
21use snarkvm::{console::program::Identifier as IdentifierCore, prelude::Network};
22use std::{
23    fmt,
24    hash::{Hash, Hasher},
25};
26
27use 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)]
35pub 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
44simple_node_impl!(Identifier);
45
46impl 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
58impl fmt::Display for Identifier {
59    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60        self.name.fmt(f)
61    }
62}
63impl fmt::Debug for Identifier {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        self.name.fmt(f)
66    }
67}
68
69impl PartialEq for Identifier {
70    fn eq(&self, other: &Self) -> bool {
71        self.name == other.name && self.span == other.span
72    }
73}
74
75impl Eq for Identifier {}
76
77impl 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
84impl<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`.
93impl 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`.
101// It's up to the caller of this method to figure out what to do `absolute_path`.
102impl From<Identifier> for Path {
103    fn from(value: Identifier) -> Self {
104        Path::new(vec![], value, None, value.span, value.id)
105    }
106}