1 30 package org.objectweb.asm.tree; 31 32 import java.util.ListIterator ; 33 34 import org.objectweb.asm.MethodVisitor; 35 36 40 public class InsnList { 41 42 49 public static boolean check; 50 51 54 private int size; 55 56 59 private AbstractInsnNode first; 60 61 64 private AbstractInsnNode last; 65 66 70 private AbstractInsnNode[] cache; 71 72 77 public int size() { 78 return size; 79 } 80 81 87 public AbstractInsnNode getFirst() { 88 return first; 89 } 90 91 97 public AbstractInsnNode getLast() { 98 return last; 99 } 100 101 111 public AbstractInsnNode get(final int index) { 112 if (index < 0 || index >= size) { 113 throw new IndexOutOfBoundsException (); 114 } 115 if (cache == null) { 116 cache = toArray(); 117 } 118 return cache[index]; 119 } 120 121 129 public boolean contains(final AbstractInsnNode insn) { 130 AbstractInsnNode i = first; 131 while (i != null && i != insn) { 132 i = i.next; 133 } 134 return i != null; 135 } 136 137 152 public int indexOf(final AbstractInsnNode insn) { 153 if (check && !contains(insn)) { 154 throw new IllegalArgumentException (); 155 } 156 if (cache == null) { 157 cache = toArray(); 158 } 159 return insn.index; 160 } 161 162 167 public void accept(final MethodVisitor mv) { 168 AbstractInsnNode insn = first; 169 while (insn != null) { 170 insn.accept(mv); 171 insn = insn.next; 172 } 173 } 174 175 180 public ListIterator iterator() { 181 return iterator(0); 182 } 183 184 189 public ListIterator iterator(int index) { 190 return new InsnListIterator(index); 191 } 192 193 198 public AbstractInsnNode[] toArray() { 199 int i = 0; 200 AbstractInsnNode elem = first; 201 AbstractInsnNode[] insns = new AbstractInsnNode[size]; 202 while (elem != null) { 203 insns[i] = elem; 204 elem.index = i++; 205 elem = elem.next; 206 } 207 return insns; 208 } 209 210 220 public void set(final AbstractInsnNode location, final AbstractInsnNode insn) { 221 if (check && !(contains(location) && insn.index == -1)) { 222 throw new IllegalArgumentException (); 223 } 224 AbstractInsnNode next = location.next; 225 insn.next = next; 226 if (next != null) { 227 next.prev = insn; 228 } else { 229 last = insn; 230 } 231 AbstractInsnNode prev = location.prev; 232 insn.prev = prev; 233 if (prev != null) { 234 prev.next = insn; 235 } else { 236 first = insn; 237 } 238 if (cache != null) { 239 int index = location.index; 240 cache[index] = insn; 241 insn.index = index; 242 } else { 243 insn.index = 0; } 245 location.index = -1; location.prev = null; 247 location.next = null; 248 } 249 250 258 public void add(final AbstractInsnNode insn) { 259 if (check && insn.index != -1) { 260 throw new IllegalArgumentException (); 261 } 262 ++size; 263 if (last == null) { 264 first = insn; 265 last = insn; 266 } else { 267 last.next = insn; 268 insn.prev = last; 269 } 270 last = insn; 271 cache = null; 272 insn.index = 0; } 274 275 282 public void add(final InsnList insns) { 283 if (check && insns == this) { 284 throw new IllegalArgumentException (); 285 } 286 if (insns.size == 0) { 287 return; 288 } 289 size += insns.size; 290 if (last == null) { 291 first = insns.first; 292 last = insns.last; 293 } else { 294 AbstractInsnNode elem = insns.first; 295 last.next = elem; 296 elem.prev = last; 297 last = insns.last; 298 } 299 cache = null; 300 insns.removeAll(false); 301 } 302 303 311 public void insert(final AbstractInsnNode insn) { 312 if (check && insn.index != -1) { 313 throw new IllegalArgumentException (); 314 } 315 ++size; 316 if (first == null) { 317 first = insn; 318 last = insn; 319 } else { 320 first.prev = insn; 321 insn.next = first; 322 } 323 first = insn; 324 cache = null; 325 insn.index = 0; } 327 328 335 public void insert(final InsnList insns) { 336 if (check && insns == this) { 337 throw new IllegalArgumentException (); 338 } 339 if (insns.size == 0) { 340 return; 341 } 342 size += insns.size; 343 if (first == null) { 344 first = insns.first; 345 last = insns.last; 346 } else { 347 AbstractInsnNode elem = insns.last; 348 first.prev = elem; 349 elem.next = first; 350 first = insns.first; 351 } 352 cache = null; 353 insns.removeAll(false); 354 } 355 356 367 public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) { 368 if (check && !(contains(location) && insn.index == -1)) { 369 throw new IllegalArgumentException (); 370 } 371 ++size; 372 AbstractInsnNode next = location.next; 373 if (next == null) { 374 last = insn; 375 } else { 376 next.prev = insn; 377 } 378 location.next = insn; 379 insn.next = next; 380 insn.prev = location; 381 cache = null; 382 insn.index = 0; } 384 385 395 public void insert(final AbstractInsnNode location, final InsnList insns) { 396 if (check && !(contains(location) && insns != this)) { 397 throw new IllegalArgumentException (); 398 } 399 if (insns.size == 0) { 400 return; 401 } 402 size += insns.size; 403 AbstractInsnNode ifirst = insns.first; 404 AbstractInsnNode ilast = insns.last; 405 AbstractInsnNode next = location.next; 406 if (next == null) { 407 last = ilast; 408 } else { 409 next.prev = ilast; 410 } 411 location.next = ifirst; 412 ilast.next = next; 413 ifirst.prev = location; 414 cache = null; 415 insns.removeAll(false); 416 } 417 418 429 public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) { 430 if (check && !(contains(location) && insn.index == -1)) { 431 throw new IllegalArgumentException (); 432 } 433 ++size; 434 AbstractInsnNode prev = location.prev; 435 if (prev == null) { 436 first = insn; 437 } else { 438 prev.next = insn; 439 } 440 location.prev = insn; 441 insn.next = location; 442 insn.prev = prev; 443 cache = null; 444 insn.index = 0; } 446 447 457 public void insertBefore(final AbstractInsnNode location, final InsnList insns) { 458 if (check && !(contains(location ) && insns != this)) { 459 throw new IllegalArgumentException (); 460 } 461 if (insns.size == 0) { 462 return; 463 } 464 size += insns.size; 465 AbstractInsnNode ifirst = insns.first; 466 AbstractInsnNode ilast = insns.last; 467 AbstractInsnNode prev = location .prev; 468 if (prev == null) { 469 first = ifirst; 470 } else { 471 prev.next = ifirst; 472 } 473 location .prev = ilast; 474 ilast.next = location ; 475 ifirst.prev = prev; 476 cache = null; 477 insns.removeAll(false); 478 } 479 480 481 482 489 public void remove(final AbstractInsnNode insn) { 490 if (check && !contains(insn)) { 491 throw new IllegalArgumentException (); 492 } 493 --size; 494 AbstractInsnNode next = insn.next; 495 AbstractInsnNode prev = insn.prev; 496 if (next == null) { 497 if (prev == null) { 498 first = null; 499 last = null; 500 } else { 501 prev.next = null; 502 last = prev; 503 } 504 } else { 505 if (prev == null) { 506 first = next; 507 next.prev = null; 508 } else { 509 prev.next = next; 510 next.prev = prev; 511 } 512 } 513 cache = null; 514 insn.index = -1; insn.prev = null; 516 insn.next = null; 517 } 518 519 525 private void removeAll(final boolean mark) { 526 if (mark) { 527 AbstractInsnNode insn = first; 528 while (insn != null) { 529 AbstractInsnNode next = insn.next; 530 insn.index = -1; insn.prev = null; 532 insn.next = null; 533 insn = next; 534 } 535 } 536 size = 0; 537 first = null; 538 last = null; 539 cache = null; 540 } 541 542 545 public void clear() { 546 removeAll(check); 547 } 548 549 550 private final class InsnListIterator implements ListIterator { 551 AbstractInsnNode next; 552 AbstractInsnNode prev; 553 554 public InsnListIterator(int index) { 555 if(index==size()) { 556 next = null; 557 prev = getLast(); 558 } else { 559 next = get(index); 560 prev = next.prev; 561 } 562 } 563 564 public boolean hasNext() { 565 return next != null; 566 } 567 568 public Object next() { 569 AbstractInsnNode result = next; 570 prev = result; 571 next = result.next; 572 return result; 573 } 574 575 public void remove() { 576 InsnList.this.remove(prev); 577 prev = prev.prev; 578 } 579 580 public boolean hasPrevious() { 581 return prev != null; 582 } 583 584 public Object previous() { 585 AbstractInsnNode result = prev; 586 next = result; 587 prev = result.prev; 588 return result; 589 } 590 591 public int nextIndex() { 592 if (next == null) { 593 return size(); 594 } 595 if (cache == null) { 596 cache = toArray(); 597 } 598 return next.index; 599 } 600 601 public int previousIndex() { 602 if (prev == null) { 603 return -1; 604 } 605 if (cache == null) { 606 cache = toArray(); 607 } 608 return prev.index; 609 } 610 611 public void add(Object o) { 612 InsnList.this.insertBefore(next, (AbstractInsnNode) o); 613 prev = (AbstractInsnNode) o; 614 } 615 616 public void set(Object o) { 617 InsnList.this.set(next.prev, (AbstractInsnNode) o); 618 prev = (AbstractInsnNode) o; 619 } 620 } 621 622 } 623 | Popular Tags |