1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
* Copyright © 2025 Anand Beh
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//!
//! Java syntax elements.
//!
//! Note that no checking exists to make sure the elements are used correctly, i.e. the correct
//! combination of structs. Instead, the library user is expected to have basic knowledge of how
//! Java syntax is composed, and to combine the structs in this module likewise.
//!
/// Declares a new variable. Renders as `Type Expr;` with a new line at the end
/// The expression can be either the variable name or an [AssignExpr].
/// ```
/// # use async_codegen::common::Str;
/// # use async_codegen::context::EmptyContext;
/// # use async_codegen::java::{AssignExpr, DeclareVarStmt};
/// # use async_codegen::util::InMemoryOutput;
/// let declare_var = DeclareVarStmt(Str("String"), Str("varname"));
/// let string = InMemoryOutput::print_output(EmptyContext, &declare_var);
/// assert_eq!("String varname;\n", string);
///
/// let init_var = DeclareVarStmt(Str("String"), AssignExpr(Str("varname"), Str("\"hello world\"")));
/// let string = InMemoryOutput::print_output(EmptyContext, &init_var);
/// assert_eq!("String varname = \"hello world\";\n", string);
/// ```
;
/// An assertion. Renders as `assert Assert;` with a new line at the end
;
/// A standalone statement. Renders the expression and adds a semicolon and a new line.
;
/// An assignation. This statement includes the semicolon and a new line.
;
/// A return statement. Renders as `return Expr;` with a new line at the end.
;
/// An assignation, as an expression. Renders as `Variable = Expr`. In Java, an assignation
/// expression has the same type and value as the assigned value.
;
/// An if block. The condition and body must both be writable.
;
/// Represents "else" syntactically. Renders as `Before else After`.
///
/// This struct requires you to specify what comes before and after the else. For example:
/// ```
/// # use async_codegen::common::Str;
/// # use async_codegen::context::EmptyContext;
/// # use async_codegen::java::{AssertStmt, Block, Else, IfBlock};
/// # use async_codegen::util::InMemoryOutput;
///
/// let if_block = IfBlock(Str("true"), Str("System.out.println(\"Hello\");"));
/// let else_block = Block(AssertStmt(Str("false")));
/// let if_else = Else(if_block, else_block);
///
/// let string = InMemoryOutput::print_output(EmptyContext, &if_else);
/// assert_eq!("if true {\nSystem.out.println(\"Hello\");\n} else {\nassert false;\n\n}", string)
/// ```
;
/// An unlabeled block.
/// This can be used in many contexts, including merely organizing the code.
;
/// Accesses a field or calls a method by name. Renders as `Owner.Member`.
;
/// Declares a class.
/// Declares an interface
/// The "extends" keyword. Renders as `Expr extends Super`.
;
/// The "implements" keyword. Renders as `Expr implements Iface1, Iface2, Iface3, ...`.
/// The interfaces must be a sequence. If it is empty, then only `Expr` will be rendered.
;
/// A single modifier keyword
/// Calls a function with a name and arguments. Renders as `Name(Arg1, Arg2, Arg3, ...)`
/// Calls a constructor with a name and arguments. Renders as `new Name(Arg1, Arg2, Arg3, ...)`
/// A function parameter, constructor parameter, or record component parameter.
///
/// Renders as `Type Name`.
;
/// A type argument-parameterized declaration. Renders as `Name<TypeArgs>`.
///
/// The type args must be a sequence. If they are empty, only `Name` will be rendered.
;
/// Applies diamond inference to the construction of a type. Renders as `Name<>`.
;
/// An array of another type. Renders as `Component[]`
;
/// An enhanced for loop in the style `for (VarName : Iter) { Body }`.
/// All fields of this struct must be writable.
/// A traditional for loop in the style `for (Init; Predicate; Update) { Body }`.
/// All the fields of this struct must be writable. For example:
/// ```
/// use async_codegen::common::{SingularSeq, Str};
/// use async_codegen::context::EmptyContext;
/// use async_codegen::java::{AssignExpr, DeclareParam, FunctionCall, MemberAccess, Stmt, TraditionalFor};
/// use async_codegen::util::InMemoryOutput;
/// let for_loop = TraditionalFor {
/// init: AssignExpr(DeclareParam(Str("int"), Str("i")), Str("0")),
/// predicate: Str("i < 5"),
/// update: Str("i++"),
/// body: Stmt(MemberAccess(Str("System.out"), FunctionCall {
/// name: Str("println"),
/// args: SingularSeq(Str("i"))
/// }))
/// };
/// let string = InMemoryOutput::print_output(EmptyContext, &for_loop);
/// assert_eq!("for (int i = 0; i < 5; i++) {\nSystem.out.println(i);\n}\n", string);
/// ```
/// Defines a constructor
/// Defines a function