1use crate::program::{JvmAccessFlags, JvmExceptionHandler, JvmInstruction, JvmMethod, JvmProgram, JvmVersion};
2
3pub struct JvmProgramBuilder {
5 program: JvmProgram,
6}
7
8impl JvmProgramBuilder {
9 pub fn new(name: impl Into<String>) -> Self {
10 Self { program: JvmProgram::new(name.into()) }
11 }
12
13 pub fn with_version(mut self, major: u16, minor: u16) -> Self {
14 self.program.version = JvmVersion { major, minor };
15 self
16 }
17
18 pub fn with_access_flags(mut self, flags: JvmAccessFlags) -> Self {
19 self.program.access_flags = flags;
20 self
21 }
22
23 pub fn with_public(mut self) -> Self {
24 self.program.access_flags.is_public = true;
25 self
26 }
27
28 pub fn with_super_class(mut self, super_class: impl Into<String>) -> Self {
29 self.program.super_class = Some(super_class.into());
30 self
31 }
32
33 pub fn add_interface(mut self, interface: impl Into<String>) -> Self {
34 self.program.interfaces.push(interface.into());
35 self
36 }
37
38 pub fn with_source_file(mut self, source_file: impl Into<String>) -> Self {
39 self.program.source_file = Some(source_file.into());
40 self
41 }
42
43 pub fn add_method<F>(mut self, name: impl Into<String>, descriptor: impl Into<String>, f: F) -> Self
44 where
45 F: FnOnce(JvmMethodBuilder) -> JvmMethodBuilder,
46 {
47 let builder = JvmMethodBuilder::new(name.into(), descriptor.into());
48 let method = f(builder).build();
49 self.program.add_method(method);
50 self
51 }
52
53 pub fn build(self) -> JvmProgram {
54 self.program
55 }
56}
57
58pub struct JvmMethodBuilder {
60 method: JvmMethod,
61}
62
63impl JvmMethodBuilder {
64 pub fn new(name: String, descriptor: String) -> Self {
65 Self { method: JvmMethod::new(name, descriptor) }
66 }
67
68 pub fn with_public(mut self) -> Self {
69 self.method.access_flags.is_public = true;
70 self
71 }
72
73 pub fn with_private(mut self) -> Self {
74 self.method.access_flags.is_private = true;
75 self
76 }
77
78 pub fn with_protected(mut self) -> Self {
79 self.method.access_flags.is_protected = true;
80 self
81 }
82
83 pub fn with_static(mut self) -> Self {
84 self.method.access_flags.is_static = true;
85 self
86 }
87
88 pub fn with_final(mut self) -> Self {
89 self.method.access_flags.is_final = true;
90 self
91 }
92
93 pub fn with_synchronized(mut self) -> Self {
94 self.method.access_flags.is_synchronized = true;
95 self
96 }
97
98 pub fn with_max_stack(mut self, max_stack: u16) -> Self {
99 self.method.max_stack = max_stack;
100 self
101 }
102
103 pub fn with_max_locals(mut self, max_locals: u16) -> Self {
104 self.method.max_locals = max_locals;
105 self
106 }
107
108 pub fn add_instruction(mut self, instruction: JvmInstruction) -> Self {
109 self.method.add_instruction(instruction);
110 self
111 }
112
113 pub fn add_exception_handler(mut self, handler: JvmExceptionHandler) -> Self {
114 self.method.add_exception_handler(handler);
115 self
116 }
117
118 pub fn add_exception(mut self, exception: impl Into<String>) -> Self {
119 self.method.add_exception(exception.into());
120 self
121 }
122
123 pub fn nop(self) -> Self {
125 self.add_instruction(JvmInstruction::Nop)
126 }
127 pub fn aconst_null(self) -> Self {
128 self.add_instruction(JvmInstruction::AconstNull)
129 }
130 pub fn iconst_m1(self) -> Self {
131 self.add_instruction(JvmInstruction::IconstM1)
132 }
133 pub fn iconst_0(self) -> Self {
134 self.add_instruction(JvmInstruction::Iconst0)
135 }
136 pub fn iconst_1(self) -> Self {
137 self.add_instruction(JvmInstruction::Iconst1)
138 }
139 pub fn iconst_2(self) -> Self {
140 self.add_instruction(JvmInstruction::Iconst2)
141 }
142 pub fn iconst_3(self) -> Self {
143 self.add_instruction(JvmInstruction::Iconst3)
144 }
145 pub fn iconst_4(self) -> Self {
146 self.add_instruction(JvmInstruction::Iconst4)
147 }
148 pub fn iconst_5(self) -> Self {
149 self.add_instruction(JvmInstruction::Iconst5)
150 }
151 pub fn lconst_0(self) -> Self {
152 self.add_instruction(JvmInstruction::Lconst0)
153 }
154 pub fn lconst_1(self) -> Self {
155 self.add_instruction(JvmInstruction::Lconst1)
156 }
157 pub fn fconst_0(self) -> Self {
158 self.add_instruction(JvmInstruction::Fconst0)
159 }
160 pub fn fconst_1(self) -> Self {
161 self.add_instruction(JvmInstruction::Fconst1)
162 }
163 pub fn fconst_2(self) -> Self {
164 self.add_instruction(JvmInstruction::Fconst2)
165 }
166 pub fn dconst_0(self) -> Self {
167 self.add_instruction(JvmInstruction::Dconst0)
168 }
169 pub fn dconst_1(self) -> Self {
170 self.add_instruction(JvmInstruction::Dconst1)
171 }
172
173 pub fn bipush(self, value: i8) -> Self {
174 self.add_instruction(JvmInstruction::Bipush { value })
175 }
176 pub fn sipush(self, value: i16) -> Self {
177 self.add_instruction(JvmInstruction::Sipush { value })
178 }
179 pub fn ldc(self, symbol: impl Into<String>) -> Self {
180 self.add_instruction(JvmInstruction::Ldc { symbol: symbol.into() })
181 }
182
183 pub fn iload(self, index: u16) -> Self {
184 self.add_instruction(JvmInstruction::Iload { index })
185 }
186 pub fn lload(self, index: u16) -> Self {
187 self.add_instruction(JvmInstruction::Lload { index })
188 }
189 pub fn fload(self, index: u16) -> Self {
190 self.add_instruction(JvmInstruction::Fload { index })
191 }
192 pub fn dload(self, index: u16) -> Self {
193 self.add_instruction(JvmInstruction::Dload { index })
194 }
195 pub fn aload(self, index: u16) -> Self {
196 self.add_instruction(JvmInstruction::Aload { index })
197 }
198 pub fn iload_0(self) -> Self {
199 self.add_instruction(JvmInstruction::Iload0)
200 }
201 pub fn iload_1(self) -> Self {
202 self.add_instruction(JvmInstruction::Iload1)
203 }
204 pub fn iload_2(self) -> Self {
205 self.add_instruction(JvmInstruction::Iload2)
206 }
207 pub fn iload_3(self) -> Self {
208 self.add_instruction(JvmInstruction::Iload3)
209 }
210 pub fn lload_0(self) -> Self {
211 self.add_instruction(JvmInstruction::Lload0)
212 }
213 pub fn lload_1(self) -> Self {
214 self.add_instruction(JvmInstruction::Lload1)
215 }
216 pub fn lload_2(self) -> Self {
217 self.add_instruction(JvmInstruction::Lload2)
218 }
219 pub fn lload_3(self) -> Self {
220 self.add_instruction(JvmInstruction::Lload3)
221 }
222 pub fn fload_0(self) -> Self {
223 self.add_instruction(JvmInstruction::Fload0)
224 }
225 pub fn fload_1(self) -> Self {
226 self.add_instruction(JvmInstruction::Fload1)
227 }
228 pub fn fload_2(self) -> Self {
229 self.add_instruction(JvmInstruction::Fload2)
230 }
231 pub fn fload_3(self) -> Self {
232 self.add_instruction(JvmInstruction::Fload3)
233 }
234 pub fn dload_0(self) -> Self {
235 self.add_instruction(JvmInstruction::Dload0)
236 }
237 pub fn dload_1(self) -> Self {
238 self.add_instruction(JvmInstruction::Dload1)
239 }
240 pub fn dload_2(self) -> Self {
241 self.add_instruction(JvmInstruction::Dload2)
242 }
243 pub fn dload_3(self) -> Self {
244 self.add_instruction(JvmInstruction::Dload3)
245 }
246 pub fn aload_0(self) -> Self {
247 self.add_instruction(JvmInstruction::Aload0)
248 }
249 pub fn aload_1(self) -> Self {
250 self.add_instruction(JvmInstruction::Aload1)
251 }
252 pub fn aload_2(self) -> Self {
253 self.add_instruction(JvmInstruction::Aload2)
254 }
255 pub fn aload_3(self) -> Self {
256 self.add_instruction(JvmInstruction::Aload3)
257 }
258
259 pub fn istore(self, index: u16) -> Self {
260 self.add_instruction(JvmInstruction::Istore { index })
261 }
262 pub fn lstore(self, index: u16) -> Self {
263 self.add_instruction(JvmInstruction::Lstore { index })
264 }
265 pub fn fstore(self, index: u16) -> Self {
266 self.add_instruction(JvmInstruction::Fstore { index })
267 }
268 pub fn dstore(self, index: u16) -> Self {
269 self.add_instruction(JvmInstruction::Dstore { index })
270 }
271 pub fn astore(self, index: u16) -> Self {
272 self.add_instruction(JvmInstruction::Astore { index })
273 }
274 pub fn istore_0(self) -> Self {
275 self.add_instruction(JvmInstruction::Istore0)
276 }
277 pub fn istore_1(self) -> Self {
278 self.add_instruction(JvmInstruction::Istore1)
279 }
280 pub fn istore_2(self) -> Self {
281 self.add_instruction(JvmInstruction::Istore2)
282 }
283 pub fn istore_3(self) -> Self {
284 self.add_instruction(JvmInstruction::Istore3)
285 }
286 pub fn lstore_0(self) -> Self {
287 self.add_instruction(JvmInstruction::Lstore0)
288 }
289 pub fn lstore_1(self) -> Self {
290 self.add_instruction(JvmInstruction::Lstore1)
291 }
292 pub fn lstore_2(self) -> Self {
293 self.add_instruction(JvmInstruction::Lstore2)
294 }
295 pub fn lstore_3(self) -> Self {
296 self.add_instruction(JvmInstruction::Lstore3)
297 }
298 pub fn fstore_0(self) -> Self {
299 self.add_instruction(JvmInstruction::Fstore0)
300 }
301 pub fn fstore_1(self) -> Self {
302 self.add_instruction(JvmInstruction::Fstore1)
303 }
304 pub fn fstore_2(self) -> Self {
305 self.add_instruction(JvmInstruction::Fstore2)
306 }
307 pub fn fstore_3(self) -> Self {
308 self.add_instruction(JvmInstruction::Fstore3)
309 }
310 pub fn dstore_0(self) -> Self {
311 self.add_instruction(JvmInstruction::Dstore0)
312 }
313 pub fn dstore_1(self) -> Self {
314 self.add_instruction(JvmInstruction::Dstore1)
315 }
316 pub fn dstore_2(self) -> Self {
317 self.add_instruction(JvmInstruction::Dstore2)
318 }
319 pub fn dstore_3(self) -> Self {
320 self.add_instruction(JvmInstruction::Dstore3)
321 }
322 pub fn astore_0(self) -> Self {
323 self.add_instruction(JvmInstruction::Astore0)
324 }
325 pub fn astore_1(self) -> Self {
326 self.add_instruction(JvmInstruction::Astore1)
327 }
328 pub fn astore_2(self) -> Self {
329 self.add_instruction(JvmInstruction::Astore2)
330 }
331 pub fn astore_3(self) -> Self {
332 self.add_instruction(JvmInstruction::Astore3)
333 }
334
335 pub fn iadd(self) -> Self {
336 self.add_instruction(JvmInstruction::Iadd)
337 }
338 pub fn ladd(self) -> Self {
339 self.add_instruction(JvmInstruction::Ladd)
340 }
341 pub fn fadd(self) -> Self {
342 self.add_instruction(JvmInstruction::Fadd)
343 }
344 pub fn dadd(self) -> Self {
345 self.add_instruction(JvmInstruction::Dadd)
346 }
347 pub fn isub(self) -> Self {
348 self.add_instruction(JvmInstruction::Isub)
349 }
350 pub fn lsub(self) -> Self {
351 self.add_instruction(JvmInstruction::Lsub)
352 }
353 pub fn fsub(self) -> Self {
354 self.add_instruction(JvmInstruction::Fsub)
355 }
356 pub fn dsub(self) -> Self {
357 self.add_instruction(JvmInstruction::Dsub)
358 }
359 pub fn imul(self) -> Self {
360 self.add_instruction(JvmInstruction::Imul)
361 }
362 pub fn lmul(self) -> Self {
363 self.add_instruction(JvmInstruction::Lmul)
364 }
365 pub fn fmul(self) -> Self {
366 self.add_instruction(JvmInstruction::Fmul)
367 }
368 pub fn dmul(self) -> Self {
369 self.add_instruction(JvmInstruction::Dmul)
370 }
371 pub fn idiv(self) -> Self {
372 self.add_instruction(JvmInstruction::Idiv)
373 }
374 pub fn ldiv(self) -> Self {
375 self.add_instruction(JvmInstruction::Ldiv)
376 }
377 pub fn fdiv(self) -> Self {
378 self.add_instruction(JvmInstruction::Fdiv)
379 }
380 pub fn ddiv(self) -> Self {
381 self.add_instruction(JvmInstruction::Ddiv)
382 }
383 pub fn irem(self) -> Self {
384 self.add_instruction(JvmInstruction::Irem)
385 }
386 pub fn lrem(self) -> Self {
387 self.add_instruction(JvmInstruction::Lrem)
388 }
389 pub fn frem(self) -> Self {
390 self.add_instruction(JvmInstruction::Frem)
391 }
392 pub fn drem(self) -> Self {
393 self.add_instruction(JvmInstruction::Drem)
394 }
395 pub fn ineg(self) -> Self {
396 self.add_instruction(JvmInstruction::Ineg)
397 }
398 pub fn lneg(self) -> Self {
399 self.add_instruction(JvmInstruction::Lneg)
400 }
401 pub fn fneg(self) -> Self {
402 self.add_instruction(JvmInstruction::Fneg)
403 }
404 pub fn dneg(self) -> Self {
405 self.add_instruction(JvmInstruction::Dneg)
406 }
407
408 pub fn ishl(self) -> Self {
409 self.add_instruction(JvmInstruction::Ishl)
410 }
411 pub fn lshl(self) -> Self {
412 self.add_instruction(JvmInstruction::Lshl)
413 }
414 pub fn ishr(self) -> Self {
415 self.add_instruction(JvmInstruction::Ishr)
416 }
417 pub fn lshr(self) -> Self {
418 self.add_instruction(JvmInstruction::Lshr)
419 }
420 pub fn iushr(self) -> Self {
421 self.add_instruction(JvmInstruction::Iushr)
422 }
423 pub fn lushr(self) -> Self {
424 self.add_instruction(JvmInstruction::Lushr)
425 }
426 pub fn iand(self) -> Self {
427 self.add_instruction(JvmInstruction::Iand)
428 }
429 pub fn land(self) -> Self {
430 self.add_instruction(JvmInstruction::Land)
431 }
432 pub fn ior(self) -> Self {
433 self.add_instruction(JvmInstruction::Ior)
434 }
435 pub fn lor(self) -> Self {
436 self.add_instruction(JvmInstruction::Lor)
437 }
438 pub fn ixor(self) -> Self {
439 self.add_instruction(JvmInstruction::Ixor)
440 }
441 pub fn lxor(self) -> Self {
442 self.add_instruction(JvmInstruction::Lxor)
443 }
444
445 pub fn lcmp(self) -> Self {
446 self.add_instruction(JvmInstruction::Lcmp)
447 }
448 pub fn fcmpl(self) -> Self {
449 self.add_instruction(JvmInstruction::Fcmpl)
450 }
451 pub fn fcmpg(self) -> Self {
452 self.add_instruction(JvmInstruction::Fcmpg)
453 }
454 pub fn dcmpl(self) -> Self {
455 self.add_instruction(JvmInstruction::Dcmpl)
456 }
457 pub fn dcmpg(self) -> Self {
458 self.add_instruction(JvmInstruction::Dcmpg)
459 }
460
461 pub fn iinc(self, index: u16, increment: i16) -> Self {
462 self.add_instruction(JvmInstruction::Iinc { index, increment })
463 }
464
465 pub fn getstatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
466 self.add_instruction(JvmInstruction::Getstatic {
467 class_name: class.into(),
468 field_name: name.into(),
469 descriptor: desc.into(),
470 })
471 }
472
473 pub fn putstatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
474 self.add_instruction(JvmInstruction::Putstatic {
475 class_name: class.into(),
476 field_name: name.into(),
477 descriptor: desc.into(),
478 })
479 }
480
481 pub fn getfield(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
482 self.add_instruction(JvmInstruction::Getfield {
483 class_name: class.into(),
484 field_name: name.into(),
485 descriptor: desc.into(),
486 })
487 }
488
489 pub fn putfield(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
490 self.add_instruction(JvmInstruction::Putfield {
491 class_name: class.into(),
492 field_name: name.into(),
493 descriptor: desc.into(),
494 })
495 }
496
497 pub fn invokevirtual(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
498 self.add_instruction(JvmInstruction::Invokevirtual {
499 class_name: class.into(),
500 method_name: name.into(),
501 descriptor: desc.into(),
502 })
503 }
504
505 pub fn invokespecial(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
506 self.add_instruction(JvmInstruction::Invokespecial {
507 class_name: class.into(),
508 method_name: name.into(),
509 descriptor: desc.into(),
510 })
511 }
512
513 pub fn invokestatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
514 self.add_instruction(JvmInstruction::Invokestatic {
515 class_name: class.into(),
516 method_name: name.into(),
517 descriptor: desc.into(),
518 })
519 }
520
521 pub fn invokeinterface(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
522 self.add_instruction(JvmInstruction::Invokeinterface {
523 class_name: class.into(),
524 method_name: name.into(),
525 descriptor: desc.into(),
526 })
527 }
528
529 pub fn new_instance(self, class: impl Into<String>) -> Self {
530 self.add_instruction(JvmInstruction::New { class_name: class.into() })
531 }
532
533 pub fn dup(self) -> Self {
534 self.add_instruction(JvmInstruction::Dup)
535 }
536 pub fn dup_x1(self) -> Self {
537 self.add_instruction(JvmInstruction::DupX1)
538 }
539 pub fn dup_x2(self) -> Self {
540 self.add_instruction(JvmInstruction::DupX2)
541 }
542 pub fn dup2(self) -> Self {
543 self.add_instruction(JvmInstruction::Dup2)
544 }
545 pub fn dup2_x1(self) -> Self {
546 self.add_instruction(JvmInstruction::Dup2X1)
547 }
548 pub fn dup2_x2(self) -> Self {
549 self.add_instruction(JvmInstruction::Dup2X2)
550 }
551 pub fn swap(self) -> Self {
552 self.add_instruction(JvmInstruction::Swap)
553 }
554 pub fn pop(self) -> Self {
555 self.add_instruction(JvmInstruction::Pop)
556 }
557 pub fn pop2(self) -> Self {
558 self.add_instruction(JvmInstruction::Pop2)
559 }
560
561 pub fn return_void(self) -> Self {
562 self.add_instruction(JvmInstruction::Return)
563 }
564 pub fn ireturn(self) -> Self {
565 self.add_instruction(JvmInstruction::Ireturn)
566 }
567 pub fn lreturn(self) -> Self {
568 self.add_instruction(JvmInstruction::Lreturn)
569 }
570 pub fn freturn(self) -> Self {
571 self.add_instruction(JvmInstruction::Freturn)
572 }
573 pub fn dreturn(self) -> Self {
574 self.add_instruction(JvmInstruction::Dreturn)
575 }
576 pub fn areturn(self) -> Self {
577 self.add_instruction(JvmInstruction::Areturn)
578 }
579
580 pub fn label(self, name: impl Into<String>) -> Self {
581 self.add_instruction(JvmInstruction::Label { name: name.into() })
582 }
583
584 pub fn goto(self, target: impl Into<String>) -> Self {
585 self.add_instruction(JvmInstruction::Goto { target: target.into() })
586 }
587
588 pub fn ifeq(self, target: impl Into<String>) -> Self {
589 self.add_instruction(JvmInstruction::Ifeq { target: target.into() })
590 }
591
592 pub fn ifne(self, target: impl Into<String>) -> Self {
593 self.add_instruction(JvmInstruction::Ifne { target: target.into() })
594 }
595
596 pub fn build(self) -> JvmMethod {
597 self.method
598 }
599}