1 // ASM: a very small and fast Java bytecode manipulation framework 2 // Copyright (c) 2000-2011 INRIA, France Telecom 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. Neither the name of the copyright holders nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 // THE POSSIBILITY OF SUCH DAMAGE. 28 package org.objectweb.asm.tree; 29 30 import static org.junit.jupiter.api.Assertions.assertArrayEquals; 31 import static org.junit.jupiter.api.Assertions.assertEquals; 32 import static org.junit.jupiter.api.Assertions.assertFalse; 33 import static org.junit.jupiter.api.Assertions.assertNotNull; 34 import static org.junit.jupiter.api.Assertions.assertNotSame; 35 import static org.junit.jupiter.api.Assertions.assertNull; 36 import static org.junit.jupiter.api.Assertions.assertThrows; 37 import static org.junit.jupiter.api.Assertions.assertTrue; 38 39 import java.util.ListIterator; 40 import java.util.NoSuchElementException; 41 import org.junit.jupiter.api.Test; 42 import org.junit.jupiter.api.function.Executable; 43 import org.objectweb.asm.Label; 44 import org.objectweb.asm.MethodVisitor; 45 import org.objectweb.asm.Opcodes; 46 47 /** 48 * Unit tests for {@link InsnList}. 49 * 50 * @author Eric Bruneton 51 * @author Eugene Kuleshov 52 */ 53 class InsnListTest { 54 55 private final InsnNode insn1 = new InsnNode(0); 56 private final InsnNode insn2 = new InsnNode(1); 57 58 @Test testSize_emptyList()59 void testSize_emptyList() { 60 assertEquals(0, newInsnList().size()); 61 } 62 63 @Test testGetFirst_emptyList()64 void testGetFirst_emptyList() { 65 assertEquals(null, newInsnList().getFirst()); 66 } 67 68 @Test testGetLast_emptyList()69 void testGetLast_emptyList() { 70 assertEquals(null, newInsnList().getLast()); 71 } 72 73 @Test testGet_outOfBounds()74 void testGet_outOfBounds() { 75 Executable get = () -> newInsnList().get(0); 76 77 assertThrows(IndexOutOfBoundsException.class, get); 78 } 79 80 @Test testContains()81 void testContains() { 82 assertFalse(newInsnList().contains(new InsnNode(0))); 83 } 84 85 @Test testIndexOf_noSuchElement()86 void testIndexOf_noSuchElement() { 87 InsnList insnList = newInsnList(); 88 89 Executable indexOf = () -> insnList.indexOf(new InsnNode(0)); 90 91 assertThrows(NoSuchElementException.class, indexOf); 92 } 93 94 @Test testIndexOf()95 void testIndexOf() { 96 InsnList insnList = newInsnList(insn1, insn2); 97 98 int index1 = insnList.indexOf(insn1); 99 int index2 = insnList.indexOf(insn2); 100 101 assertEquals(0, index1); 102 assertEquals(1, index2); 103 } 104 105 @Test testAccept_cloneListVisitor()106 void testAccept_cloneListVisitor() { 107 InsnList insnList = newInsnList(); 108 insnList.add(new InsnNode(55)); 109 insnList.add(new InsnNode(77)); 110 InsnList dstInsnList = new InsnList(); 111 112 insnList.accept( 113 new MethodVisitor(/* latest */ Opcodes.ASM10_EXPERIMENTAL) { 114 @Override 115 public void visitInsn(final int opcode) { 116 dstInsnList.add(new InsnNode(opcode)); 117 } 118 }); 119 120 assertEquals(2, dstInsnList.size()); 121 assertEquals(55, dstInsnList.get(0).opcode); 122 assertEquals(77, dstInsnList.get(1).opcode); 123 } 124 125 @Test testIteratorNext_noSuchElement()126 void testIteratorNext_noSuchElement() { 127 ListIterator<AbstractInsnNode> iterator = newInsnList().iterator(); 128 129 Executable next = () -> iterator.next(); 130 131 assertThrows(NoSuchElementException.class, next); 132 } 133 134 @Test testIteratorNext_nonEmptyList()135 void testIteratorNext_nonEmptyList() { 136 InsnList insnList = newInsnList(insn1, insn2); 137 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 138 139 AbstractInsnNode insn = iterator.next(); 140 141 assertEquals(insn2, insn); 142 assertFalse(iterator.hasNext()); 143 assertEquals(2, iterator.nextIndex()); 144 assertTrue(iterator.hasPrevious()); 145 assertEquals(1, iterator.previousIndex()); 146 } 147 148 @Test testIteratorPrevious_noSuchElement()149 void testIteratorPrevious_noSuchElement() { 150 ListIterator<AbstractInsnNode> iterator = newInsnList().iterator(); 151 152 Executable previous = () -> iterator.previous(); 153 154 assertThrows(NoSuchElementException.class, previous); 155 } 156 157 @Test testIteratorPrevious_nonEmptyList()158 void testIteratorPrevious_nonEmptyList() { 159 InsnList insnList = newInsnList(insn1, insn2); 160 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 161 162 AbstractInsnNode insn = iterator.previous(); 163 164 assertEquals(insn1, insn); 165 assertTrue(iterator.hasNext()); 166 assertEquals(0, iterator.nextIndex()); 167 assertFalse(iterator.hasPrevious()); 168 assertEquals(-1, iterator.previousIndex()); 169 } 170 171 @Test testIteratorAdd_emptyList()172 void testIteratorAdd_emptyList() { 173 InsnNode insn = new InsnNode(0); 174 InsnList insnList = newInsnList(); 175 176 insnList.iterator().add(insn); 177 178 assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray()); 179 } 180 181 @Test testIteratorAdd_firstInsn()182 void testIteratorAdd_firstInsn() { 183 InsnNode insn = new InsnNode(0); 184 InsnList insnList = newInsnList(insn1, insn2); 185 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 186 187 iterator.add(insn); 188 189 assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray()); 190 } 191 192 @Test testIteratorRemove_illegalState()193 void testIteratorRemove_illegalState() { 194 InsnList insnList = newInsnList(insn1, insn2); 195 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 196 197 Executable remove = () -> iterator.remove(); 198 199 assertThrows(IllegalStateException.class, remove); 200 } 201 202 @Test testIteratorRemove_afterNext()203 void testIteratorRemove_afterNext() { 204 InsnList insnList = newInsnList(insn1, insn2); 205 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 206 iterator.next(); 207 208 iterator.remove(); 209 210 assertArrayEquals(new AbstractInsnNode[] {insn1}, insnList.toArray()); 211 } 212 213 @Test testIteratorRemove_afterPrevious()214 void testIteratorRemove_afterPrevious() { 215 InsnList insnList = newInsnList(insn1, insn2); 216 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 217 iterator.previous(); 218 219 iterator.remove(); 220 221 assertArrayEquals(new AbstractInsnNode[] {insn2}, insnList.toArray()); 222 } 223 224 @Test testIteratorAdd_lastInsn()225 void testIteratorAdd_lastInsn() { 226 InsnNode insn = new InsnNode(0); 227 InsnList insnList = newInsnList(insn1, insn2); 228 ListIterator<AbstractInsnNode> iterator = insnList.iterator(2); 229 230 iterator.add(insn); 231 232 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray()); 233 } 234 235 @Test testIteratorSet_illegalState()236 void testIteratorSet_illegalState() { 237 InsnNode insn = new InsnNode(0); 238 InsnList insnList = newInsnList(insn1, insn2); 239 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 240 241 Executable set = () -> iterator.set(insn); 242 243 assertThrows(IllegalStateException.class, set); 244 } 245 246 @Test testIteratorSet_afterNext()247 void testIteratorSet_afterNext() { 248 InsnNode insn = new InsnNode(0); 249 InsnList insnList = newInsnList(insn1, insn2); 250 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 251 iterator.next(); 252 253 iterator.set(insn); 254 255 assertArrayEquals(new AbstractInsnNode[] {insn1, insn}, insnList.toArray()); 256 } 257 258 @Test testIteratorSet_afterPrevious()259 void testIteratorSet_afterPrevious() { 260 InsnNode insn = new InsnNode(0); 261 InsnList insnList = newInsnList(insn1, insn2); 262 ListIterator<AbstractInsnNode> iterator = insnList.iterator(1); 263 iterator.previous(); 264 265 iterator.set(insn); 266 267 assertArrayEquals(new AbstractInsnNode[] {insn, insn2}, insnList.toArray()); 268 } 269 270 @Test testIterator_cacheIsNull()271 void testIterator_cacheIsNull() { 272 InsnList insnList = newInsnList(insn1, insn2); 273 insnList.iterator(); 274 assertNull(insnList.cache); 275 } 276 277 @Test testToArray_emptyList()278 void testToArray_emptyList() { 279 assertEquals(0, newInsnList().toArray().length); 280 } 281 282 @Test testToArray_nonEmptyList()283 void testToArray_nonEmptyList() { 284 InsnList insnList = newInsnList(insn1, insn2); 285 286 AbstractInsnNode[] insnArray = insnList.toArray(); 287 288 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnArray); 289 } 290 291 @Test testSet_noSuchElement()292 void testSet_noSuchElement() { 293 InsnList insnList = newInsnList(); 294 295 Executable set = () -> insnList.set(new InsnNode(0), new InsnNode(0)); 296 297 assertThrows(NoSuchElementException.class, set); 298 } 299 300 @Test testSet_singleInsn()301 void testSet_singleInsn() { 302 InsnList insnList = newInsnList(); 303 insnList.add(insn1); 304 AbstractInsnNode insn = new InsnNode(0); 305 306 insnList.set(insn1, insn); 307 308 assertEquals(1, insnList.size()); 309 assertEquals(insn, insnList.getFirst()); 310 } 311 312 @Test testSet_firstInsn()313 void testSet_firstInsn() { 314 InsnList insnList = newInsnList(insn1, insn2); 315 AbstractInsnNode insn = new InsnNode(0); 316 317 insnList.set(insn1, insn); 318 319 assertEquals(2, insnList.size()); 320 assertEquals(insn, insnList.getFirst()); 321 } 322 323 @Test testSet_lastInsn()324 void testSet_lastInsn() { 325 InsnList insnList = newInsnList(insn1, insn2); 326 AbstractInsnNode insn = new InsnNode(0); 327 insnList.toArray(); 328 329 insnList.set(insn2, insn); 330 331 assertEquals(2, insnList.size()); 332 assertEquals(insn, insnList.getLast()); 333 } 334 335 @Test testAdd_illegalArgument()336 void testAdd_illegalArgument() { 337 InsnList insnList = newInsnList(); 338 newInsnList(insn1, insn2); 339 340 Executable add = () -> insnList.add(insn1); 341 342 assertThrows(IllegalArgumentException.class, add); 343 } 344 345 @Test testAdd_inEmptyList()346 void testAdd_inEmptyList() { 347 InsnList insnList = newInsnList(); 348 InsnNode insn = new InsnNode(0); 349 350 insnList.add(insn); 351 352 assertEquals(1, insnList.size()); 353 assertEquals(insn, insnList.getFirst()); 354 assertEquals(insn, insnList.getLast()); 355 assertEquals(insn, insnList.get(0)); 356 assertTrue(insnList.contains(insn)); 357 assertEquals(0, insnList.indexOf(insn)); 358 assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray()); 359 assertEquals(null, insn.getPrevious()); 360 assertEquals(null, insn.getNext()); 361 } 362 363 @Test testAdd_inNonEmptyList()364 void testAdd_inNonEmptyList() { 365 InsnList insnList = newInsnList(); 366 insnList.add(insn1); 367 InsnNode insn = new InsnNode(0); 368 369 insnList.add(insn); 370 371 assertEquals(2, insnList.size()); 372 assertEquals(insn, insnList.getLast()); 373 assertEquals(1, insnList.indexOf(insn)); 374 assertEquals(insn, insnList.get(1)); 375 assertTrue(insnList.contains(insn)); 376 } 377 378 @Test testAddList_illegalArgument()379 void testAddList_illegalArgument() { 380 InsnList insnList = newInsnList(); 381 382 Executable add = () -> insnList.add(insnList); 383 384 assertThrows(IllegalArgumentException.class, add); 385 } 386 387 @Test testAddList_inEmptyList_emptyList()388 void testAddList_inEmptyList_emptyList() { 389 InsnList insnList = newInsnList(); 390 391 insnList.add(newInsnList()); 392 393 assertEquals(0, insnList.size()); 394 assertEquals(null, insnList.getFirst()); 395 assertEquals(null, insnList.getLast()); 396 assertArrayEquals(new AbstractInsnNode[0], insnList.toArray()); 397 } 398 399 @Test testAddList_inEmptyList_nonEmptyList()400 void testAddList_inEmptyList_nonEmptyList() { 401 InsnList insnList = newInsnList(); 402 403 insnList.add(newInsnList(insn1, insn2)); 404 405 assertEquals(2, insnList.size()); 406 assertEquals(insn1, insnList.getFirst()); 407 assertEquals(insn2, insnList.getLast()); 408 assertEquals(insn1, insnList.get(0)); 409 assertTrue(insnList.contains(insn1)); 410 assertTrue(insnList.contains(insn2)); 411 assertEquals(0, insnList.indexOf(insn1)); 412 assertEquals(1, insnList.indexOf(insn2)); 413 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnList.toArray()); 414 } 415 416 @Test testAddList_inNonEmptyList_nonEmptyList()417 void testAddList_inNonEmptyList_nonEmptyList() { 418 InsnList insnList = newInsnList(); 419 InsnNode insn = new InsnNode(0); 420 insnList.add(insn); 421 422 insnList.add(newInsnList(insn1, insn2)); 423 424 assertEquals(3, insnList.size()); 425 assertEquals(insn, insnList.getFirst()); 426 assertEquals(insn2, insnList.getLast()); 427 assertEquals(insn, insnList.get(0)); 428 assertTrue(insnList.contains(insn)); 429 assertTrue(insnList.contains(insn1)); 430 assertTrue(insnList.contains(insn2)); 431 assertEquals(0, insnList.indexOf(insn)); 432 assertEquals(1, insnList.indexOf(insn1)); 433 assertEquals(2, insnList.indexOf(insn2)); 434 assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray()); 435 } 436 437 @Test testInsert_illegalArgument()438 void testInsert_illegalArgument() { 439 InsnList insnList = newInsnList(); 440 newInsnList(insn1, insn2); 441 442 Executable insert = () -> insnList.insert(insn1); 443 444 assertThrows(IllegalArgumentException.class, insert); 445 } 446 447 @Test testInsert_inEmptyList()448 void testInsert_inEmptyList() { 449 InsnList insnList = newInsnList(); 450 InsnNode insn = new InsnNode(0); 451 452 insnList.insert(insn); 453 454 assertEquals(1, insnList.size()); 455 assertEquals(insn, insnList.getFirst()); 456 assertEquals(insn, insnList.getLast()); 457 assertEquals(insn, insnList.get(0)); 458 assertTrue(insnList.contains(insn)); 459 assertEquals(0, insnList.indexOf(insn)); 460 assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray()); 461 } 462 463 @Test testInsert_inNonEmptyList()464 void testInsert_inNonEmptyList() { 465 InsnList insnList = newInsnList(); 466 InsnNode insn = new InsnNode(0); 467 insnList.add(new InsnNode(0)); 468 469 insnList.insert(insn); 470 471 assertEquals(2, insnList.size()); 472 assertEquals(insn, insnList.getFirst()); 473 assertEquals(insn, insnList.get(0)); 474 assertTrue(insnList.contains(insn)); 475 assertEquals(0, insnList.indexOf(insn)); 476 } 477 478 @Test testInsertList_illegalArgument()479 void testInsertList_illegalArgument() { 480 InsnList insnList = newInsnList(); 481 482 Executable insert = () -> insnList.insert(insnList); 483 484 assertThrows(IllegalArgumentException.class, insert); 485 } 486 487 @Test testInsertList_inEmptyList_emptyList()488 void testInsertList_inEmptyList_emptyList() { 489 InsnList insnList = newInsnList(); 490 491 insnList.insert(newInsnList()); 492 493 assertEquals(0, insnList.size()); 494 assertEquals(null, insnList.getFirst()); 495 assertEquals(null, insnList.getLast()); 496 assertArrayEquals(new AbstractInsnNode[0], insnList.toArray()); 497 } 498 499 @Test testInsertList_inEmptyList_nonEmptyList()500 void testInsertList_inEmptyList_nonEmptyList() { 501 InsnList insnList = newInsnList(); 502 503 insnList.insert(newInsnList(insn1, insn2)); 504 505 assertEquals(2, insnList.size(), 2); 506 assertEquals(insn1, insnList.getFirst()); 507 assertEquals(insn2, insnList.getLast()); 508 assertEquals(insn1, insnList.get(0)); 509 assertTrue(insnList.contains(insn1)); 510 assertTrue(insnList.contains(insn2)); 511 assertEquals(0, insnList.indexOf(insn1)); 512 assertEquals(1, insnList.indexOf(insn2)); 513 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2}, insnList.toArray()); 514 } 515 516 @Test testInsertList_inNonEmptyList_nonEmptyList()517 void testInsertList_inNonEmptyList_nonEmptyList() { 518 InsnList insnList = newInsnList(); 519 InsnNode insn = new InsnNode(0); 520 insnList.add(insn); 521 522 insnList.insert(newInsnList(insn1, insn2)); 523 524 assertEquals(3, insnList.size()); 525 assertEquals(insn1, insnList.getFirst()); 526 assertEquals(insn, insnList.getLast()); 527 assertEquals(insn1, insnList.get(0)); 528 assertTrue(insnList.contains(insn)); 529 assertTrue(insnList.contains(insn1)); 530 assertTrue(insnList.contains(insn2)); 531 assertEquals(0, insnList.indexOf(insn1)); 532 assertEquals(1, insnList.indexOf(insn2)); 533 assertEquals(2, insnList.indexOf(insn)); 534 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray()); 535 } 536 537 @Test testInsertAfter_noSuchElement()538 void testInsertAfter_noSuchElement() { 539 InsnList insnList = newInsnList(insn1, insn2); 540 541 Executable insert = () -> insnList.insert(new InsnNode(0), new InsnNode(0)); 542 543 assertThrows(NoSuchElementException.class, insert); 544 } 545 546 @Test testInsertAfter_lastInsn()547 void testInsertAfter_lastInsn() { 548 InsnList insnList = newInsnList(insn1, insn2); 549 InsnNode insn = new InsnNode(0); 550 551 insnList.insert(insn2, insn); 552 553 assertEquals(3, insnList.size()); 554 assertEquals(insn1, insnList.getFirst()); 555 assertEquals(insn, insnList.getLast()); 556 assertEquals(insn1, insnList.get(0)); 557 assertTrue(insnList.contains(insn)); 558 assertEquals(2, insnList.indexOf(insn)); 559 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray()); 560 } 561 562 @Test testInsertAfter_notLastInsn()563 void testInsertAfter_notLastInsn() { 564 InsnList insnList = newInsnList(insn1, insn2); 565 InsnNode insn = new InsnNode(0); 566 567 insnList.insert(insn1, insn); 568 569 assertEquals(3, insnList.size()); 570 assertEquals(insn1, insnList.getFirst()); 571 assertEquals(insn2, insnList.getLast()); 572 assertEquals(insn1, insnList.get(0)); 573 assertTrue(insnList.contains(insn)); 574 assertEquals(1, insnList.indexOf(insn)); 575 assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray()); 576 } 577 578 @Test testInsertListAfter_noSuchElement()579 void testInsertListAfter_noSuchElement() { 580 InsnList insnList = newInsnList(insn1, insn2); 581 582 Executable insert = () -> insnList.insert(new InsnNode(0), newInsnList()); 583 584 assertThrows(NoSuchElementException.class, insert); 585 } 586 587 @Test testInsertListAfter_lastInsn_emptyList()588 void testInsertListAfter_lastInsn_emptyList() { 589 InsnList insnList = newInsnList(); 590 InsnNode insn = new InsnNode(0); 591 insnList.add(insn); 592 593 insnList.insert(insn, newInsnList()); 594 595 assertEquals(1, insnList.size()); 596 assertEquals(insn, insnList.getFirst()); 597 assertEquals(insn, insnList.getLast()); 598 assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray()); 599 } 600 601 @Test testInsertListAfter_lastInsn_nonEmptyList()602 void testInsertListAfter_lastInsn_nonEmptyList() { 603 InsnList insnList = newInsnList(); 604 InsnNode insn = new InsnNode(0); 605 insnList.add(insn); 606 607 insnList.insert(insn, newInsnList(insn1, insn2)); 608 609 assertEquals(3, insnList.size()); 610 assertEquals(insn, insnList.getFirst()); 611 assertEquals(insn2, insnList.getLast()); 612 assertEquals(insn, insnList.get(0)); 613 assertTrue(insnList.contains(insn)); 614 assertTrue(insnList.contains(insn1)); 615 assertTrue(insnList.contains(insn2)); 616 assertEquals(0, insnList.indexOf(insn)); 617 assertEquals(1, insnList.indexOf(insn1)); 618 assertEquals(2, insnList.indexOf(insn2)); 619 assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray()); 620 } 621 622 @Test testInsertListAfter_notLastInsn_nonEmptyList()623 void testInsertListAfter_notLastInsn_nonEmptyList() { 624 InsnList insnList = newInsnList(); 625 InsnNode insn = new InsnNode(0); 626 insnList.add(insn); 627 insnList.add(new InsnNode(0)); 628 629 insnList.insert(insn, newInsnList(insn1, insn2)); 630 631 assertEquals(4, insnList.size()); 632 assertEquals(insn, insnList.getFirst()); 633 assertEquals(insn, insnList.get(0)); 634 assertTrue(insnList.contains(insn)); 635 assertTrue(insnList.contains(insn1)); 636 assertTrue(insnList.contains(insn2)); 637 assertEquals(0, insnList.indexOf(insn)); 638 assertEquals(1, insnList.indexOf(insn1)); 639 assertEquals(2, insnList.indexOf(insn2)); 640 } 641 642 @Test testInsertBefore_noSuchElement()643 void testInsertBefore_noSuchElement() { 644 InsnList insnList = newInsnList(insn1, insn2); 645 646 Executable insertBefore = () -> insnList.insertBefore(new InsnNode(0), new InsnNode(0)); 647 648 assertThrows(NoSuchElementException.class, insertBefore); 649 } 650 651 @Test testInsertBefore_firstInsn()652 void testInsertBefore_firstInsn() { 653 InsnList insnList = newInsnList(insn1, insn2); 654 InsnNode insn = new InsnNode(0); 655 656 insnList.insertBefore(insn1, insn); 657 658 assertEquals(3, insnList.size()); 659 assertEquals(insn, insnList.getFirst()); 660 assertEquals(insn2, insnList.getLast()); 661 assertEquals(insn, insnList.get(0)); 662 assertTrue(insnList.contains(insn)); 663 assertEquals(0, insnList.indexOf(insn)); 664 assertArrayEquals(new AbstractInsnNode[] {insn, insn1, insn2}, insnList.toArray()); 665 } 666 667 @Test testInsertBefore_notFirstInsn()668 void testInsertBefore_notFirstInsn() { 669 InsnList insnList = newInsnList(insn1, insn2); 670 InsnNode insn = new InsnNode(0); 671 672 insnList.insertBefore(insn2, insn); 673 674 assertEquals(3, insnList.size()); 675 assertEquals(insn1, insnList.getFirst()); 676 assertEquals(insn2, insnList.getLast()); 677 assertEquals(insn, insnList.get(1)); 678 assertTrue(insnList.contains(insn)); 679 assertEquals(1, insnList.indexOf(insn)); 680 assertArrayEquals(new AbstractInsnNode[] {insn1, insn, insn2}, insnList.toArray()); 681 } 682 683 @Test testInsertListBefore_noSuchElement()684 void testInsertListBefore_noSuchElement() { 685 InsnList insnList = newInsnList(insn1, insn2); 686 687 Executable insertBefore = () -> insnList.insertBefore(new InsnNode(0), newInsnList()); 688 689 assertThrows(NoSuchElementException.class, insertBefore); 690 } 691 692 @Test testInsertListBefore_firstInsn_emptyList()693 void testInsertListBefore_firstInsn_emptyList() { 694 InsnList insnList = newInsnList(); 695 InsnNode insn = new InsnNode(0); 696 insnList.add(insn); 697 698 insnList.insertBefore(insn, newInsnList()); 699 700 assertEquals(1, insnList.size()); 701 assertEquals(insn, insnList.getFirst()); 702 assertEquals(insn, insnList.getLast()); 703 assertArrayEquals(new AbstractInsnNode[] {insn}, insnList.toArray()); 704 } 705 706 @Test testInsertListBefore_firstInsn_nonEmptyList()707 void testInsertListBefore_firstInsn_nonEmptyList() { 708 InsnList insnList = newInsnList(); 709 InsnNode insn = new InsnNode(0); 710 insnList.add(insn); 711 712 insnList.insertBefore(insn, newInsnList(insn1, insn2)); 713 714 assertEquals(3, insnList.size()); 715 assertEquals(insn1, insnList.getFirst()); 716 assertEquals(insn, insnList.getLast()); 717 assertEquals(insn1, insnList.get(0)); 718 assertTrue(insnList.contains(insn)); 719 assertTrue(insnList.contains(insn1)); 720 assertTrue(insnList.contains(insn2)); 721 assertEquals(2, insnList.indexOf(insn)); 722 assertEquals(0, insnList.indexOf(insn1)); 723 assertEquals(1, insnList.indexOf(insn2)); 724 assertArrayEquals(new AbstractInsnNode[] {insn1, insn2, insn}, insnList.toArray()); 725 } 726 727 @Test testInsertListBefore_notFirstInsn_nonEmptyList()728 void testInsertListBefore_notFirstInsn_nonEmptyList() { 729 InsnList insnList = newInsnList(); 730 InsnNode insn = new InsnNode(0); 731 insnList.add(new InsnNode(0)); 732 insnList.add(insn); 733 734 insnList.insertBefore(insn, newInsnList(insn1, insn2)); 735 736 assertEquals(4, insnList.size()); 737 assertEquals(insn1, insnList.get(1)); 738 assertEquals(insn2, insnList.get(2)); 739 assertTrue(insnList.contains(insn)); 740 assertTrue(insnList.contains(insn1)); 741 assertTrue(insnList.contains(insn2)); 742 assertEquals(3, insnList.indexOf(insn)); 743 assertEquals(1, insnList.indexOf(insn1)); 744 assertEquals(2, insnList.indexOf(insn2)); 745 } 746 747 @Test testRemove_noSuchElement()748 void testRemove_noSuchElement() { 749 InsnList insnList = newInsnList(insn1, insn2); 750 751 Executable remove = () -> insnList.remove(new InsnNode(0)); 752 753 assertThrows(NoSuchElementException.class, remove); 754 } 755 756 @Test testRemove_singleInsn()757 void testRemove_singleInsn() { 758 InsnList insnList = newInsnList(); 759 InsnNode insn = new InsnNode(0); 760 insnList.add(insn); 761 762 insnList.remove(insn); 763 764 assertEquals(0, insnList.size()); 765 assertEquals(null, insnList.getFirst()); 766 assertEquals(null, insnList.getLast()); 767 assertFalse(insnList.contains(insn)); 768 assertArrayEquals(new AbstractInsnNode[0], insnList.toArray()); 769 assertEquals(null, insn.getPrevious()); 770 assertEquals(null, insn.getNext()); 771 } 772 773 @Test testRemove_firstInsn()774 void testRemove_firstInsn() { 775 InsnList insnList = newInsnList(); 776 InsnNode insn = new InsnNode(0); 777 insnList.add(insn); 778 insnList.add(new InsnNode(0)); 779 780 insnList.remove(insn); 781 782 assertFalse(insnList.contains(insn)); 783 assertEquals(null, insn.getPrevious()); 784 assertEquals(null, insn.getNext()); 785 } 786 787 @Test testRemove_middleInsn()788 void testRemove_middleInsn() { 789 InsnList insnList = newInsnList(); 790 InsnNode insn = new InsnNode(0); 791 insnList.add(new InsnNode(0)); 792 insnList.add(insn); 793 insnList.add(new InsnNode(0)); 794 795 insnList.remove(insn); 796 797 assertFalse(insnList.contains(insn)); 798 assertEquals(null, insn.getPrevious()); 799 assertEquals(null, insn.getNext()); 800 } 801 802 @Test testRemove_lastInsn()803 void testRemove_lastInsn() { 804 InsnList insnList = newInsnList(); 805 InsnNode insn = new InsnNode(0); 806 insnList.add(new InsnNode(0)); 807 insnList.add(insn); 808 809 insnList.remove(insn); 810 811 assertFalse(insnList.contains(insn)); 812 assertEquals(null, insn.getPrevious()); 813 assertEquals(null, insn.getNext()); 814 } 815 816 @Test testClear()817 void testClear() { 818 InsnList insnList = newInsnList(); 819 InsnNode insn = new InsnNode(0); 820 insnList.add(new InsnNode(0)); 821 insnList.add(insn); 822 insnList.add(new InsnNode(0)); 823 824 insnList.clear(); 825 826 assertEquals(0, insnList.size()); 827 assertEquals(null, insnList.getFirst()); 828 assertEquals(null, insnList.getLast()); 829 assertFalse(insnList.contains(insn)); 830 assertArrayEquals(new AbstractInsnNode[0], insnList.toArray()); 831 assertEquals(null, insn.getPrevious()); 832 assertEquals(null, insn.getNext()); 833 } 834 835 @Test testResetLabels()836 void testResetLabels() { 837 InsnList insnList = newInsnList(); 838 LabelNode labelNode = new LabelNode(); 839 insnList.add(new InsnNode(55)); 840 insnList.add(labelNode); 841 insnList.add(new InsnNode(77)); 842 Label label = labelNode.getLabel(); 843 844 insnList.resetLabels(); 845 846 assertNotNull(label); 847 assertNotSame(label, labelNode.getLabel()); 848 } 849 newInsnList()850 private static InsnList newInsnList() { 851 return new CheckedInsnList(); 852 } 853 newInsnList(final InsnNode insnNode1, final InsnNode insnNode2)854 private static InsnList newInsnList(final InsnNode insnNode1, final InsnNode insnNode2) { 855 InsnList insnList = new CheckedInsnList(); 856 insnList.add(insnNode1); 857 insnList.add(insnNode2); 858 return insnList; 859 } 860 861 /** An {@link InsnList} which checks that its methods are properly used. */ 862 static class CheckedInsnList extends InsnList { 863 864 @Override indexOf(final AbstractInsnNode insnNode)865 public int indexOf(final AbstractInsnNode insnNode) { 866 if (!contains(insnNode)) { 867 throw new NoSuchElementException(); 868 } 869 return super.indexOf(insnNode); 870 } 871 872 @Override set(final AbstractInsnNode oldInsnNode, final AbstractInsnNode newInsnNode)873 public void set(final AbstractInsnNode oldInsnNode, final AbstractInsnNode newInsnNode) { 874 if (!contains(oldInsnNode)) { 875 throw new NoSuchElementException(); 876 } 877 if (newInsnNode.index != -1) { 878 throw new IllegalArgumentException(); 879 } 880 super.set(oldInsnNode, newInsnNode); 881 } 882 883 @Override add(final AbstractInsnNode insnNode)884 public void add(final AbstractInsnNode insnNode) { 885 if (insnNode.index != -1) { 886 throw new IllegalArgumentException(); 887 } 888 super.add(insnNode); 889 } 890 891 @Override add(final InsnList insnList)892 public void add(final InsnList insnList) { 893 if (insnList == this) { 894 throw new IllegalArgumentException(); 895 } 896 super.add(insnList); 897 } 898 899 @Override insert(final AbstractInsnNode insnNode)900 public void insert(final AbstractInsnNode insnNode) { 901 if (insnNode.index != -1) { 902 throw new IllegalArgumentException(); 903 } 904 super.insert(insnNode); 905 } 906 907 @Override insert(final InsnList insnList)908 public void insert(final InsnList insnList) { 909 if (insnList == this) { 910 throw new IllegalArgumentException(); 911 } 912 super.insert(insnList); 913 } 914 915 @Override insert(final AbstractInsnNode previousInsn, final AbstractInsnNode insnNode)916 public void insert(final AbstractInsnNode previousInsn, final AbstractInsnNode insnNode) { 917 if (!contains(previousInsn)) { 918 throw new NoSuchElementException(); 919 } 920 if (insnNode.index != -1) { 921 throw new IllegalArgumentException(); 922 } 923 super.insert(previousInsn, insnNode); 924 } 925 926 @Override insert(final AbstractInsnNode previousInsn, final InsnList insnList)927 public void insert(final AbstractInsnNode previousInsn, final InsnList insnList) { 928 if (!contains(previousInsn)) { 929 throw new NoSuchElementException(); 930 } 931 if (insnList == this) { 932 throw new IllegalArgumentException(); 933 } 934 super.insert(previousInsn, insnList); 935 } 936 937 @Override insertBefore(final AbstractInsnNode nextInsn, final AbstractInsnNode insnNode)938 public void insertBefore(final AbstractInsnNode nextInsn, final AbstractInsnNode insnNode) { 939 if (!contains(nextInsn)) { 940 throw new NoSuchElementException(); 941 } 942 if (insnNode.index != -1) { 943 throw new IllegalArgumentException(); 944 } 945 super.insertBefore(nextInsn, insnNode); 946 } 947 948 @Override insertBefore(final AbstractInsnNode nextInsn, final InsnList insnList)949 public void insertBefore(final AbstractInsnNode nextInsn, final InsnList insnList) { 950 if (!contains(nextInsn)) { 951 throw new NoSuchElementException(); 952 } 953 if (insnList == this) { 954 throw new IllegalArgumentException(); 955 } 956 super.insertBefore(nextInsn, insnList); 957 } 958 959 @Override remove(final AbstractInsnNode insnNode)960 public void remove(final AbstractInsnNode insnNode) { 961 if (!contains(insnNode)) { 962 throw new NoSuchElementException(); 963 } 964 super.remove(insnNode); 965 } 966 967 @Override clear()968 public void clear() { 969 removeAll(true); 970 super.clear(); 971 } 972 } 973 } 974