Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 2000 Patrice Pominville
   * Copyright (C) 2004 Ondrej Lhotak, Ganesh Sittampalam
   *
   * 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 soot.options.*;
 
 import java.util.*;



Loads symbols for SootClasses from either class files or jimple files.
 
 public class SootResolver 
 {
    
Maps each resolved class to a list of all references in it.
 
     private final Map<SootClassArrayListclassToTypesSignature = new HashMap<SootClassArrayList>();

    
Maps each resolved class to a list of all references in it.
 
     private final Map<SootClassArrayListclassToTypesHierarchy = new HashMap<SootClassArrayList>();

    
SootClasses waiting to be resolved.
 
     private final LinkedList/*SootClass*/[] worklist = new LinkedList[4];
 
 
     public SootResolver (Singletons.Global g) {
         [.] = new LinkedList();
         [.] = new LinkedList();
         [.] = new LinkedList();
         
         
     }
 
     public static SootResolver v() { return G.v().soot_SootResolver();}
    
    
Returns true if we are resolving all class refs recursively.
 
     private boolean resolveEverything() {
         return( Options.v().whole_program() || Options.v().whole_shimple()
 	|| Options.v().full_resolver() 
 	|| Options.v().output_format() == . );
     }

    
Returns a (possibly not yet resolved) SootClass to be used in references to a class. If/when the class is resolved, it will be resolved into this SootClass.
 
     public SootClass makeClassRef(String className)
     {
         if(Scene.v().containsClass(className))
             return Scene.v().getSootClass(className);
 
         SootClass newClass;
         newClass = new SootClass(className);
         newClass.setResolvingLevel(.);
         Scene.v().addClass(newClass);
 
         return newClass;
     }


    
Resolves the given class. Depending on the resolver settings, may decide to resolve other classes as well. If the class has already been resolved, just returns the class that was already resolved.
 
     public SootClass resolveClass(String classNameint desiredLevel) {
         SootClass resolvedClass = makeClassRef(className);
         addToResolveWorklist(resolvedClassdesiredLevel);
         processResolveWorklist();
         return resolvedClass;
     }

    
Resolve all classes on toResolveWorklist.
 
     private void processResolveWorklist() {
        forint i = .i >= .i-- ) {
            while( ![i].isEmpty() ) {
                SootClass sc = (SootClass[i].removeFirst();
                ifresolveEverything() ) {
                    boolean onlySignatures = sc.isPhantom() || (
	            			Options.v().no_bodies_for_excluded() &&
	            			Scene.v().isExcluded(sc) &&
	            			!Scene.v().getBasicClasses().contains(sc.getName())
            			);
					ifonlySignatures ) {
				        if(sc.isPhantom()) {
				        	forSootMethod msc.getMethods() ) {
				        		m.setPhantom(true);
				        	}
				        	forSootField fsc.getFields() ) {
				        		f.setPhantom(true);
				        	}
				        }
			        } else bringToBodies(sc);
                } else {
                    switch(i) {
                        case .bringToBodies(sc); break;
                        case .bringToSignatures(sc); break;
                        case .bringToHierarchy(sc); break;
                    }
                }
            }
        }
    }
    private void addToResolveWorklist(Type typeint level) {
        iftype instanceof RefType )
            addToResolveWorklist(((RefTypetype).getClassName(), level);
        else iftype instanceof ArrayType )
            addToResolveWorklist(((ArrayTypetype).level);
    }
    private void addToResolveWorklist(String classNameint level) {
        addToResolveWorklist(makeClassRef(className), level);
    }
    private void addToResolveWorklist(SootClass scint desiredLevel) {
        ifsc.resolvingLevel() >= desiredLevel ) return;
        [desiredLevel].add(sc);
    }

    
