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 {
11 Self { program: JvmProgram::new(name.into()) }
12 }
13
14 pub fn with_version(mut self, major: u16, minor: u16) -> Self {
16 self.program.version = JvmVersion { major, minor };
17 self
18 }
19
20 pub fn with_access_flags(mut self, flags: JvmAccessFlags) -> Self {
22 self.program.access_flags = flags;
23 self
24 }
25
26 pub fn with_public(mut self) -> Self {
28 self.program.access_flags.is_public = true;
29 self
30 }
31
32 pub fn with_super_class(mut self, super_class: impl Into<String>) -> Self {
34 self.program.super_class = Some(super_class.into());
35 self
36 }
37
38 pub fn add_interface(mut self, interface: impl Into<String>) -> Self {
40 self.program.interfaces.push(interface.into());
41 self
42 }
43
44 pub fn with_source_file(mut self, source_file: impl Into<String>) -> Self {
46 self.program.source_file = Some(source_file.into());
47 self
48 }
49
50 pub fn add_method<F>(mut self, name: impl Into<String>, descriptor: impl Into<String>, f: F) -> Self
52 where
53 F: FnOnce(JvmMethodBuilder) -> JvmMethodBuilder,
54 {
55 let builder = JvmMethodBuilder::new(name.into(), descriptor.into());
56 let method = f(builder).build();
57 self.program.add_method(method);
58 self
59 }
60
61 pub fn build(self) -> JvmProgram {
63 self.program
64 }
65}
66
67pub struct JvmMethodBuilder {
69 method: JvmMethod,
70}
71
72impl JvmMethodBuilder {
73 pub fn new(name: String, descriptor: String) -> Self {
75 Self { method: JvmMethod::new(name, descriptor) }
76 }
77
78 pub fn with_public(mut self) -> Self {
80 self.method.access_flags.is_public = true;
81 self
82 }
83
84 pub fn with_private(mut self) -> Self {
86 self.method.access_flags.is_private = true;
87 self
88 }
89
90 pub fn with_protected(mut self) -> Self {
92 self.method.access_flags.is_protected = true;
93 self
94 }
95
96 pub fn with_static(mut self) -> Self {
98 self.method.access_flags.is_static = true;
99 self
100 }
101
102 pub fn with_final(mut self) -> Self {
104 self.method.access_flags.is_final = true;
105 self
106 }
107
108 pub fn with_synchronized(mut self) -> Self {
110 self.method.access_flags.is_synchronized = true;
111 self
112 }
113
114 pub fn with_max_stack(mut self, max_stack: u16) -> Self {
116 self.method.max_stack = max_stack;
117 self
118 }
119
120 pub fn with_max_locals(mut self, max_locals: u16) -> Self {
122 self.method.max_locals = max_locals;
123 self
124 }
125
126 pub fn add_instruction(mut self, instruction: JvmInstruction) -> Self {
128 self.method.add_instruction(instruction);
129 self
130 }
131
132 pub fn add_exception_handler(mut self, handler: JvmExceptionHandler) -> Self {
134 self.method.add_exception_handler(handler);
135 self
136 }
137
138 pub fn add_exception(mut self, exception: impl Into<String>) -> Self {
140 self.method.add_exception(exception.into());
141 self
142 }
143
144 pub fn nop(self) -> Self {
147 self.add_instruction(JvmInstruction::Nop)
148 }
149 pub fn aconst_null(self) -> Self {
151 self.add_instruction(JvmInstruction::AconstNull)
152 }
153 pub fn iconst_m1(self) -> Self {
155 self.add_instruction(JvmInstruction::IconstM1)
156 }
157 pub fn iconst_0(self) -> Self {
159 self.add_instruction(JvmInstruction::Iconst0)
160 }
161 pub fn iconst_1(self) -> Self {
163 self.add_instruction(JvmInstruction::Iconst1)
164 }
165 pub fn iconst_2(self) -> Self {
167 self.add_instruction(JvmInstruction::Iconst2)
168 }
169 pub fn iconst_3(self) -> Self {
171 self.add_instruction(JvmInstruction::Iconst3)
172 }
173 pub fn iconst_4(self) -> Self {
175 self.add_instruction(JvmInstruction::Iconst4)
176 }
177 pub fn iconst_5(self) -> Self {
179 self.add_instruction(JvmInstruction::Iconst5)
180 }
181 pub fn lconst_0(self) -> Self {
183 self.add_instruction(JvmInstruction::Lconst0)
184 }
185 pub fn lconst_1(self) -> Self {
187 self.add_instruction(JvmInstruction::Lconst1)
188 }
189 pub fn fconst_0(self) -> Self {
191 self.add_instruction(JvmInstruction::Fconst0)
192 }
193 pub fn fconst_1(self) -> Self {
195 self.add_instruction(JvmInstruction::Fconst1)
196 }
197 pub fn fconst_2(self) -> Self {
199 self.add_instruction(JvmInstruction::Fconst2)
200 }
201 pub fn dconst_0(self) -> Self {
203 self.add_instruction(JvmInstruction::Dconst0)
204 }
205 pub fn dconst_1(self) -> Self {
207 self.add_instruction(JvmInstruction::Dconst1)
208 }
209
210 pub fn bipush(self, value: i8) -> Self {
212 self.add_instruction(JvmInstruction::Bipush { value })
213 }
214 pub fn sipush(self, value: i16) -> Self {
216 self.add_instruction(JvmInstruction::Sipush { value })
217 }
218 pub fn ldc(self, symbol: impl Into<String>) -> Self {
220 self.add_instruction(JvmInstruction::Ldc { symbol: symbol.into() })
221 }
222
223 pub fn iload(self, index: u16) -> Self {
225 self.add_instruction(JvmInstruction::Iload { index })
226 }
227 pub fn lload(self, index: u16) -> Self {
229 self.add_instruction(JvmInstruction::Lload { index })
230 }
231 pub fn fload(self, index: u16) -> Self {
233 self.add_instruction(JvmInstruction::Fload { index })
234 }
235 pub fn dload(self, index: u16) -> Self {
237 self.add_instruction(JvmInstruction::Dload { index })
238 }
239 pub fn aload(self, index: u16) -> Self {
241 self.add_instruction(JvmInstruction::Aload { index })
242 }
243 pub fn iload_0(self) -> Self {
245 self.add_instruction(JvmInstruction::Iload0)
246 }
247 pub fn iload_1(self) -> Self {
249 self.add_instruction(JvmInstruction::Iload1)
250 }
251 pub fn iload_2(self) -> Self {
253 self.add_instruction(JvmInstruction::Iload2)
254 }
255 pub fn iload_3(self) -> Self {
257 self.add_instruction(JvmInstruction::Iload3)
258 }
259 pub fn lload_0(self) -> Self {
261 self.add_instruction(JvmInstruction::Lload0)
262 }
263 pub fn lload_1(self) -> Self {
265 self.add_instruction(JvmInstruction::Lload1)
266 }
267 pub fn lload_2(self) -> Self {
269 self.add_instruction(JvmInstruction::Lload2)
270 }
271 pub fn lload_3(self) -> Self {
273 self.add_instruction(JvmInstruction::Lload3)
274 }
275 pub fn fload_0(self) -> Self {
277 self.add_instruction(JvmInstruction::Fload0)
278 }
279 pub fn fload_1(self) -> Self {
281 self.add_instruction(JvmInstruction::Fload1)
282 }
283 pub fn fload_2(self) -> Self {
285 self.add_instruction(JvmInstruction::Fload2)
286 }
287 pub fn fload_3(self) -> Self {
289 self.add_instruction(JvmInstruction::Fload3)
290 }
291 pub fn dload_0(self) -> Self {
293 self.add_instruction(JvmInstruction::Dload0)
294 }
295 pub fn dload_1(self) -> Self {
297 self.add_instruction(JvmInstruction::Dload1)
298 }
299 pub fn dload_2(self) -> Self {
301 self.add_instruction(JvmInstruction::Dload2)
302 }
303 pub fn dload_3(self) -> Self {
305 self.add_instruction(JvmInstruction::Dload3)
306 }
307 pub fn aload_0(self) -> Self {
309 self.add_instruction(JvmInstruction::Aload0)
310 }
311 pub fn aload_1(self) -> Self {
313 self.add_instruction(JvmInstruction::Aload1)
314 }
315 pub fn aload_2(self) -> Self {
317 self.add_instruction(JvmInstruction::Aload2)
318 }
319 pub fn aload_3(self) -> Self {
321 self.add_instruction(JvmInstruction::Aload3)
322 }
323
324 pub fn istore(self, index: u16) -> Self {
326 self.add_instruction(JvmInstruction::Istore { index })
327 }
328 pub fn lstore(self, index: u16) -> Self {
330 self.add_instruction(JvmInstruction::Lstore { index })
331 }
332 pub fn fstore(self, index: u16) -> Self {
334 self.add_instruction(JvmInstruction::Fstore { index })
335 }
336 pub fn dstore(self, index: u16) -> Self {
338 self.add_instruction(JvmInstruction::Dstore { index })
339 }
340 pub fn astore(self, index: u16) -> Self {
342 self.add_instruction(JvmInstruction::Astore { index })
343 }
344 pub fn istore_0(self) -> Self {
346 self.add_instruction(JvmInstruction::Istore0)
347 }
348 pub fn istore_1(self) -> Self {
350 self.add_instruction(JvmInstruction::Istore1)
351 }
352 pub fn istore_2(self) -> Self {
354 self.add_instruction(JvmInstruction::Istore2)
355 }
356 pub fn istore_3(self) -> Self {
358 self.add_instruction(JvmInstruction::Istore3)
359 }
360 pub fn lstore_0(self) -> Self {
362 self.add_instruction(JvmInstruction::Lstore0)
363 }
364 pub fn lstore_1(self) -> Self {
366 self.add_instruction(JvmInstruction::Lstore1)
367 }
368 pub fn lstore_2(self) -> Self {
370 self.add_instruction(JvmInstruction::Lstore2)
371 }
372 pub fn lstore_3(self) -> Self {
374 self.add_instruction(JvmInstruction::Lstore3)
375 }
376 pub fn fstore_0(self) -> Self {
378 self.add_instruction(JvmInstruction::Fstore0)
379 }
380 pub fn fstore_1(self) -> Self {
382 self.add_instruction(JvmInstruction::Fstore1)
383 }
384 pub fn fstore_2(self) -> Self {
386 self.add_instruction(JvmInstruction::Fstore2)
387 }
388 pub fn fstore_3(self) -> Self {
390 self.add_instruction(JvmInstruction::Fstore3)
391 }
392 pub fn dstore_0(self) -> Self {
394 self.add_instruction(JvmInstruction::Dstore0)
395 }
396 pub fn dstore_1(self) -> Self {
398 self.add_instruction(JvmInstruction::Dstore1)
399 }
400 pub fn dstore_2(self) -> Self {
402 self.add_instruction(JvmInstruction::Dstore2)
403 }
404 pub fn dstore_3(self) -> Self {
406 self.add_instruction(JvmInstruction::Dstore3)
407 }
408 pub fn astore_0(self) -> Self {
410 self.add_instruction(JvmInstruction::Astore0)
411 }
412 pub fn astore_1(self) -> Self {
414 self.add_instruction(JvmInstruction::Astore1)
415 }
416 pub fn astore_2(self) -> Self {
418 self.add_instruction(JvmInstruction::Astore2)
419 }
420 pub fn astore_3(self) -> Self {
422 self.add_instruction(JvmInstruction::Astore3)
423 }
424
425 pub fn iadd(self) -> Self {
427 self.add_instruction(JvmInstruction::Iadd)
428 }
429 pub fn ladd(self) -> Self {
431 self.add_instruction(JvmInstruction::Ladd)
432 }
433 pub fn fadd(self) -> Self {
435 self.add_instruction(JvmInstruction::Fadd)
436 }
437 pub fn dadd(self) -> Self {
439 self.add_instruction(JvmInstruction::Dadd)
440 }
441 pub fn isub(self) -> Self {
443 self.add_instruction(JvmInstruction::Isub)
444 }
445 pub fn lsub(self) -> Self {
447 self.add_instruction(JvmInstruction::Lsub)
448 }
449 pub fn fsub(self) -> Self {
451 self.add_instruction(JvmInstruction::Fsub)
452 }
453 pub fn dsub(self) -> Self {
455 self.add_instruction(JvmInstruction::Dsub)
456 }
457 pub fn imul(self) -> Self {
459 self.add_instruction(JvmInstruction::Imul)
460 }
461 pub fn lmul(self) -> Self {
463 self.add_instruction(JvmInstruction::Lmul)
464 }
465 pub fn fmul(self) -> Self {
467 self.add_instruction(JvmInstruction::Fmul)
468 }
469 pub fn dmul(self) -> Self {
471 self.add_instruction(JvmInstruction::Dmul)
472 }
473 pub fn idiv(self) -> Self {
475 self.add_instruction(JvmInstruction::Idiv)
476 }
477 pub fn ldiv(self) -> Self {
479 self.add_instruction(JvmInstruction::Ldiv)
480 }
481 pub fn fdiv(self) -> Self {
483 self.add_instruction(JvmInstruction::Fdiv)
484 }
485 pub fn ddiv(self) -> Self {
487 self.add_instruction(JvmInstruction::Ddiv)
488 }
489 pub fn irem(self) -> Self {
491 self.add_instruction(JvmInstruction::Irem)
492 }
493 pub fn lrem(self) -> Self {
495 self.add_instruction(JvmInstruction::Lrem)
496 }
497 pub fn frem(self) -> Self {
499 self.add_instruction(JvmInstruction::Frem)
500 }
501 pub fn drem(self) -> Self {
503 self.add_instruction(JvmInstruction::Drem)
504 }
505 pub fn ineg(self) -> Self {
507 self.add_instruction(JvmInstruction::Ineg)
508 }
509 pub fn lneg(self) -> Self {
511 self.add_instruction(JvmInstruction::Lneg)
512 }
513 pub fn fneg(self) -> Self {
515 self.add_instruction(JvmInstruction::Fneg)
516 }
517 pub fn dneg(self) -> Self {
519 self.add_instruction(JvmInstruction::Dneg)
520 }
521
522 pub fn ishl(self) -> Self {
524 self.add_instruction(JvmInstruction::Ishl)
525 }
526 pub fn lshl(self) -> Self {
528 self.add_instruction(JvmInstruction::Lshl)
529 }
530 pub fn ishr(self) -> Self {
532 self.add_instruction(JvmInstruction::Ishr)
533 }
534 pub fn lshr(self) -> Self {
536 self.add_instruction(JvmInstruction::Lshr)
537 }
538 pub fn iushr(self) -> Self {
540 self.add_instruction(JvmInstruction::Iushr)
541 }
542 pub fn lushr(self) -> Self {
544 self.add_instruction(JvmInstruction::Lushr)
545 }
546 pub fn iand(self) -> Self {
548 self.add_instruction(JvmInstruction::Iand)
549 }
550 pub fn land(self) -> Self {
552 self.add_instruction(JvmInstruction::Land)
553 }
554 pub fn ior(self) -> Self {
556 self.add_instruction(JvmInstruction::Ior)
557 }
558 pub fn lor(self) -> Self {
560 self.add_instruction(JvmInstruction::Lor)
561 }
562 pub fn ixor(self) -> Self {
564 self.add_instruction(JvmInstruction::Ixor)
565 }
566 pub fn lxor(self) -> Self {
568 self.add_instruction(JvmInstruction::Lxor)
569 }
570
571 pub fn lcmp(self) -> Self {
573 self.add_instruction(JvmInstruction::Lcmp)
574 }
575 pub fn fcmpl(self) -> Self {
577 self.add_instruction(JvmInstruction::Fcmpl)
578 }
579 pub fn fcmpg(self) -> Self {
581 self.add_instruction(JvmInstruction::Fcmpg)
582 }
583 pub fn dcmpl(self) -> Self {
585 self.add_instruction(JvmInstruction::Dcmpl)
586 }
587 pub fn dcmpg(self) -> Self {
589 self.add_instruction(JvmInstruction::Dcmpg)
590 }
591
592 pub fn iinc(self, index: u16, value: i16) -> Self {
594 self.add_instruction(JvmInstruction::Iinc { index, value })
595 }
596
597 pub fn getstatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
599 self.add_instruction(JvmInstruction::Getstatic {
600 class_name: class.into(),
601 field_name: name.into(),
602 descriptor: desc.into(),
603 })
604 }
605
606 pub fn putstatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
608 self.add_instruction(JvmInstruction::Putstatic {
609 class_name: class.into(),
610 field_name: name.into(),
611 descriptor: desc.into(),
612 })
613 }
614
615 pub fn getfield(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
617 self.add_instruction(JvmInstruction::Getfield {
618 class_name: class.into(),
619 field_name: name.into(),
620 descriptor: desc.into(),
621 })
622 }
623
624 pub fn putfield(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
626 self.add_instruction(JvmInstruction::Putfield {
627 class_name: class.into(),
628 field_name: name.into(),
629 descriptor: desc.into(),
630 })
631 }
632
633 pub fn invokevirtual(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
635 self.add_instruction(JvmInstruction::Invokevirtual {
636 class_name: class.into(),
637 method_name: name.into(),
638 descriptor: desc.into(),
639 })
640 }
641
642 pub fn invokespecial(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
644 self.add_instruction(JvmInstruction::Invokespecial {
645 class_name: class.into(),
646 method_name: name.into(),
647 descriptor: desc.into(),
648 })
649 }
650
651 pub fn invokestatic(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
653 self.add_instruction(JvmInstruction::Invokestatic {
654 class_name: class.into(),
655 method_name: name.into(),
656 descriptor: desc.into(),
657 })
658 }
659
660 pub fn invokeinterface(self, class: impl Into<String>, name: impl Into<String>, desc: impl Into<String>) -> Self {
662 self.add_instruction(JvmInstruction::Invokeinterface {
663 class_name: class.into(),
664 method_name: name.into(),
665 descriptor: desc.into(),
666 })
667 }
668
669 pub fn new_instance(self, class: impl Into<String>) -> Self {
671 self.add_instruction(JvmInstruction::New { class_name: class.into() })
672 }
673
674 pub fn dup(self) -> Self {
676 self.add_instruction(JvmInstruction::Dup)
677 }
678 pub fn dup_x1(self) -> Self {
680 self.add_instruction(JvmInstruction::DupX1)
681 }
682 pub fn dup_x2(self) -> Self {
684 self.add_instruction(JvmInstruction::DupX2)
685 }
686 pub fn dup2(self) -> Self {
688 self.add_instruction(JvmInstruction::Dup2)
689 }
690 pub fn dup2_x1(self) -> Self {
692 self.add_instruction(JvmInstruction::Dup2X1)
693 }
694 pub fn dup2_x2(self) -> Self {
696 self.add_instruction(JvmInstruction::Dup2X2)
697 }
698 pub fn swap(self) -> Self {
700 self.add_instruction(JvmInstruction::Swap)
701 }
702 pub fn pop(self) -> Self {
704 self.add_instruction(JvmInstruction::Pop)
705 }
706 pub fn pop2(self) -> Self {
708 self.add_instruction(JvmInstruction::Pop2)
709 }
710
711 pub fn return_void(self) -> Self {
713 self.add_instruction(JvmInstruction::Return)
714 }
715 pub fn ireturn(self) -> Self {
717 self.add_instruction(JvmInstruction::Ireturn)
718 }
719 pub fn lreturn(self) -> Self {
721 self.add_instruction(JvmInstruction::Lreturn)
722 }
723 pub fn freturn(self) -> Self {
725 self.add_instruction(JvmInstruction::Freturn)
726 }
727 pub fn dreturn(self) -> Self {
729 self.add_instruction(JvmInstruction::Dreturn)
730 }
731 pub fn areturn(self) -> Self {
733 self.add_instruction(JvmInstruction::Areturn)
734 }
735
736 pub fn label(self, name: impl Into<String>) -> Self {
738 self.add_instruction(JvmInstruction::Label { name: name.into() })
739 }
740
741 pub fn goto(self, target: impl Into<String>) -> Self {
743 self.add_instruction(JvmInstruction::Goto { target: target.into() })
744 }
745
746 pub fn ifeq(self, target: impl Into<String>) -> Self {
748 self.add_instruction(JvmInstruction::Ifeq { target: target.into() })
749 }
750
751 pub fn ifne(self, target: impl Into<String>) -> Self {
753 self.add_instruction(JvmInstruction::Ifne { target: target.into() })
754 }
755
756 pub fn build(self) -> JvmMethod {
758 self.method
759 }
760}