/******************************************************************************* * 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.shrike.bench; import java.io.BufferedWriter; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import com.ibm.wala.shrikeBT.Constants; import com.ibm.wala.shrikeBT.Util; import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; import com.ibm.wala.shrikeCT.ClassReader; /** * @author roca */ public class InterfaceAnalyzer { final static class TypeStats { int totalOccurrences; int methodOccurrences; int publicMethodOccurrences; int foreignPublicMethodOccurrences; int lastMUID; } final static HashMap<String, TypeStats> typeStats = new HashMap<String, TypeStats>(); public static void main(String[] args) throws Exception { OfflineInstrumenter instrumenter = new OfflineInstrumenter(true); Writer w = new BufferedWriter(new OutputStreamWriter(System.out)); args = instrumenter.parseStandardArgs(args); instrumenter.beginTraversal(); ClassInstrumenter ci; while ((ci = instrumenter.nextClass()) != null) { doClass(ci.getReader()); } instrumenter.close(); w.write("Type\t# Total\t# Method\t# Public Method\t# Public Method as Foreign\n"); for (Iterator<String> i = typeStats.keySet().iterator(); i.hasNext();) { String k = i.next(); TypeStats t = typeStats.get(k); w.write(k + "\t" + t.totalOccurrences + "\t" + t.methodOccurrences + "\t" + t.publicMethodOccurrences + "\t" + t.foreignPublicMethodOccurrences + "\n"); } w.close(); } static int methodUID = 0; /** * @param reader */ private static void doClass(ClassReader reader) throws Exception { if ((reader.getAccessFlags() & Constants.ACC_INTERFACE) != 0 && (reader.getAccessFlags() & Constants.ACC_PUBLIC) != 0) { String cType = Util.makeType(reader.getName()); for (int m = 0; m < reader.getMethodCount(); m++) { String sig = reader.getMethodType(m); String[] params = Util.getParamsTypes(null, sig); int flags = reader.getMethodAccessFlags(m); int mUID = methodUID++; for (int p = 0; p < params.length; p++) { doType(flags, params[p], cType, mUID); } doType(flags, Util.getReturnType(sig), cType, mUID); } } } private static void doType(int flags, String type, String containerType, int mUID) { TypeStats t = typeStats.get(type); if (t == null) { t = new TypeStats(); typeStats.put(type, t); } t.totalOccurrences++; if (t.lastMUID != mUID) { t.methodOccurrences++; if ((flags & Constants.ACC_PUBLIC) != 0) { t.publicMethodOccurrences++; String elemType = type; while (Util.isArrayType(elemType)) { elemType = elemType.substring(1); } if (!Util.isPrimitiveType(elemType) && !packagePart(elemType, 2).equals(packagePart(containerType, 2))) { t.foreignPublicMethodOccurrences++; } } } t.lastMUID = mUID; } private static String packagePart(String t, int count) { String c = Util.makeClass(t); int lastDot = -1; for (int i = 0; i < count; i++) { int dot = c.indexOf('.', lastDot + 1); if (dot < 0) { return c; } lastDot = dot; } return c.substring(0, lastDot); } }