leo_passes/path_resolution/
ast.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 super::PathResolutionVisitor;
18use leo_ast::{
19    AstReconstructor,
20    CallExpression,
21    CompositeType,
22    ErrExpression,
23    Expression,
24    Path,
25    StructExpression,
26    StructVariableInitializer,
27    Type,
28};
29
30impl AstReconstructor for PathResolutionVisitor<'_> {
31    type AdditionalInput = ();
32    type AdditionalOutput = ();
33
34    fn reconstruct_composite_type(&mut self, mut input: CompositeType) -> (Type, Self::AdditionalOutput) {
35        if input.path.try_absolute_path().is_none() {
36            input.path = input.path.with_module_prefix(&self.module);
37        }
38        (
39            Type::Composite(CompositeType {
40                path: input.path,
41                const_arguments: input
42                    .const_arguments
43                    .into_iter()
44                    .map(|arg| self.reconstruct_expression(arg, &()).0)
45                    .collect(),
46                ..input
47            }),
48            Default::default(),
49        )
50    }
51
52    fn reconstruct_err(&mut self, input: ErrExpression, _additional: &()) -> (Expression, Self::AdditionalOutput) {
53        (input.into(), ())
54    }
55
56    fn reconstruct_call(
57        &mut self,
58        mut input: CallExpression,
59        _additional: &(),
60    ) -> (Expression, Self::AdditionalOutput) {
61        if input.function.try_absolute_path().is_none() {
62            input.function = input.function.with_module_prefix(&self.module);
63        }
64        (
65            CallExpression {
66                function: input.function,
67                const_arguments: input
68                    .const_arguments
69                    .into_iter()
70                    .map(|arg| self.reconstruct_expression(arg, &()).0)
71                    .collect(),
72                arguments: input.arguments.into_iter().map(|arg| self.reconstruct_expression(arg, &()).0).collect(),
73                ..input
74            }
75            .into(),
76            Default::default(),
77        )
78    }
79
80    fn reconstruct_struct_init(
81        &mut self,
82        mut input: StructExpression,
83        _additional: &(),
84    ) -> (Expression, Self::AdditionalOutput) {
85        if input.path.try_absolute_path().is_none() {
86            input.path = input.path.with_module_prefix(&self.module)
87        }
88        (
89            StructExpression {
90                path: input.path,
91                const_arguments: input
92                    .const_arguments
93                    .into_iter()
94                    .map(|arg| self.reconstruct_expression(arg, &()).0)
95                    .collect(),
96                members: input
97                    .members
98                    .into_iter()
99                    .map(|member| StructVariableInitializer {
100                        identifier: member.identifier,
101                        expression: member.expression.map(|expr| self.reconstruct_expression(expr, &()).0),
102                        span: member.span,
103                        id: member.id,
104                    })
105                    .collect(),
106                ..input
107            }
108            .into(),
109            Default::default(),
110        )
111    }
112
113    fn reconstruct_path(&mut self, mut input: Path, _additional: &()) -> (Expression, Self::AdditionalOutput) {
114        // Because some paths may be paths to global consts, we have to prefix all paths at this
115        // stage because we don't have semantic information just yet.
116        if input.try_absolute_path().is_none() {
117            input = input.with_module_prefix(&self.module);
118        }
119        (input.into(), Default::default())
120    }
121}