Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-ast-fragment.h"
20 : :
21 : : namespace Rust {
22 : : namespace AST {
23 : :
24 : 23098358 : Fragment::Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes,
25 : 23098358 : std::vector<std::unique_ptr<AST::Token>> tokens)
26 : 23098358 : : kind (kind), nodes (std::move (nodes)), tokens (std::move (tokens))
27 : 23098358 : {}
28 : :
29 : 23087953 : Fragment::Fragment (Fragment const &other) : kind (other.get_kind ())
30 : : {
31 : 23087953 : *this = other;
32 : 23087953 : }
33 : :
34 : : Fragment &
35 : 46231047 : Fragment::operator= (Fragment const &other)
36 : : {
37 : 46231047 : kind = other.get_kind ();
38 : :
39 : 46231047 : nodes.clear ();
40 : 46231047 : nodes.reserve (other.nodes.size ());
41 : 46487073 : for (auto &n : other.nodes)
42 : 256026 : nodes.push_back (n);
43 : :
44 : 46231047 : tokens.clear ();
45 : 46231047 : tokens.reserve (other.tokens.size ());
46 : 54888241 : for (auto &t : other.tokens)
47 : 8657194 : tokens.emplace_back (t->clone_token ());
48 : :
49 : 46231047 : return *this;
50 : : }
51 : :
52 : : Fragment
53 : 23091862 : Fragment::create_error ()
54 : : {
55 : 23091862 : return Fragment (FragmentKind::Error, {}, {});
56 : : }
57 : :
58 : : Fragment
59 : 6496 : Fragment::create_empty ()
60 : : {
61 : 6496 : return Fragment (FragmentKind::Complete, {}, {});
62 : : }
63 : :
64 : 55418 : Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
65 : 55418 : std::vector<std::unique_ptr<AST::Token>> tokens)
66 : 55418 : : kind (FragmentKind::Complete), nodes (std::move (nodes)),
67 : 55418 : tokens (std::move (tokens))
68 : 55418 : {}
69 : :
70 : 277 : Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
71 : 277 : std::unique_ptr<AST::Token> token)
72 : 277 : : kind (FragmentKind::Complete), nodes (std::move (nodes))
73 : : {
74 : 277 : tokens.emplace_back (std::move (token));
75 : 277 : }
76 : :
77 : : std::vector<SingleASTNode> &
78 : 5501 : Fragment::get_nodes ()
79 : : {
80 : 5501 : return nodes;
81 : : }
82 : :
83 : : std::vector<std::unique_ptr<AST::Token>> &
84 : 48 : Fragment::get_tokens ()
85 : : {
86 : 48 : return tokens;
87 : : }
88 : :
89 : : FragmentKind
90 : 92400353 : Fragment::get_kind () const
91 : : {
92 : 92400353 : return kind;
93 : : }
94 : :
95 : : bool
96 : 23081353 : Fragment::is_error () const
97 : : {
98 : 23081353 : return get_kind () == FragmentKind::Error;
99 : : }
100 : :
101 : : bool
102 : 23019658 : Fragment::should_expand () const
103 : : {
104 : 23019658 : return !is_error ();
105 : : }
106 : :
107 : : bool
108 : 49661 : Fragment::is_expression_fragment () const
109 : : {
110 : 49661 : return is_single_fragment_of_kind (SingleASTNode::Kind::Expr);
111 : : }
112 : :
113 : : bool
114 : 497 : Fragment::is_type_fragment () const
115 : : {
116 : 497 : return is_single_fragment_of_kind (SingleASTNode::Kind::Type);
117 : : }
118 : :
119 : : bool
120 : 1 : Fragment::is_pattern_fragment () const
121 : : {
122 : 1 : return is_single_fragment_of_kind (SingleASTNode::Kind::Pattern);
123 : : }
124 : :
125 : : std::unique_ptr<Expr>
126 : 49659 : Fragment::take_expression_fragment ()
127 : : {
128 : 49659 : assert_single_fragment (SingleASTNode::Kind::Expr);
129 : 49659 : return nodes[0].take_expr ();
130 : : }
131 : :
132 : : std::unique_ptr<Type>
133 : 497 : Fragment::take_type_fragment ()
134 : : {
135 : 497 : assert_single_fragment (SingleASTNode::Kind::Type);
136 : 497 : return nodes[0].take_type ();
137 : : }
138 : :
139 : : std::unique_ptr<Pattern>
140 : 1 : Fragment::take_pattern_fragment ()
141 : : {
142 : 1 : assert_single_fragment (SingleASTNode::Kind::Pattern);
143 : 1 : return nodes[0].take_pattern ();
144 : : }
145 : :
146 : : void
147 : 0 : Fragment::accept_vis (ASTVisitor &vis)
148 : : {
149 : 0 : for (auto &node : nodes)
150 : 0 : node.accept_vis (vis);
151 : 0 : }
152 : :
153 : : bool
154 : 100316 : Fragment::is_single_fragment () const
155 : : {
156 : 100316 : return nodes.size () == 1;
157 : : }
158 : :
159 : : bool
160 : 50159 : Fragment::is_single_fragment_of_kind (SingleASTNode::Kind expected) const
161 : : {
162 : 50159 : return is_single_fragment () && nodes[0].get_kind () == expected;
163 : : }
164 : :
165 : : void
166 : 50157 : Fragment::assert_single_fragment (SingleASTNode::Kind expected) const
167 : : {
168 : 50157 : static const std::map<SingleASTNode::Kind, const char *> str_map = {
169 : : {SingleASTNode::Kind::Assoc, "associated item"},
170 : : {SingleASTNode::Kind::Item, "item"},
171 : : {SingleASTNode::Kind::Type, "type"},
172 : : {SingleASTNode::Kind::Expr, "expr"},
173 : : {SingleASTNode::Kind::Stmt, "stmt"},
174 : : {SingleASTNode::Kind::Extern, "extern"},
175 : : {SingleASTNode::Kind::Pattern, "pattern"},
176 : 50157 : };
177 : :
178 : 50157 : auto actual = nodes[0].get_kind ();
179 : 50157 : auto fail = false;
180 : :
181 : 50157 : if (!is_single_fragment ())
182 : : {
183 : 0 : rust_error_at (UNDEF_LOCATION, "fragment is not single");
184 : 0 : fail = true;
185 : : }
186 : :
187 : 50157 : if (actual != expected)
188 : : {
189 : 0 : rust_error_at (
190 : : UNDEF_LOCATION,
191 : : "invalid fragment operation: expected %qs node, got %qs node",
192 : 0 : str_map.find (expected)->second,
193 : 0 : str_map.find (nodes[0].get_kind ())->second);
194 : 0 : fail = true;
195 : : }
196 : :
197 : 50157 : rust_assert (!fail);
198 : 50157 : }
199 : :
200 : : } // namespace AST
201 : : } // namespace Rust
|