1mod annotation;
18pub use annotation::*;
19
20mod core_function;
21pub use core_function::*;
22
23mod variant;
24pub use variant::*;
25
26mod input;
27pub use input::*;
28
29mod output;
30pub use output::*;
31
32mod mode;
33pub use mode::*;
34
35use crate::{Block, FunctionStub, Identifier, Indent, Node, NodeID, TupleType, Type};
36use leo_span::{Span, Symbol};
37
38use itertools::Itertools as _;
39use serde::{Deserialize, Serialize};
40use std::fmt;
41
42#[derive(Clone, Default, Serialize, Deserialize)]
44pub struct Function {
45 pub annotations: Vec<Annotation>,
47 pub variant: Variant,
49 pub identifier: Identifier,
51 pub input: Vec<Input>,
53 pub output: Vec<Output>,
55 pub output_type: Type,
57 pub block: Block,
59 pub span: Span,
61 pub id: NodeID,
63}
64
65impl PartialEq for Function {
66 fn eq(&self, other: &Self) -> bool {
67 self.identifier == other.identifier
68 }
69}
70
71impl Eq for Function {}
72
73impl Function {
74 #[allow(clippy::too_many_arguments)]
76 pub fn new(
77 annotations: Vec<Annotation>,
78 variant: Variant,
79 identifier: Identifier,
80 input: Vec<Input>,
81 output: Vec<Output>,
82 block: Block,
83 span: Span,
84 id: NodeID,
85 ) -> Self {
86 let output_type = match output.len() {
87 0 => Type::Unit,
88 1 => output[0].type_.clone(),
89 _ => Type::Tuple(TupleType::new(output.iter().map(|o| o.type_.clone()).collect())),
90 };
91
92 Function { annotations, variant, identifier, input, output, output_type, block, span, id }
93 }
94
95 pub fn name(&self) -> Symbol {
97 self.identifier.name
98 }
99}
100
101impl From<FunctionStub> for Function {
102 fn from(function: FunctionStub) -> Self {
103 Self {
104 annotations: function.annotations,
105 variant: function.variant,
106 identifier: function.identifier,
107 input: function.input,
108 output: function.output,
109 output_type: function.output_type,
110 block: Block::default(),
111 span: function.span,
112 id: function.id,
113 }
114 }
115}
116
117impl fmt::Debug for Function {
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 write!(f, "{}", self)
120 }
121}
122
123impl fmt::Display for Function {
124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
125 match self.variant {
126 Variant::Inline => write!(f, "inline ")?,
127 Variant::Function => write!(f, "function ")?,
128 Variant::AsyncFunction => write!(f, "async function ")?,
129 Variant::Transition => write!(f, "transition ")?,
130 Variant::AsyncTransition => write!(f, "async transition ")?,
131 Variant::Script => write!(f, "script ")?,
132 }
133 write!(f, "{}({})", self.identifier, self.input.iter().format(", "))?;
134
135 match self.output.len() {
136 0 => {}
137 1 => {
138 if !matches!(self.output[0].type_, Type::Unit) {
139 write!(f, " -> {}", self.output[0])?;
140 }
141 }
142 _ => {
143 write!(f, " -> ({})", self.output.iter().format(", "))?;
144 }
145 }
146
147 writeln!(f, " {{")?;
148 for stmt in self.block.statements.iter() {
149 writeln!(f, "{}{}", Indent(stmt), stmt.semicolon())?;
150 }
151 write!(f, "}}")
152 }
153}
154
155crate::simple_node_impl!(Function);