Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 1997-1999 Raja Vallee-Rai
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 /*
  * Modified by the Sable Research Group and others 1997-1999.  
  * See the 'credits' file distributed with Soot for the complete list of
  * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
  */
 
 package soot;
 
 import java.util.List;
 
An implementation of a Chain which can contain only Units, and handles patching to deal with element insertions and removals. This is done by calling Unit.redirectJumpsToThisTo at strategic times.
 
 public class PatchingChain<E extends Unitextends AbstractCollection<E> implements Chain<E> 
 {
     protected Chain<E> innerChain;

    
Constructs a PatchingChain from the given Chain.
 
     public PatchingChain(Chain<E> aChain)
     {
          = aChain;
     }

    
Returns the inner chain used by the PatchingChain. In general, this should not be used. However, direct access to the inner chain may be necessary if you wish to perform certain operations (such as control-flow manipulations) without interference from the patching algorithms.
 
     public Chain<E> getNonPatchingChain()
     {
         return ;
     }
    
    
Adds the given object to this Chain.
 
     public boolean add(E o)
     {
         return .add(o);
     }

    
Replaces out in the Chain by in.
 
     public void swapWith(E out, E in)
     {
         insertBefore(inout);
         remove(out);
     }

    
Inserts toInsert in the Chain after point.
 
     public void insertAfter(E toInsert, E point)
     {
         .insertAfter(toInsertpoint);
     }

    
Inserts toInsert in the Chain after point.
 
     public void insertAfter(List<E> toInsert, E point)
     {
         .insertAfter(toInsertpoint);
     }
     
     public void insertAfter(Chain<E> toInsert, E point)
     {
         .insertAfter(toInsertpoint);
     }

    
Inserts toInsert in the Chain before point.
 
     public void insertBefore(List<E> toInsert, E point)
     {
         LinkedList<E> backwardList = new LinkedList<E>();
         // Insert toInsert backwards into the list
         {
             Iterator<E> it = toInsert.iterator();
             
            while(it.hasNext())
                backwardList.addFirst(it.next());
        }
                
        E previousPoint = point;
        Iterator<E> it = backwardList.iterator();
        while (it.hasNext())
        {
            E o = it.next();
            insertBeforeNoRedirect(opreviousPoint);
            previousPoint = o;
        }
        point.redirectJumpsToThisTo(toInsert.get(0));
    }
    
    
Inserts toInsert in the Chain before point.
    public void insertBefore(Chain<E> toInsert, E point)
    {
        LinkedList<E> backwardList = new LinkedList<E>();
        // Insert toInsert backwards into the list
        {
            Iterator<E> it = toInsert.iterator();
            
            while(it.hasNext())
                backwardList.addFirst(it.next());
        }
                
        E previousPoint = point;
        Iterator<E> it = backwardList.iterator();
        while (it.hasNext())
        {
            E o = it.next();
            insertBefore(opreviousPoint);
            previousPoint = o;
        }
    }

    
Inserts toInsert in the Chain before point.
    public void insertBefore(E toInsert, E point)
    {
        point.redirectJumpsToThisTo(toInsert);
        .insertBefore(toInsertpoint);
    }
    
    
Inserts toInsert in the Chain before point WITHOUT redirecting jumps.
    public void insertBeforeNoRedirect(E toInsert, E point)
    {
        .insertBefore(toInsertpoint);
    }

    
Returns true if object a follows object b in the Chain.
    public boolean follows(E a, E b)
    {
        return .follows(a,b);
    }

    
Removes the given object from this Chain.
    @SuppressWarnings("unchecked")
    public boolean remove(Object obj)
    {
        boolean res = false;
        if(contains(obj))
        {
            Unit successor;
            
            if((successor = getSuccOf((E) obj)) == null)
                successor = getPredOf((E) obj); 
		// Note that redirecting to the last unit in the method 
		// like this is probably incorrect when dealing with a Trap.
	        // I.e., let's say that the final unit in the method used to
	        // be U10, preceded by U9, and that there was a Trap which
	        // returned U10 as getEndUnit(). I.e., before the trap covered U9.
	        // When we redirect the Trap's end unit to U9, the trap will no
	        // longer cover U9. I know this is incorrect, but I'm not sure how
	        // to fix it, so I'm leaving this comment in the hopes that some
	        // future maintainer will see the right course to take.
            
            res = .remove(obj);
            ((E)obj).redirectJumpsToThisTo(successor);
        }
        return res;        
    }

    
Returns true if this patching chain contains the specified element.
    public boolean contains(Object u)
    {
        return .contains(u);
    }

    
Adds the given object at the beginning of the Chain.
    public void addFirst(E u)
    {
        .addFirst(u);
    }
    
    
Adds the given object at the end of the Chain.
    public void addLast(E u)
    {
        .addLast(u);
    }
    
    
Removes the first object from this Chain.
    public void removeFirst() 
    {
        remove(.getFirst());
    }
    
    
Removes the last object from this Chain.
    public void removeLast()
    {
        remove(.getLast());
    }
    
    
Returns the first object in this Chain.
    public E getFirst() { return .getFirst(); }

    
Returns the last object in this Chain.
    public E getLast() { return .getLast(); }
    
    
Returns the object immediately following point.
    public E getSuccOf(E point){return .getSuccOf(point);}

    
Returns the object immediately preceding point.
    public E getPredOf(E point){return .getPredOf(point);}
    protected class PatchingIterator implements Iterator<E>
    {
        protected Iterator<E> innerIterator = null;
        protected E lastObject;
        protected boolean state = false;
        protected PatchingIterator (Chain<E> innerChain) {  = innerChain.iterator(); }
        protected PatchingIterator (Chain<E> innerChain, E u) {  = innerChain.iterator(u); }
        protected PatchingIterator (Chain<E> innerChain, E head, E tail) {  = innerChain.iterator(headtail); }
        public boolean hasNext() { return .hasNext(); }
        public E next() {  = .next();  = truereturn ; }
        public void remove() 
        { 
            if (!)
                throw new IllegalStateException("remove called before first next() call");
            Unit successor;
            
              if((successor = getSuccOf()) == null)
		  successor = getPredOf();
		  // Note that redirecting to the last unit in the method 
		  // like this is probably incorrect when dealing with a Trap.
		  // I.e., let's say that the final unit in the method used to
		  // be U10, preceded by U9, and that there was a Trap which
		  // returned U10 as getEndUnit(). I.e., before the trap covered U9.
		  // When we redirect the Trap's end unit to U9, the trap will no
		  // longer cover U9. I know this is incorrect, but I'm not sure how
		  // to fix it, so I'm leaving this comment in the hopes that some
		  // future maintainer will see the right course to take.
            
            .remove();
            .redirectJumpsToThisTo(successor);
        }
    }

    
Returns an iterator over a copy of this chain. This avoids ConcurrentModificationExceptions from being thrown if the underlying Chain is modified during iteration. Do not use this to remove elements which have not yet been iterated over!
    public Iterator<E> snapshotIterator() 
    {
        List<E> l = new ArrayList<E>(); l.addAll(this);
        return l.iterator();
    }
   
    
Returns an iterator over this Chain.
    public Iterator<E> iterator() { return new PatchingIterator(); }

    
Returns an iterator over this Chain, starting at the given object.
    public Iterator<E> iterator(E u) { return new PatchingIterator(u); }

    
Returns an iterator over this Chain, starting at head and reaching tail (inclusive).
    public Iterator<E> iterator(E head, E tail) { return new PatchingIterator(headtail); }

    
Returns the size of this Chain.
    public int size(){return .size(); }
New to GrepCode? Check out our FAQ X