2012-09-04 22:56:05 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* 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
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* Created on Oct 3, 2005
|
|
|
|
*/
|
|
|
|
package com.ibm.wala.cast.java.test;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.ArrayList;
|
2013-05-28 22:31:30 +00:00
|
|
|
import java.util.Arrays;
|
2012-09-04 22:56:05 +00:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.jar.JarFile;
|
|
|
|
|
|
|
|
import org.junit.Assert;
|
|
|
|
|
|
|
|
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
|
|
|
import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
|
|
|
import com.ibm.wala.cast.loader.AstClass;
|
|
|
|
import com.ibm.wala.cast.loader.AstMethod;
|
|
|
|
import com.ibm.wala.classLoader.IClass;
|
|
|
|
import com.ibm.wala.classLoader.IClassLoader;
|
|
|
|
import com.ibm.wala.classLoader.IMethod;
|
|
|
|
import com.ibm.wala.classLoader.JarFileModule;
|
|
|
|
import com.ibm.wala.classLoader.Language;
|
|
|
|
import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
|
|
|
import com.ibm.wala.classLoader.SourceFileModule;
|
|
|
|
import com.ibm.wala.client.AbstractAnalysisEngine;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
2018-04-10 20:00:44 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
2014-05-20 20:00:06 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
2012-09-04 22:56:05 +00:00
|
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
|
|
import com.ibm.wala.properties.WalaProperties;
|
|
|
|
import com.ibm.wala.ssa.IR;
|
|
|
|
import com.ibm.wala.ssa.SSAInstruction;
|
|
|
|
import com.ibm.wala.types.ClassLoaderReference;
|
|
|
|
import com.ibm.wala.types.MethodReference;
|
|
|
|
import com.ibm.wala.types.TypeName;
|
|
|
|
import com.ibm.wala.types.TypeReference;
|
2013-02-03 02:27:45 +00:00
|
|
|
import com.ibm.wala.types.annotations.Annotation;
|
2012-09-04 22:56:05 +00:00
|
|
|
import com.ibm.wala.util.CancelException;
|
|
|
|
import com.ibm.wala.util.collections.HashSetFactory;
|
2017-12-04 04:39:28 +00:00
|
|
|
import com.ibm.wala.util.collections.Iterator2Iterable;
|
2012-09-04 22:56:05 +00:00
|
|
|
import com.ibm.wala.util.collections.Pair;
|
|
|
|
import com.ibm.wala.util.debug.Assertions;
|
|
|
|
import com.ibm.wala.util.strings.Atom;
|
|
|
|
|
|
|
|
public abstract class IRTests {
|
|
|
|
|
2015-02-26 14:34:03 +00:00
|
|
|
protected boolean dump = false;
|
|
|
|
|
2012-09-04 22:56:05 +00:00
|
|
|
protected IRTests(String projectName) {
|
|
|
|
this.projectName = projectName;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected final String projectName;
|
|
|
|
|
|
|
|
protected static String javaHomePath;
|
|
|
|
|
|
|
|
private String testSrcPath = "." + File.separator + "src";
|
|
|
|
|
2013-05-28 22:31:30 +00:00
|
|
|
public static final List<String> rtJar = Arrays.asList(WalaProperties.getJ2SEJarFiles());
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
protected static List<IRAssertion> emptyList = Collections.emptyList();
|
|
|
|
|
2013-05-28 22:32:24 +00:00
|
|
|
// TODO delete this code; leaving just in case --MS
|
2013-05-28 22:31:30 +00:00
|
|
|
// static {
|
|
|
|
// boolean found = false;
|
|
|
|
// try {
|
|
|
|
// rtJar = new LinkedList<String>();
|
|
|
|
//
|
|
|
|
// Properties p = WalaProperties.loadProperties();
|
|
|
|
// javaHomePath = p.getProperty(WalaProperties.J2SE_DIR);
|
|
|
|
//
|
|
|
|
// if (new File(javaHomePath).isDirectory()) {
|
|
|
|
// if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
|
|
|
// /**
|
|
|
|
// * todo: {@link WalaProperties#getJ2SEJarFiles()}
|
|
|
|
// */
|
|
|
|
// rtJar.add(javaHomePath + "/classes.jar");
|
|
|
|
// rtJar.add(javaHomePath + "/ui.jar");
|
|
|
|
// } else {
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "classes.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "rt.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "core.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "vm.jar");
|
|
|
|
// }
|
|
|
|
// found = true;
|
|
|
|
// }
|
|
|
|
// } catch (Exception e) {
|
|
|
|
// // no properties
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if (!found) {
|
|
|
|
// javaHomePath = System.getProperty("java.home");
|
|
|
|
// if ("Mac OS X".equals(System.getProperty("os.name"))) { // nick
|
|
|
|
// rtJar.add(javaHomePath + "/../Classes/classes.jar");
|
|
|
|
// rtJar.add(javaHomePath + "/../Classes/ui.jar");
|
|
|
|
// } else {
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "rt.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "core.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "vm.jar");
|
|
|
|
// rtJar.add(javaHomePath + File.separator + "lib" + File.separator + "classes.jar");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
public interface IRAssertion {
|
|
|
|
|
|
|
|
void check(CallGraph cg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static class EdgeAssertions implements IRAssertion {
|
|
|
|
public final String srcDescriptor;
|
|
|
|
|
2017-03-12 03:20:51 +00:00
|
|
|
public final List/* <String> */<String> tgtDescriptors = new ArrayList<>();
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
public EdgeAssertions(String srcDescriptor) {
|
|
|
|
this.srcDescriptor = srcDescriptor;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor) {
|
|
|
|
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor);
|
|
|
|
return ea;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2) {
|
|
|
|
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor1);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor2);
|
|
|
|
return ea;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3) {
|
|
|
|
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor1);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor2);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor3);
|
|
|
|
return ea;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static EdgeAssertions make(String srcDescriptor, String tgtDescriptor1, String tgtDescriptor2, String tgtDescriptor3,
|
|
|
|
String tgtDescriptor4) {
|
|
|
|
EdgeAssertions ea = new EdgeAssertions(srcDescriptor);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor1);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor2);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor3);
|
|
|
|
ea.tgtDescriptors.add(tgtDescriptor4);
|
|
|
|
return ea;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:53:58 +00:00
|
|
|
@Override
|
2012-09-04 22:56:05 +00:00
|
|
|
public void check(CallGraph callGraph) {
|
|
|
|
MethodReference srcMethod = descriptorToMethodRef(this.srcDescriptor, callGraph.getClassHierarchy());
|
|
|
|
Set<CGNode> srcNodes = callGraph.getNodes(srcMethod);
|
|
|
|
|
|
|
|
if (srcNodes.size() == 0) {
|
|
|
|
System.err.println(("Unreachable/non-existent method: " + srcMethod));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (srcNodes.size() > 1) {
|
|
|
|
System.err.println("Context-sensitive call graph?");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assume only one node for src method
|
|
|
|
CGNode srcNode = srcNodes.iterator().next();
|
|
|
|
|
|
|
|
for (String target : this.tgtDescriptors) {
|
|
|
|
MethodReference tgtMethod = descriptorToMethodRef(target, callGraph.getClassHierarchy());
|
|
|
|
// Assume only one node for target method
|
|
|
|
Set<CGNode> tgtNodes = callGraph.getNodes(tgtMethod);
|
|
|
|
if (tgtNodes.size() == 0) {
|
|
|
|
System.err.println(("Unreachable/non-existent method: " + tgtMethod));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
CGNode tgtNode = tgtNodes.iterator().next();
|
|
|
|
|
|
|
|
boolean found = false;
|
2017-12-04 04:39:28 +00:00
|
|
|
for (CGNode succ : Iterator2Iterable.make(callGraph.getSuccNodes(srcNode))) {
|
2012-09-04 22:56:05 +00:00
|
|
|
if (tgtNode == succ) {
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
System.err.println(("Missing edge: " + srcMethod + " -> " + tgtMethod));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static class SourceMapAssertion implements IRAssertion {
|
|
|
|
private final String method;
|
|
|
|
|
|
|
|
private final String variableName;
|
|
|
|
|
|
|
|
private final int definingLineNumber;
|
|
|
|
|
|
|
|
protected SourceMapAssertion(String method, String variableName, int definingLineNumber) {
|
|
|
|
this.method = method;
|
|
|
|
this.variableName = variableName;
|
|
|
|
this.definingLineNumber = definingLineNumber;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:53:58 +00:00
|
|
|
@Override
|
2012-09-04 22:56:05 +00:00
|
|
|
public void check(CallGraph cg) {
|
|
|
|
|
|
|
|
MethodReference mref = descriptorToMethodRef(method, cg.getClassHierarchy());
|
|
|
|
|
|
|
|
for (CGNode cgNode : cg.getNodes(mref)) {
|
2015-10-14 17:32:34 +00:00
|
|
|
Assert.assertTrue("failed for " + this.variableName + " in " + cgNode + "\n" + cgNode.getIR(), this.check(cgNode.getMethod(), cgNode.getIR()));
|
2012-09-04 22:56:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean check(IMethod m, IR ir) {
|
|
|
|
System.err.println(("check for " + variableName + " defined at " + definingLineNumber));
|
|
|
|
SSAInstruction[] insts = ir.getInstructions();
|
|
|
|
for (int i = 0; i < insts.length; i++) {
|
|
|
|
if (insts[i] != null) {
|
|
|
|
int ln = m.getLineNumber(i);
|
|
|
|
if (ln == definingLineNumber) {
|
|
|
|
System.err.println((" found " + insts[i] + " at " + ln));
|
|
|
|
for (int j = 0; j < insts[i].getNumberOfDefs(); j++) {
|
|
|
|
int def = insts[i].getDef(j);
|
|
|
|
System.err.println((" looking at def " + j + ": " + def));
|
|
|
|
String[] names = ir.getLocalNames(i, def);
|
|
|
|
if (names != null) {
|
|
|
|
for (String name : names) {
|
|
|
|
System.err.println((" looking at name " + name));
|
|
|
|
if (name.equals(variableName)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-03 02:27:45 +00:00
|
|
|
protected static class AnnotationAssertions implements IRAssertion {
|
|
|
|
|
|
|
|
public static class ClassAnnotation {
|
|
|
|
private final String className;
|
|
|
|
private final String annotationTypeName;
|
|
|
|
|
|
|
|
public ClassAnnotation(String className, String annotationTypeName) {
|
|
|
|
super();
|
|
|
|
this.className = className;
|
|
|
|
this.annotationTypeName = annotationTypeName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class MethodAnnotation {
|
|
|
|
private final String methodSig;
|
|
|
|
private final String annotationTypeName;
|
|
|
|
|
|
|
|
public MethodAnnotation(String methodSig, String annotationTypeName) {
|
|
|
|
super();
|
|
|
|
this.methodSig = methodSig;
|
|
|
|
this.annotationTypeName = annotationTypeName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public final Set<ClassAnnotation> classAnnotations = HashSetFactory.make();
|
|
|
|
public final Set<MethodAnnotation> methodAnnotations = HashSetFactory.make();
|
|
|
|
|
2013-06-25 15:53:58 +00:00
|
|
|
@Override
|
2013-02-03 02:27:45 +00:00
|
|
|
public void check(CallGraph cg) {
|
|
|
|
classes: for(ClassAnnotation ca : classAnnotations) {
|
|
|
|
IClass cls = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ca.className));
|
|
|
|
IClass at = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ca.annotationTypeName));
|
|
|
|
for(Annotation a : cls.getAnnotations()) {
|
|
|
|
if (a.getType().equals(at.getReference())) {
|
|
|
|
continue classes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Assert.assertFalse("cannot find " + at + " in " + cls, false);
|
|
|
|
}
|
|
|
|
|
2013-03-01 15:07:20 +00:00
|
|
|
annot: for(MethodAnnotation ma : methodAnnotations) {
|
2013-02-03 02:27:45 +00:00
|
|
|
IClass at = cg.getClassHierarchy().lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, ma.annotationTypeName));
|
2013-03-01 15:07:20 +00:00
|
|
|
for(CGNode n : cg) {
|
2013-02-03 02:27:45 +00:00
|
|
|
if (n.getMethod().getSignature().equals(ma.methodSig)) {
|
|
|
|
for(Annotation a : n.getMethod().getAnnotations()) {
|
|
|
|
if (a.getType().equals(at.getReference())) {
|
|
|
|
continue annot;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Assert.assertFalse("cannot find " + at, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-04 22:56:05 +00:00
|
|
|
protected Collection<String> singleTestSrc() {
|
|
|
|
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaInputForTest());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Collection<String> singleTestSrc(final String folder) {
|
|
|
|
return Collections.singletonList(getTestSrcPath() + File.separator + folder + File.separator + singleJavaInputForTest());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Collection<String> singlePkgTestSrc(String pkgName) {
|
|
|
|
return Collections.singletonList(getTestSrcPath() + File.separator + singleJavaPkgInputForTest(pkgName));
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String getTestName() {
|
|
|
|
StackTraceElement stack[] = new Throwable().getStackTrace();
|
|
|
|
for(int i = 0; i <= stack.length; i++) {
|
|
|
|
if (stack[i].getMethodName().startsWith("test")) {
|
|
|
|
return stack[i].getMethodName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error("test method not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String[] simpleTestEntryPoint() {
|
|
|
|
return new String[] { "L" + getTestName().substring(4) };
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String[] simplePkgTestEntryPoint(String pkgName) {
|
|
|
|
return new String[] { "L" + pkgName + "/" + getTestName().substring(4) };
|
|
|
|
}
|
|
|
|
|
2018-04-10 20:00:44 +00:00
|
|
|
protected abstract <I extends InstanceKey> AbstractAnalysisEngine<I, CallGraphBuilder<I>, ?> getAnalysisEngine(String[] mainClassDescriptors, Collection<String> sources, List<String> libs);
|
2012-09-04 22:56:05 +00:00
|
|
|
|
2018-04-13 17:51:58 +00:00
|
|
|
public <I extends InstanceKey> Pair<CallGraph, PointerAnalysis<? extends InstanceKey>> runTest(Collection<String> sources, List<String> libs,
|
2015-10-14 17:32:34 +00:00
|
|
|
String[] mainClassDescriptors, List<? extends IRAssertion> ca, boolean assertReachable) throws IllegalArgumentException, CancelException, IOException {
|
2018-04-10 20:00:44 +00:00
|
|
|
AbstractAnalysisEngine<I, CallGraphBuilder<I>, ?> engine = getAnalysisEngine(mainClassDescriptors, sources, libs);
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
CallGraph callGraph;
|
|
|
|
callGraph = engine.buildDefaultCallGraph();
|
2013-12-03 20:20:53 +00:00
|
|
|
//System.err.println(callGraph.toString());
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
// If we've gotten this far, IR has been produced.
|
2015-02-26 14:34:03 +00:00
|
|
|
if (dump) {
|
|
|
|
dumpIR(callGraph, sources, assertReachable);
|
|
|
|
}
|
|
|
|
|
2012-09-04 22:56:05 +00:00
|
|
|
// Now check any assertions as to source mapping
|
|
|
|
for (IRAssertion IRAssertion : ca) {
|
|
|
|
IRAssertion.check(callGraph);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Pair.make(callGraph, engine.getPointerAnalysis());
|
2015-10-14 17:32:34 +00:00
|
|
|
}
|
2012-09-04 22:56:05 +00:00
|
|
|
|
2017-07-27 21:53:07 +00:00
|
|
|
protected static void dumpIR(CallGraph cg, Collection<String> sources, boolean assertReachable) {
|
2012-09-04 22:56:05 +00:00
|
|
|
Set<String> sourcePaths = HashSetFactory.make();
|
|
|
|
for(String src : sources) {
|
|
|
|
sourcePaths.add(src.substring(src.lastIndexOf(File.separator)+1));
|
|
|
|
}
|
|
|
|
|
|
|
|
Set<IMethod> unreachable = HashSetFactory.make();
|
|
|
|
IClassHierarchy cha = cg.getClassHierarchy();
|
|
|
|
IClassLoader sourceLoader = cha.getLoader(JavaSourceAnalysisScope.SOURCE);
|
2017-12-04 04:39:28 +00:00
|
|
|
for (IClass clazz : Iterator2Iterable.make(sourceLoader.iterateAllClasses())) {
|
2012-09-04 22:56:05 +00:00
|
|
|
|
|
|
|
System.err.println(clazz);
|
|
|
|
if (clazz.isInterface())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (IMethod m : clazz.getDeclaredMethods()) {
|
|
|
|
if (m.isAbstract()) {
|
|
|
|
System.err.println(m);
|
|
|
|
} else {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
Iterator<CGNode> nodeIter = cg.getNodes(m.getReference()).iterator();
|
2012-09-04 22:56:05 +00:00
|
|
|
if (!nodeIter.hasNext()) {
|
|
|
|
if (m instanceof AstMethod) {
|
|
|
|
String fn = ((AstClass)m.getDeclaringClass()).getSourcePosition().getURL().getFile();
|
|
|
|
if (sourcePaths.contains(fn.substring(fn.lastIndexOf(File.separator)+1))) {
|
|
|
|
System.err.println(("Method " + m.getReference() + " not reachable?"));
|
|
|
|
unreachable.add(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
CGNode node = nodeIter.next();
|
2012-09-04 22:56:05 +00:00
|
|
|
System.err.println(node.getIR());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (assertReachable) {
|
|
|
|
Assert.assertTrue("unreachable methods: " + unreachable.toString(), unreachable.isEmpty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param srcMethodDescriptor a full method descriptor of the form ldr#type#methName#methSig example:
|
|
|
|
* Source#Simple1#main#([Ljava/lang/String;)V
|
|
|
|
* @param cha
|
|
|
|
*/
|
|
|
|
public static MethodReference descriptorToMethodRef(String srcMethodDescriptor, IClassHierarchy cha) {
|
|
|
|
String[] ldrTypeMeth = srcMethodDescriptor.split("\\#");
|
|
|
|
|
|
|
|
String loaderName = ldrTypeMeth[0];
|
|
|
|
String typeStr = ldrTypeMeth[1];
|
|
|
|
String methName = ldrTypeMeth[2];
|
|
|
|
String methSig = ldrTypeMeth[3];
|
|
|
|
|
|
|
|
TypeReference typeRef = findOrCreateTypeReference(loaderName, typeStr, cha);
|
|
|
|
|
|
|
|
Language l = cha.getLoader(typeRef.getClassLoader()).getLanguage();
|
|
|
|
return MethodReference.findOrCreate(l, typeRef, methName, methSig);
|
|
|
|
}
|
|
|
|
|
|
|
|
static TypeReference findOrCreateTypeReference(String loaderName, String typeStr, IClassHierarchy cha) {
|
|
|
|
ClassLoaderReference clr = findLoader(loaderName, cha);
|
|
|
|
TypeName typeName = TypeName.string2TypeName("L" + typeStr);
|
|
|
|
TypeReference typeRef = TypeReference.findOrCreate(clr, typeName);
|
|
|
|
return typeRef;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ClassLoaderReference findLoader(String loaderName, IClassHierarchy cha) {
|
|
|
|
Atom loaderAtom = Atom.findOrCreateUnicodeAtom(loaderName);
|
|
|
|
IClassLoader[] loaders = cha.getLoaders();
|
|
|
|
for (IClassLoader loader : loaders) {
|
|
|
|
if (loader.getName() == loaderAtom) {
|
|
|
|
return loader.getReference();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Assertions.UNREACHABLE();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
public static void populateScope(JavaSourceAnalysisEngine<?> engine, Collection<String> sources, List<String> libs) {
|
2012-09-04 22:56:05 +00:00
|
|
|
boolean foundLib = false;
|
|
|
|
for (String lib : libs) {
|
|
|
|
File libFile = new File(lib);
|
|
|
|
if (libFile.exists()) {
|
|
|
|
foundLib = true;
|
|
|
|
try {
|
2016-06-03 11:07:05 +00:00
|
|
|
engine.addSystemModule(new JarFileModule(new JarFile(libFile, false)));
|
2012-09-04 22:56:05 +00:00
|
|
|
} catch (IOException e) {
|
|
|
|
Assert.fail(e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert foundLib : "couldn't find library file from " + libs;
|
|
|
|
|
|
|
|
for (String srcFilePath : sources) {
|
|
|
|
String srcFileName = srcFilePath.substring(srcFilePath.lastIndexOf(File.separator) + 1);
|
|
|
|
File f = new File(srcFilePath);
|
|
|
|
Assert.assertTrue("couldn't find " + srcFilePath, f.exists());
|
|
|
|
if (f.isDirectory()) {
|
|
|
|
engine.addSourceModule(new SourceDirectoryTreeModule(f));
|
|
|
|
} else {
|
2013-06-25 15:53:58 +00:00
|
|
|
engine.addSourceModule(new SourceFileModule(f, srcFileName, null));
|
2012-09-04 22:56:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setTestSrcPath(String testSrcPath) {
|
|
|
|
this.testSrcPath = testSrcPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String getTestSrcPath() {
|
|
|
|
return testSrcPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String singleJavaInputForTest() {
|
|
|
|
return getTestName().substring(4) + ".java";
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String singleInputForTest() {
|
|
|
|
return getTestName().substring(4);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected String singleJavaPkgInputForTest(String pkgName) {
|
|
|
|
return pkgName + File.separator + getTestName().substring(4) + ".java";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|