Hierarchy - we know the hierarchy of the class and that's it requires at least Hierarchy for all supertypes and enclosing types.
    // RoboVM note: Made this method public
    public void bringToHierarchy(SootClass sc) {
        if(sc.resolvingLevel() >= . ) return;
        if(Options.v().debug_resolver())
            G.v()..println("bringing to HIERARCHY: "+sc);
        String className = sc.getName();
        ClassSource is = SourceLocator.v().getClassSource(className);
        boolean modelAsPhantomRef = is == null;
//        || (
//        		Options.v().no_jrl() &&
//        		Scene.v().isExcluded(sc) &&
//        		!Scene.v().getBasicClasses().contains(sc.getName())
//    		);        
		ifmodelAsPhantomRef ) {
            if(!Scene.v().allowsPhantomRefs()) {
            	String suffix="";
            	if(className.equals("java.lang.Object")) {
            		suffix = " Try adding rt.jar to Soot's classpath, e.g.:\n" +
            				"java -cp sootclasses.jar soot.Main -cp " +
            				".:/path/to/jdk/jre/lib/rt.jar <other options>";
            	} else if(className.equals("javax.crypto.Cipher")) {
            		suffix = " Try adding jce.jar to Soot's classpath, e.g.:\n" +
            				"java -cp sootclasses.jar soot.Main -cp " +
            				".:/path/to/jdk/jre/lib/rt.jar:/path/to/jdk/jre/lib/jce.jar <other options>";
            	}
                throw new RuntimeException("couldn't find class: " +
                    className + " (is your soot-class-path set properly?)"+suffix);
            } else {
                G.v()..println(
                        "Warning: " + className + " is a phantom class!");
                sc.setPhantomClass();
                .putscnew ArrayList() );
                .putscnew ArrayList() );
            }
        } else {
            Dependencies dependencies = is.resolve(sc);
            .putscnew ArrayList(dependencies.typesToSignature) );
            .putscnew ArrayList(dependencies.typesToHierarchy) );
        }
        reResolveHierarchy(sc);
    }
    public void reResolveHierarchy(SootClass sc) {
        // Bring superclasses to hierarchy
        if(sc.hasSuperclass()) 
            addToResolveWorklist(sc.getSuperclass(), .);
        if(sc.hasOuterClass()) 
            addToResolveWorklist(sc.getOuterClass(), .);
        forIterator ifaceIt = sc.getInterfaces().iterator(); ifaceIt.hasNext(); ) {
            final SootClass iface = (SootClassifaceIt.next();
            addToResolveWorklist(iface.);
        }
    }

    
Signatures - we know the signatures of all methods and fields requires at least Hierarchy for all referred to types in these signatures.
    // RoboVM note: Made this method public
    public void bringToSignatures(SootClass sc) {
        if(sc.resolvingLevel() >= . ) return;
        bringToHierarchy(sc);
        if(Options.v().debug_resolver()) 
            G.v()..println("bringing to SIGNATURES: "+sc);
        forIterator fIt = sc.getFields().iterator(); fIt.hasNext(); ) {
            final SootField f = (SootFieldfIt.next();
            addToResolveWorklistf.getType(), . );
        }
        forIterator mIt = sc.getMethods().iterator(); mIt.hasNext(); ) {
            final SootMethod m = (SootMethodmIt.next();
            addToResolveWorklistm.getReturnType(), . );
            forIterator ptypeIt = m.getParameterTypes().iterator(); ptypeIt.hasNext(); ) {
                final Type ptype = (TypeptypeIt.next();
                addToResolveWorklistptype. );
            }
            for (SootClass exception : m.getExceptions()) {
                addToResolveWorklistexception. );
            }
        }
        // Bring superclasses to signatures
        if(sc.hasSuperclass()) 
        forIterator ifaceIt = sc.getInterfaces().iterator(); ifaceIt.hasNext(); ) {
            final SootClass iface = (SootClassifaceIt.next();
            addToResolveWorklist(iface.);
        }
    }

    
Bodies - we can now start loading the bodies of methods for all referred to methods and fields in the bodies, requires signatures for the method receiver and field container, and hierarchy for all other classes referenced in method references. Current implementation does not distinguish between the receiver and other references. Therefore, it is conservative and brings all of them to signatures. But this could/should be improved.
    private void bringToBodies(SootClass sc) {
        if(sc.resolvingLevel() >= . ) return;
        bringToSignatures(sc);
        if(Options.v().debug_resolver()) 
            G.v()..println("bringing to BODIES: "+sc);
        {
        	Collection references = .get(sc);
            ifreferences == null ) return;
            Iterator it = references.iterator();
            whileit.hasNext() ) {
                final Object o = it.next();
                ifo instanceof String ) {
                    addToResolveWorklist((Stringo.);
                } else ifo instanceof Type ) {
                    addToResolveWorklist((Typeo.);
                } else throw new RuntimeException(o.toString());
            }
        }
        {
        	Collection references = .get(sc);
            ifreferences == null ) return;
            Iterator it = references.iterator();
            whileit.hasNext() ) {
                final Object o = it.next();
                ifo instanceof String ) {
                    addToResolveWorklist((Stringo.);
                } else ifo instanceof Type ) {
                    addToResolveWorklist((Typeo.);
                } else throw new RuntimeException(o.toString());
            }
        }
    }
    public void reResolve(SootClass cl) {
        int resolvingLevel = cl.resolvingLevel();
        ifresolvingLevel < . ) return;
        reResolveHierarchy(cl);
        addToResolveWorklist(clresolvingLevel);
        processResolveWorklist();
    }
New to GrepCode? Check out our FAQ X