<commit_before>/* Soot - a J*va Optimization Framework
 * Copyright (C) 1997-1999 <NAME>
 *
 * 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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import soot.jimple.SpecialInvokeExpr;
import soot.util.ArraySet;
import soot.util.Chain;

/** Represents the class hierarchy.  It is closely linked to a Scene,
 * and must be recreated if the Scene changes. 
 *
 * The general convention is that if a method name contains 
 * "Including", then it returns the non-strict result; otherwise,
 * it does a strict query (e.g. strict superclass).  */
public class Hierarchy
{
    // These two maps are not filled in the constructor.
    Map<SootClass, List<SootClass>> classToSubclasses;
    Map<SootClass, List<SootClass>> interfaceToSubinterfaces;
    Map<SootClass, List<SootClass>> interfaceToSuperinterfaces;

    Map<SootClass, List<SootClass>> classToDirSubclasses;
    Map<SootClass, List<SootClass>> interfaceToDirSubinterfaces;
    Map<SootClass, List<SootClass>> interfaceToDirSuperinterfaces;

    // This holds the direct implementers.
    Map<SootClass, List<SootClass>> interfaceToDirImplementers;

    int state;
    Scene sc;

    /** Constructs a hierarchy from the current scene. */
    public Hierarchy()
    {
        this.sc = Scene.v();
        state = sc.getState();

        // Well, this used to be describable by 'Duh'.
        // Construct the subclasses hierarchy and the subinterfaces hierarchy.
        {
            Chain<SootClass> allClasses = sc.getClasses();

            classToSubclasses = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            interfaceToSubinterfaces = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            interfaceToSuperinterfaces = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            
            classToDirSubclasses = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirSubinterfaces = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirSuperinterfaces = new HashMap<SootClass, List<SootClass>>
            	(allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirImplementers = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            
            for (SootClass c : allClasses) {
                if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;

                if (c.isInterface())
                {
                    interfaceToDirSubinterfaces.put(c, new ArrayList<SootClass>());
                    interfaceToDirSuperinterfaces.put(c, new ArrayList<SootClass>());
                    interfaceToDirImplementers.put(c, new ArrayList<SootClass>());
                }
                else
                    classToDirSubclasses.put(c, new ArrayList<SootClass>());
            }

            for (SootClass c : allClasses) {
                if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                

                if (c.hasSuperclass()) {
                    if (c.isInterface()) {
                        List<SootClass> l2 = interfaceToDirSuperinterfaces.get(c);
                        for (SootClass i : c.getInterfaces()) {
                            if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                            List<SootClass> l = interfaceToDirSubinterfaces.get(i);
                            if (l != null) l.add(c);
                            if (l2 != null) l2.add(i);
                        }
                    }
                    else {
                        List<SootClass> l = classToDirSubclasses.get(c.getSuperclass());                        
                        if (l != null) l.add(c);

                        for (SootClass i : c.getInterfaces()) {
                            if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                            l = interfaceToDirImplementers.get(i);
                            if (l != null) l.add(c);
                        }
                    }
                }
            }

            // Fill the directImplementers lists with subclasses.
            for (SootClass c : allClasses) {
            	if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
            	if (c.isInterface()) {
            		List<SootClass> imp = interfaceToDirImplementers.get(c);
            		Set<SootClass> s = new ArraySet<SootClass>();            		
            		for (SootClass c0 : imp) {
            			if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
            			s.addAll(getSubclassesOfIncluding(c0));
            		}
            		imp.clear();
            		imp.addAll(s);
                }
            }

            for (SootClass c : allClasses) {
                if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;

                if (c.isInterface())
                {
                    interfaceToDirSubinterfaces.put(c, Collections.unmodifiableList
                    		(interfaceToDirSubinterfaces.get(c)));
                    interfaceToDirSuperinterfaces.put(c, Collections.unmodifiableList
                    		(interfaceToDirSuperinterfaces.get(c)));
                    interfaceToDirImplementers.put(c, Collections.unmodifiableList
                    		(interfaceToDirImplementers.get(c)));
                }
                else
                    classToDirSubclasses.put(c, Collections.unmodifiableList
                                          (classToDirSubclasses.get(c)));
            }
        }<commit_msg>removed an unnecessary double-nesting of unmodifiable collections<commit_after>/* Soot - a J*va Optimization Framework
 * Copyright (C) 1997-1999 <NAME>
 *
 * 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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import soot.jimple.SpecialInvokeExpr;
import soot.util.ArraySet;
import soot.util.Chain;

/** Represents the class hierarchy.  It is closely linked to a Scene,
 * and must be recreated if the Scene changes. 
 *
 * The general convention is that if a method name contains 
 * "Including", then it returns the non-strict result; otherwise,
 * it does a strict query (e.g. strict superclass).  */
public class Hierarchy
{
    // These two maps are not filled in the constructor.
    Map<SootClass, List<SootClass>> classToSubclasses;
    Map<SootClass, List<SootClass>> interfaceToSubinterfaces;
    Map<SootClass, List<SootClass>> interfaceToSuperinterfaces;

    Map<SootClass, List<SootClass>> classToDirSubclasses;
    Map<SootClass, List<SootClass>> interfaceToDirSubinterfaces;
    Map<SootClass, List<SootClass>> interfaceToDirSuperinterfaces;

    // This holds the direct implementers.
    Map<SootClass, List<SootClass>> interfaceToDirImplementers;

    int state;
    Scene sc;

    /** Constructs a hierarchy from the current scene. */
    public Hierarchy()
    {
        this.sc = Scene.v();
        state = sc.getState();

        // Well, this used to be describable by 'Duh'.
        // Construct the subclasses hierarchy and the subinterfaces hierarchy.
        {
            Chain<SootClass> allClasses = sc.getClasses();

            classToSubclasses = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            interfaceToSubinterfaces = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            interfaceToSuperinterfaces = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
            
            classToDirSubclasses = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirSubinterfaces = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirSuperinterfaces = new HashMap<SootClass, List<SootClass>>
            	(allClasses.size() * 2 + 1, 0.7f);
            interfaceToDirImplementers = new HashMap<SootClass, List<SootClass>>
                (allClasses.size() * 2 + 1, 0.7f);
            
            for (SootClass c : allClasses) {
                if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;

                if (c.isInterface())
                {
                    interfaceToDirSubinterfaces.put(c, new ArrayList<SootClass>());
                    interfaceToDirSuperinterfaces.put(c, new ArrayList<SootClass>());
                    interfaceToDirImplementers.put(c, new ArrayList<SootClass>());
                }
                else
                    classToDirSubclasses.put(c, new ArrayList<SootClass>());
            }

            for (SootClass c : allClasses) {
                if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                

                if (c.hasSuperclass()) {
                    if (c.isInterface()) {
                        List<SootClass> l2 = interfaceToDirSuperinterfaces.get(c);
                        for (SootClass i : c.getInterfaces()) {
                            if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                            List<SootClass> l = interfaceToDirSubinterfaces.get(i);
                            if (l != null) l.add(c);
                            if (l2 != null) l2.add(i);
                        }
                    }
                    else {
                        List<SootClass> l = classToDirSubclasses.get(c.getSuperclass());                        
                        if (l != null) l.add(c);

                        for (SootClass i : c.getInterfaces()) {
                            if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
                            l = interfaceToDirImplementers.get(i);
                            if (l != null) l.add(c);
                        }
                    }
                }
            }

            // Fill the directImplementers lists with subclasses.
            for (SootClass c : allClasses) {
            	if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
            	if (c.isInterface()) {
            		List<SootClass> imp = interfaceToDirImplementers.get(c);
            		Set<SootClass> s = new ArraySet<SootClass>();            		
            		for (SootClass c0 : imp) {
            			if( c.resolvingLevel() < SootClass.HIERARCHY ) continue;
            			s.addAll(getSubclassesOfIncluding(c0));
            		}
            		imp.clear();
            		imp.addAll(s);
                }
            }
        }
{'fraction_non_alphanumeric': 0.09510108864696734, 'fraction_numerical': 0.01010886469673406, 'mean_word_length': 1.9722671596949388, 'pattern_counts': {'":': 0, '<': 96, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6504412', 'n_tokens_mistral': 3714, 'n_tokens_neox': 3506, 'n_words': 957}