Line data Source code
1 : // Copyright (C) 2020-2026 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 25373285 : Fragment::Fragment (FragmentKind kind, std::vector<SingleASTNode> nodes,
25 : std::vector<std::unique_ptr<AST::Token>> tokens)
26 25373285 : : kind (kind), nodes (std::move (nodes)), tokens (std::move (tokens))
27 25373285 : {}
28 :
29 25367899 : Fragment::Fragment (Fragment const &other) : kind (other.get_kind ())
30 : {
31 25367899 : *this = other;
32 25367899 : }
33 :
34 : Fragment &
35 50791579 : Fragment::operator= (Fragment const &other)
36 : {
37 50791579 : kind = other.get_kind ();
38 :
39 50791579 : nodes.clear ();
40 50791579 : nodes.reserve (other.nodes.size ());
41 51079301 : for (auto &n : other.nodes)
42 287722 : nodes.push_back (n);
43 :
44 50791579 : tokens.clear ();
45 50791579 : tokens.reserve (other.tokens.size ());
46 59777797 : for (auto &t : other.tokens)
47 8986218 : tokens.emplace_back (t->clone_token ());
48 :
49 50791579 : return *this;
50 : }
51 :
52 : Fragment
53 25367070 : Fragment::create_error ()
54 : {
55 25367070 : return Fragment (FragmentKind::Error, {}, {});
56 : }
57 :
58 : Fragment
59 6215 : Fragment::create_empty ()
60 : {
61 6215 : return Fragment (FragmentKind::Complete, {}, {});
62 : }
63 :
64 57261 : Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
65 : std::vector<std::unique_ptr<AST::Token>> tokens)
66 57261 : : kind (FragmentKind::Complete), nodes (std::move (nodes)),
67 57261 : tokens (std::move (tokens))
68 57261 : {}
69 :
70 4405 : Fragment::Fragment (std::vector<AST::SingleASTNode> nodes,
71 : std::unique_ptr<AST::Token> token)
72 4405 : : kind (FragmentKind::Complete), nodes (std::move (nodes))
73 : {
74 4405 : tokens.emplace_back (std::move (token));
75 4405 : }
76 :
77 : std::vector<SingleASTNode> &
78 5963 : Fragment::get_nodes ()
79 : {
80 5963 : return nodes;
81 : }
82 :
83 : std::vector<std::unique_ptr<AST::Token>> &
84 2864 : Fragment::get_tokens ()
85 : {
86 2864 : return tokens;
87 : }
88 :
89 : FragmentKind
90 101521434 : Fragment::get_kind () const
91 : {
92 101521434 : return kind;
93 : }
94 :
95 : bool
96 25361956 : Fragment::is_error () const
97 : {
98 25361956 : return get_kind () == FragmentKind::Error;
99 : }
100 :
101 : bool
102 25296846 : Fragment::should_expand () const
103 : {
104 25296846 : return !is_error ();
105 : }
106 :
107 : bool
108 52349 : Fragment::is_expression_fragment () const
109 : {
110 52349 : 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 52347 : Fragment::take_expression_fragment ()
127 : {
128 52347 : assert_single_fragment (SingleASTNode::Kind::Expr);
129 52347 : 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 105692 : Fragment::is_single_fragment () const
155 : {
156 105692 : return nodes.size () == 1;
157 : }
158 :
159 : bool
160 52847 : Fragment::is_single_fragment_of_kind (SingleASTNode::Kind expected) const
161 : {
162 52847 : return is_single_fragment () && nodes[0].get_kind () == expected;
163 : }
164 :
165 : void
166 52845 : Fragment::assert_single_fragment (SingleASTNode::Kind expected) const
167 : {
168 52845 : 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 52845 : };
177 :
178 52845 : auto actual = nodes[0].get_kind ();
179 52845 : auto fail = false;
180 :
181 52845 : if (!is_single_fragment ())
182 : {
183 0 : rust_error_at (UNDEF_LOCATION, "fragment is not single");
184 0 : fail = true;
185 : }
186 :
187 52845 : 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 52845 : rust_assert (!fail);
198 52845 : }
199 :
200 : } // namespace AST
201 : } // namespace Rust
|