All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.java.soot.jimple.toolkits.scalar.ToppedSet Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
/* 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.jimple.toolkits.scalar;

import soot.toolkits.scalar.*;
import java.util.*;

/** Represents information for flow analysis, adding a top element to a lattice.
 * A FlowSet is an element of a lattice; this lattice might be described by a FlowUniverse.
 * If add, remove, size, isEmpty, toList and contains are implemented, the lattice must be the powerset of some set.
 *
 */
public class ToppedSet extends AbstractFlowSet
{
    FlowSet underlyingSet;
    boolean isTop;

    public void setTop(boolean top) { isTop = top; }
    public boolean isTop() { return isTop; }

    public ToppedSet(FlowSet under)
    {
        underlyingSet = under;
    }

    public ToppedSet clone()
    {
        ToppedSet newSet = new ToppedSet(underlyingSet.clone());
        newSet.setTop(isTop());
        return newSet;
    }

    public void copy(FlowSet d)
    {
        ToppedSet dest = (ToppedSet)d;
        if (!isTop())
        {
            underlyingSet.copy(dest.underlyingSet);
            dest.setTop(false);
            return;
        }

        dest.setTop(true);
    }

    public Object emptySet()
    {
        return new ToppedSet((FlowSet)underlyingSet.emptySet());
    }

    public void clear()
    {
        isTop = false;
        underlyingSet.clear();
    }

    public void union(FlowSet o, FlowSet d)
    {
      if (o instanceof ToppedSet &&
          d instanceof ToppedSet) {
        ToppedSet other = (ToppedSet)o;
        ToppedSet dest = (ToppedSet)d;

        if (isTop())
        {
            copy(dest);
            return;
        }

        if (other.isTop())
            other.copy(dest);
        else
        {
            underlyingSet.union(other.underlyingSet, 
                                dest.underlyingSet);
            dest.setTop(false);
        }
      } else
        super.union(o, d);
    }

    public void intersection(FlowSet o, FlowSet d)
    {
        if (isTop())
        {
            o.copy(d);
            return;
        }

        ToppedSet other = (ToppedSet)o, dest = (ToppedSet)d;

        if (other.isTop())
        {
            copy(dest);
            return;
        }
        else
        {
            underlyingSet.intersection(other.underlyingSet, 
                                       dest.underlyingSet);
            dest.setTop(false);
        }
    }

    public void difference(FlowSet o, FlowSet d)
    {
      ToppedSet other = (ToppedSet)o, dest = (ToppedSet)d;

      if (isTop()) {
        if (other.isTop())
          dest.clear();
        else if (other.underlyingSet instanceof BoundedFlowSet)
          ((BoundedFlowSet)other.underlyingSet).complement(dest);
        else
          throw new RuntimeException("can't take difference!");
      } else {
        if (other.isTop())
          dest.clear();
        else
          underlyingSet.difference(other.underlyingSet, dest.underlyingSet);
      }
        /* not very helpful...
        if (isTop() && other.isTop())
          dest.clear();
        else if (isTop())
        if (!(other.underlyingSet instanceof BoundedFlowSet) &&
            othe
        if (other.underlyingSet instanceof BoundedFlowSet)
        {
            FlowSet temp = (FlowSet)other.underlyingSet.clone();
            ((BoundedFlowSet)other.underlyingSet).complement(temp);
            temp.union(temp, dest.underlyingSet);
            return;
        }
        throw new RuntimeException("can't take difference!");
        */
    }

    public boolean isEmpty()
    {
        if (isTop()) return false;
        return underlyingSet.isEmpty();
    }

    public int size()
    {
        if (isTop()) throw new UnsupportedOperationException();
        return underlyingSet.size();
    }

    public void add(Object obj)
    {
        if (isTop()) return;
        underlyingSet.add(obj);
    }

    public void remove(Object obj)
    {
        if (isTop()) return;
        underlyingSet.remove(obj);
    }

    public boolean contains(Object obj)
    {
        if (isTop()) return true;
        return underlyingSet.contains(obj);
    }

    public List toList()
    {
        if (isTop()) throw new UnsupportedOperationException();
        return underlyingSet.toList();
    }

    public boolean equals(Object o)
    {
        if (!(o instanceof ToppedSet))
            return false;

        ToppedSet other = (ToppedSet)o;
        if (other.isTop() != isTop())
            return false;
        return underlyingSet.equals(other.underlyingSet);
    }

    public String toString()
    {
        if (isTop()) return "{TOP}"; else return underlyingSet.toString();
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy