leo_ast/common/identifier.rs
1// Copyright (C) 2019-2026 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::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 implementation
33/// to reflect the new struct instantiation.
34#[derive(Clone, Copy, Default, Serialize)]
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 an unresolved `Path` expression
91// It's up to the caller of this method to figure out how to resolve the resulting `Path`.
92impl From<Identifier> for Expression {
93 fn from(value: Identifier) -> Self {
94 Expression::Path(crate::Path::from(value))
95 }
96}
97
98// Converts an `Identifier` to a `Path`.
99// It's up to the caller of this method to figure out how to resolve the resulting `Path`.
100impl From<Identifier> for Path {
101 fn from(value: Identifier) -> Self {
102 Path::new(None, vec![], value, value.span, value.id)
103 }
104}