com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil.java

Source

/******************************************************************************
 * Copyright (c) 2002 - 2006 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *****************************************************************************/
package com.ibm.wala.cast.ipa.callgraph;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;

import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.input.BOMInputStream;

import com.ibm.wala.cast.loader.SingleClassLoaderFactory;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.classLoader.SourceFileModule;
import com.ibm.wala.classLoader.SourceModule;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.IRFactory;
import com.ibm.wala.util.debug.Assertions;

public class CAstCallGraphUtil {

    /**
     * flag to prevent dumping of verbose call graph / pointer analysis output
     */
    public static boolean AVOID_DUMP = true;

    public static SourceFileModule makeSourceModule(URL script, String dir, String name) {
        // DO NOT use File.separator here, since this name is matched against
        // URLs. It seems that, in DOS, URL.getFile() does not return a
        // \-separated file name, but rather one with /'s. Rather makes one
        // wonder why the function is called get_File_ :(
        return makeSourceModule(script, dir + "/" + name);
    }

    public static SourceFileModule makeSourceModule(URL script, String scriptName) {
        String hackedName = script.getFile().replaceAll("%5c", "/").replaceAll("%20", " ");

        File scriptFile = new File(hackedName);

        assert hackedName.endsWith(scriptName) : scriptName + " does not match file " + script.getFile();

        return new SourceFileModule(scriptFile, scriptName, null) {
            @Override
            public InputStream getInputStream() {
                BOMInputStream bs = new BOMInputStream(super.getInputStream(), false, ByteOrderMark.UTF_8,
                        ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE,
                        ByteOrderMark.UTF_32BE);
                try {
                    if (bs.hasBOM()) {
                        System.err.println("removing BOM " + bs.getBOM());
                    }
                    return bs;
                } catch (IOException e) {
                    return super.getInputStream();
                }
            }
        };
    }

    public static AnalysisScope makeScope(String[] files, SingleClassLoaderFactory loaders, Language language)
            throws IOException {
        CAstAnalysisScope result = new CAstAnalysisScope(files, loaders, Collections.singleton(language));
        return result;
    }

    public static AnalysisScope makeScope(SourceModule[] files, SingleClassLoaderFactory loaders, Language language)
            throws IOException {
        CAstAnalysisScope result = new CAstAnalysisScope(files, loaders, Collections.singleton(language));
        return result;
    }

    public static AnalysisCache makeCache(IRFactory<IMethod> factory) {
        return new AnalysisCache(factory);
    }

    public static String getShortName(CGNode nd) {
        IMethod method = nd.getMethod();
        return getShortName(method);
    }

    public static String getShortName(IMethod method) {
        String origName = method.getName().toString();
        String result = origName;
        if (origName.equals("do") || origName.equals("ctor")) {
            result = method.getDeclaringClass().getName().toString();
            result = result.substring(result.lastIndexOf('/') + 1);
            if (origName.equals("ctor")) {
                if (result.equals("LFunction")) {
                    String s = method.toString();
                    if (s.indexOf('(') != -1) {
                        String functionName = s.substring(s.indexOf('(') + 1, s.indexOf(')'));
                        functionName = functionName.substring(functionName.lastIndexOf('/') + 1);
                        result += " " + functionName;
                    }
                }
                result = "ctor of " + result;
            }
        }
        return result;
    }

    public static void dumpCG(PointerAnalysis<InstanceKey> PA, CallGraph CG) {
        if (AVOID_DUMP)
            return;
        for (Iterator x = CG.iterator(); x.hasNext();) {
            CGNode N = (CGNode) x.next();
            System.err.print("callees of node " + getShortName(N) + " : [");
            boolean fst = true;
            for (Iterator<? extends CGNode> ns = CG.getSuccNodes(N); ns.hasNext();) {
                if (fst)
                    fst = false;
                else
                    System.err.print(", ");
                System.err.print(getShortName(ns.next()));
            }
            System.err.println("]");
            System.err.println("\nIR of node " + N.getGraphNodeId() + ", context " + N.getContext());
            IR ir = N.getIR();
            if (ir != null) {
                System.err.println(ir);
            } else {
                System.err.println("no IR!");
            }
        }

        System.err.println("pointer analysis");
        for (Iterator x = PA.getPointerKeys().iterator(); x.hasNext();) {
            PointerKey n = (PointerKey) x.next();
            try {
                System.err.println((n + " --> " + PA.getPointsToSet(n)));
            } catch (Throwable e) {
                System.err.println(("error computing set for " + n));
            }
        }
    }

    public static SourceFileModule[] handleFileNames(String[] fileNameArgs) {
        SourceFileModule[] fileNames = new SourceFileModule[fileNameArgs.length];
        for (int i = 0; i < fileNameArgs.length; i++) {
            if (new File(fileNameArgs[i]).exists()) {
                try {
                    fileNames[i] = CAstCallGraphUtil.makeSourceModule(new File(fileNameArgs[i]).toURI().toURL(),
                            fileNameArgs[i]);
                } catch (MalformedURLException e) {
                    Assertions.UNREACHABLE(e.toString());
                }
            } else {
                URL url = CAstCallGraphUtil.class.getClassLoader().getResource(fileNameArgs[i]);
                fileNames[i] = CAstCallGraphUtil.makeSourceModule(url, fileNameArgs[i]);
            }
        }

        return fileNames;
    }

}