Prune constructor and method signatures after removing unused fields

Removing an unused field sometimes means removing constructor code
that used to initialize that field.  Removing that initialization code
sometimes leaves whole constructor arguments unused.  Removing those
unused arguments can leave us with unused code to compute those
arguments in constructors' callers, and so on.  This commit tries to
clean all of this up, working backward from the unused fields that an
earlier commit already removed.  Hopefully I have avoided removing
upstream code that had other important side effects, but it wouldn't
hurt for a WALA expert to review this change carefully.
This commit is contained in:
Ben Liblit 2017-03-25 17:18:27 -05:00
parent b4e5d078dd
commit 42c7866dfd
30 changed files with 46 additions and 59 deletions

View File

@ -288,7 +288,7 @@ public abstract class JDTJava2CAstTranslator<T extends Position> {
private final T fSourcePosition;
public ClassEntity(ITypeBinding jdtType, String name, Collection<CAstQualifier> quals, Collection<CAstEntity> entities,
T pos, Set<CAstAnnotation> annotations) {
T pos) {
fName = name;
fQuals = quals;
fEntities = entities;
@ -531,9 +531,7 @@ public abstract class JDTJava2CAstTranslator<T extends Position> {
Collection<CAstQualifier> quals = JDT2CAstUtils.mapModifiersToQualifiers(modifiers, isInterface, isAnnotation);
Set<CAstAnnotation> annotations = handleAnnotations(typeBinding);
return new ClassEntity(typeBinding, name, quals, memberEntities, makePosition(n), annotations);
return new ClassEntity(typeBinding, name, quals, memberEntities, makePosition(n));
}
private CAstEntity visit(AnonymousClassDeclaration n, WalkContext context) {

View File

@ -91,7 +91,7 @@ public abstract class FieldBasedCallGraphBuilder {
private MethodTargetSelector setupMethodTargetSelector(IClassHierarchy cha, JavaScriptConstructorFunctions constructors2, AnalysisOptions options) {
MethodTargetSelector result = new JavaScriptConstructTargetSelector(constructors2, options.getMethodTargetSelector());
if (options instanceof JSAnalysisOptions && ((JSAnalysisOptions)options).handleCallApply()) {
result = new JavaScriptFunctionApplyTargetSelector(new JavaScriptFunctionDotCallTargetSelector(result, cache));
result = new JavaScriptFunctionApplyTargetSelector(new JavaScriptFunctionDotCallTargetSelector(result));
}
return result;
}

View File

@ -38,7 +38,7 @@ public class JSZeroOrOneXCFABuilder extends JSCFABuilder {
SSAContextInterpreter contextInterpreter = setupSSAContextInterpreter(cha, options, cache, appContextInterpreter);
setupMethodTargetSelector(cha, options, cache);
setupMethodTargetSelector(cha, options);
setupContextSelector(options, appContextSelector, doOneCFA);
@ -71,11 +71,11 @@ public class JSZeroOrOneXCFABuilder extends JSCFABuilder {
}
private void setupMethodTargetSelector(IClassHierarchy cha, JSAnalysisOptions options, IAnalysisCacheView cache) {
private void setupMethodTargetSelector(IClassHierarchy cha, JSAnalysisOptions options) {
MethodTargetSelector targetSelector = new JavaScriptConstructTargetSelector(cha, options
.getMethodTargetSelector());
if (options.handleCallApply()) {
targetSelector = new JavaScriptFunctionApplyTargetSelector(new JavaScriptFunctionDotCallTargetSelector(targetSelector, cache));
targetSelector = new JavaScriptFunctionApplyTargetSelector(new JavaScriptFunctionDotCallTargetSelector(targetSelector));
}
if (options.useLoadFileTargetSelector()) {
targetSelector = new LoadFileTargetSelector(targetSelector, this);

View File

@ -62,7 +62,7 @@ public class JavaScriptFunctionDotCallTargetSelector implements MethodTargetSele
private static final TypeName CALL_TYPE_NAME = TypeName.findOrCreate("Lprologue.js/Function_prototype_call");
private final MethodTargetSelector base;
public JavaScriptFunctionDotCallTargetSelector(MethodTargetSelector base, IAnalysisCacheView cache2) {
public JavaScriptFunctionDotCallTargetSelector(MethodTargetSelector base) {
this.base = base;
}

View File

@ -161,7 +161,7 @@ public class SSAConversion extends AbstractSSAConversion {
return (o instanceof CopyPropagationRecord) && instructionIndex == ((CopyPropagationRecord) o).instructionIndex;
}
private CopyPropagationRecord(int instructionIndex, int lhs, int rhs) {
private CopyPropagationRecord(int instructionIndex, int rhs) {
if (DEBUG_UNDO)
System.err.println(("new copy record for instruction #" + instructionIndex + ", rhs value is " + rhs));
this.rhs = rhs;
@ -442,7 +442,7 @@ public class SSAConversion extends AbstractSSAConversion {
assignments.put(rhs, lhs);
CopyPropagationRecord rec = new CopyPropagationRecord(index, lhs, newRhs);
CopyPropagationRecord rec = new CopyPropagationRecord(index, newRhs);
push(R[lhs], rec);
if (topR(rhs) != null) {
topR(rhs).addChild(rec);

View File

@ -63,10 +63,10 @@ public class ContextSensitiveReachingDefs {
*/
private final ReachingDefsDomain domain = new ReachingDefsDomain();
public ContextSensitiveReachingDefs(CallGraph cg, IAnalysisCacheView cache) {
public ContextSensitiveReachingDefs(CallGraph cg) {
this.cha = cg.getClassHierarchy();
// we use an ICFGSupergraph, which basically adapts ExplodedInterproceduralCFG to the ISupergraph interface
this.supergraph = ICFGSupergraph.make(cg, cache);
this.supergraph = ICFGSupergraph.make(cg);
}
/**

View File

@ -184,8 +184,7 @@ public class DataflowTest extends WalaTestCase {
CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, new AnalysisCacheImpl(), cha, scope);
CallGraph cg = builder.makeCallGraph(options, null);
IAnalysisCacheView cache = new AnalysisCacheImpl();
ContextSensitiveReachingDefs reachingDefs = new ContextSensitiveReachingDefs(cg, cache);
ContextSensitiveReachingDefs reachingDefs = new ContextSensitiveReachingDefs(cg);
TabulationResult<BasicBlockInContext<IExplodedBasicBlock>, CGNode, Pair<CGNode, Integer>> result = reachingDefs.analyze();
ISupergraph<BasicBlockInContext<IExplodedBasicBlock>, CGNode> supergraph = reachingDefs.getSupergraph();
for (BasicBlockInContext<IExplodedBasicBlock> bb : supergraph) {

View File

@ -83,8 +83,7 @@ public class InitializerTest {
System.out.println("Start");
IAnalysisCacheView cache = new AnalysisCacheImpl();
StaticInitializer reachingDefs = new StaticInitializer(cg, cache);
StaticInitializer reachingDefs = new StaticInitializer(cg);
TabulationResult<BasicBlockInContext<IExplodedBasicBlock>, CGNode, IClass> result = reachingDefs.analyze();
ISupergraph<BasicBlockInContext<IExplodedBasicBlock>, CGNode> supergraph = reachingDefs.getSupergraph();
for (BasicBlockInContext<IExplodedBasicBlock> bb : supergraph) {

View File

@ -68,9 +68,9 @@ public class StaticInitializer {
return initialized;
}
public StaticInitializer(CallGraph cg, IAnalysisCacheView cache) {
public StaticInitializer(CallGraph cg) {
cha = cg.getClassHierarchy();
supergraph = ICFGSupergraph.make(cg, cache);
supergraph = ICFGSupergraph.make(cg);
}
/**

View File

@ -141,7 +141,7 @@ public class IntraprocNullPointerAnalysis<T extends ISSABasicBlock> {
solver.solve(progress);
final Graph<T> deleted = createDeletedGraph(solver);
final Graph<T> deleted = createDeletedGraph();
for (final T ch : catched) {
deleted.addNode(ch);
@ -161,8 +161,8 @@ public class IntraprocNullPointerAnalysis<T extends ISSABasicBlock> {
}
}
private Graph<T> createDeletedGraph(NullPointerSolver<T> solver) {
NegativeCFGBuilderVisitor nCFGbuilder = new NegativeCFGBuilderVisitor(solver);
private Graph<T> createDeletedGraph() {
NegativeCFGBuilderVisitor nCFGbuilder = new NegativeCFGBuilderVisitor();
for (T bb : cfg) {
nCFGbuilder.work(bb);
}
@ -201,7 +201,7 @@ public class IntraprocNullPointerAnalysis<T extends ISSABasicBlock> {
private class NegativeCFGBuilderVisitor implements IVisitor {
private final Graph<T> deleted;
private NegativeCFGBuilderVisitor(NullPointerSolver<T> solver) {
private NegativeCFGBuilderVisitor() {
this.deleted = new SparseNumberedGraph<T>(2);
for (T bb : cfg) {
deleted.addNode(bb);

View File

@ -52,12 +52,12 @@ public class ICFGSupergraph implements ISupergraph<BasicBlockInContext<IExploded
private final ExplodedInterproceduralCFG icfg;
protected ICFGSupergraph(ExplodedInterproceduralCFG icfg, IAnalysisCacheView cache) {
protected ICFGSupergraph(ExplodedInterproceduralCFG icfg) {
this.icfg = icfg;
}
public static ICFGSupergraph make(CallGraph cg, IAnalysisCacheView cache) {
ICFGSupergraph w = new ICFGSupergraph(ExplodedInterproceduralCFG.make(cg), cache);
public static ICFGSupergraph make(CallGraph cg) {
ICFGSupergraph w = new ICFGSupergraph(ExplodedInterproceduralCFG.make(cg));
return w;
}

View File

@ -65,7 +65,7 @@ public class IFDSExplorerExample {
CallGraph cg = builder.makeCallGraph(options, null);
System.out.println("done with CG");
System.out.println("computing reaching defs");
ContextSensitiveReachingDefs reachingDefs = new ContextSensitiveReachingDefs(cg, cache);
ContextSensitiveReachingDefs reachingDefs = new ContextSensitiveReachingDefs(cg);
TabulationResult<BasicBlockInContext<IExplodedBasicBlock>, CGNode, Pair<CGNode, Integer>> result = reachingDefs.analyze();
System.out.println("done with reaching defs");
IFDSExplorer.setDotExe(p.getProperty("dotExe"));

View File

@ -48,8 +48,6 @@
*/
package org.scandroid.flow.functions;
import org.scandroid.domain.IFDSTaintDomain;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
@ -58,7 +56,7 @@ import com.ibm.wala.util.intset.IntSetAction;
public class TracingFlowFunction<E extends ISSABasicBlock> implements IUnaryFlowFunction {
private final IUnaryFlowFunction function;
public TracingFlowFunction(IFDSTaintDomain<E> domain, IUnaryFlowFunction function) {
public TracingFlowFunction(IUnaryFlowFunction function) {
this.function = function;
}

View File

@ -205,7 +205,7 @@ public class CGAnalysisContext<E extends ISSABasicBlock> {
}
});
if (options.includeLibrary()) {
graph = (ISupergraph) ICFGSupergraph.make(cg, cache);
graph = (ISupergraph) ICFGSupergraph.make(cg);
} else {
Collection<CGNode> nodes = HashSetFactory.make();
@ -213,7 +213,7 @@ public class CGAnalysisContext<E extends ISSABasicBlock> {
nodes.add(nIter.next());
}
CallGraph pcg = PartialCallGraph.make(cg, cg.getEntrypointNodes(), nodes);
graph = (ISupergraph) ICFGSupergraph.make(pcg, cache);
graph = (ISupergraph) ICFGSupergraph.make(pcg);
}
oneLevelGraph = GraphSlicer.prune(cg, new Predicate<CGNode>() {

View File

@ -42,7 +42,7 @@ public class AddBytecodeDebug {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1; i++) {
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
try (final Writer w = new BufferedWriter(new FileWriter("report", false))) {
args = instrumenter.parseStandardArgs(args);

View File

@ -73,7 +73,7 @@ public class Bench {
doException = true;
}
}
instrumenter = new OfflineInstrumenter(!doException);
instrumenter = new OfflineInstrumenter();
instrumenter.setPassUnmodifiedClasses(true);
instrumenter.beginTraversal();
ClassInstrumenter ci;

View File

@ -41,7 +41,7 @@ public class InterfaceAnalyzer {
final static HashMap<String, TypeStats> typeStats = new HashMap<>();
public static void main(String[] args) throws Exception {
OfflineInstrumenter instrumenter = new OfflineInstrumenter(true);
OfflineInstrumenter instrumenter = new OfflineInstrumenter();
try (final Writer w = new BufferedWriter(new OutputStreamWriter(System.out))) {

View File

@ -57,7 +57,7 @@ public class Mangler {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1; i++) {
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
try (final Writer w = new BufferedWriter(new FileWriter("report", false))) {

View File

@ -39,7 +39,7 @@ public class Statistics {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1; i++) {
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
try (Writer w = new BufferedWriter(new FileWriter("report", false))) {

View File

@ -86,7 +86,7 @@ public class OfflineDynamicCallGraph {
patchCalls = true;
} else if ("--rt-jar".equals(args[i])) {
System.err.println("using " + args[i+1] + " as stdlib");
OfflineInstrumenter libReader = new OfflineInstrumenter(true);
OfflineInstrumenter libReader = new OfflineInstrumenter();
libReader.addInputJar(new File(args[i+1]));
while ((ci = libReader.nextClass()) != null) {
CTUtils.addClassToHierarchy(cha, ci.getReader());
@ -94,7 +94,7 @@ public class OfflineDynamicCallGraph {
}
}
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
args = instrumenter.parseStandardArgs(args);
instrumenter.setPassUnmodifiedClasses(true);

View File

@ -23,7 +23,7 @@ public class OnlineDynamicCallGraph implements ClassFileTransformer {
private Writer out = new PrintWriter(System.err);
public OnlineDynamicCallGraph() throws IllegalArgumentException, IOException, InvalidClassFileException {
OfflineInstrumenter libReader = new OfflineInstrumenter(true);
OfflineInstrumenter libReader = new OfflineInstrumenter();
for (String cps : new String[]{ System.getProperty("java.class.path"), System.getProperty("sun.boot.class.path") }) {
for (String cp : cps.split(File.pathSeparator)) {
File x = new File(cp);
@ -50,7 +50,7 @@ public class OnlineDynamicCallGraph implements ClassFileTransformer {
if (className.contains("com/ibm/wala") || className.contains("java/lang") || (className.contains("java/") && !className.matches("java/util/[A-Z]")) || className.contains("sun/")) {
return classfileBuffer;
} else {
ClassInstrumenter ci = new ClassInstrumenter(className, classfileBuffer, cha, false);
ClassInstrumenter ci = new ClassInstrumenter(className, classfileBuffer, cha);
return OfflineDynamicCallGraph.doClass(ci, out).makeBytes();
}
} catch (InvalidClassFileException | IOException | FailureException e) {

View File

@ -93,7 +93,7 @@ public class CopyWriter {
final ArrayList<ZipEntry> entries = new ArrayList<>();
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
instrumenter.setManifestBuilder(new OfflineInstrumenter.ManifestBuilder() {
@Override
public void addEntry(ZipEntry ze) {

View File

@ -66,8 +66,8 @@ final public class ClassInstrumenter {
/**
* Create a class instrumenter from raw bytes.
*/
public ClassInstrumenter(String inputName, byte[] bytes, ClassHierarchyProvider cha, boolean reuseStackMaps) throws InvalidClassFileException {
this(inputName, new ClassReader(bytes), cha, reuseStackMaps);
public ClassInstrumenter(String inputName, byte[] bytes, ClassHierarchyProvider cha) throws InvalidClassFileException {
this(inputName, new ClassReader(bytes), cha);
}
/**
@ -91,7 +91,7 @@ final public class ClassInstrumenter {
*
* @throws IllegalArgumentException if cr is null
*/
public ClassInstrumenter(String inputName, ClassReader cr, ClassHierarchyProvider cha, boolean reuseStackMaps) throws InvalidClassFileException {
public ClassInstrumenter(String inputName, ClassReader cr, ClassHierarchyProvider cha) throws InvalidClassFileException {
if (cr == null) {
throw new IllegalArgumentException("cr is null");
}

View File

@ -24,20 +24,13 @@ import com.ibm.wala.shrikeCT.InvalidClassFileException;
* specialization of OfflineInstrumenterBase to use the shrikeCT functionality.
*/
final public class OfflineInstrumenter extends OfflineInstrumenterBase {
private final boolean reuseStackMaps;
/**
* Create an empty collection of classes to instrument.
*/
public OfflineInstrumenter(boolean reuseStackMaps) {
this.reuseStackMaps = reuseStackMaps;
}
@Override
protected Object makeClassFromStream(String inputName, BufferedInputStream s) throws IOException {
byte[] bytes = new byte[s.available()];
Util.readFully(s, bytes);
try {
return new ClassInstrumenter(inputName, bytes, cha, reuseStackMaps);
return new ClassInstrumenter(inputName, bytes, cha);
} catch (InvalidClassFileException e) {
throw new IOException("Class is invalid: " + e.getMessage());
}

View File

@ -48,7 +48,7 @@ public class BatchVerifier {
private static int errors = 0;
public static void main(String[] args) throws Exception {
OfflineInstrumenter oi = new OfflineInstrumenter(true);
OfflineInstrumenter oi = new OfflineInstrumenter();
args = oi.parseStandardArgs(args);
for (int i = 0; i < args.length; i++) {

View File

@ -41,7 +41,7 @@ public class BootstrapDumper {
}
public static void main(String[] args) throws Exception {
OfflineInstrumenter oi = new OfflineInstrumenter(true);
OfflineInstrumenter oi = new OfflineInstrumenter();
String[] classpathEntries = oi.parseStandardArgs(args);
PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

View File

@ -57,7 +57,7 @@ public class BootstrapInstrumentor {
}
public void doit(String[] args) throws Exception {
OfflineInstrumenter oi = new OfflineInstrumenter(true);
OfflineInstrumenter oi = new OfflineInstrumenter();
oi.parseStandardArgs(args);
oi.setPassUnmodifiedClasses(true);

View File

@ -72,7 +72,7 @@ public class ClassPrinter {
}
public static void main(String[] args) throws Exception {
OfflineInstrumenter oi = new OfflineInstrumenter(true);
OfflineInstrumenter oi = new OfflineInstrumenter();
args = oi.parseStandardArgs(args);
PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

View File

@ -36,7 +36,7 @@ public class ClassSearcher {
private static int scanned = 0;
public static void main(String[] args) throws Exception {
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
try (final Writer w = new BufferedWriter(new FileWriter("report", true))) {

View File

@ -51,7 +51,7 @@ public class MethodTracer {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1; i++) {
instrumenter = new OfflineInstrumenter(true);
instrumenter = new OfflineInstrumenter();
try (final Writer w = new BufferedWriter(new FileWriter("report", false))) {