2013-05-22 22:39:19 +00:00
|
|
|
/*******************************************************************************
|
|
|
|
* Copyright (c) 2013 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
|
|
|
|
*******************************************************************************/
|
2007-11-16 01:53:34 +00:00
|
|
|
package com.ibm.wala.cast.test;
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
import junit.framework.Assert;
|
|
|
|
|
2012-02-17 20:21:59 +00:00
|
|
|
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
2007-11-16 21:01:09 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
|
|
|
import com.ibm.wala.cast.loader.SingleClassLoaderFactory;
|
|
|
|
import com.ibm.wala.classLoader.IClass;
|
|
|
|
import com.ibm.wala.classLoader.IField;
|
|
|
|
import com.ibm.wala.classLoader.IMethod;
|
|
|
|
import com.ibm.wala.classLoader.Language;
|
|
|
|
import com.ibm.wala.classLoader.SourceFileModule;
|
2007-11-16 01:53:34 +00:00
|
|
|
import com.ibm.wala.core.tests.util.WalaTestCase;
|
2007-12-10 05:35:23 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
2007-11-16 01:53:34 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
2007-11-16 21:01:09 +00:00
|
|
|
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
|
|
|
import com.ibm.wala.ssa.IRFactory;
|
|
|
|
import com.ibm.wala.ssa.SSAOptions;
|
|
|
|
import com.ibm.wala.util.collections.HashMapFactory;
|
|
|
|
import com.ibm.wala.util.collections.Pair;
|
2007-11-16 01:53:34 +00:00
|
|
|
|
|
|
|
public abstract class TestCAstTranslator extends WalaTestCase {
|
|
|
|
|
|
|
|
protected static class TranslatorAssertions {
|
2007-11-16 21:01:09 +00:00
|
|
|
private final Set<String> classes = new HashSet<String>();
|
|
|
|
|
|
|
|
private final Map<String, String> supers = new HashMap<String, String>();
|
|
|
|
|
|
|
|
private final Set<Pair<String, String>> instanceFields = new HashSet<Pair<String, String>>();
|
|
|
|
|
|
|
|
private final Set<Pair<String, String>> staticFields = new HashSet<Pair<String, String>>();
|
|
|
|
|
|
|
|
private final Map<Pair<String, Object>, Object> instanceMethods = HashMapFactory.make();
|
|
|
|
|
|
|
|
private final Map<Pair<String, Object>, Object> staticMethods = HashMapFactory.make();
|
|
|
|
|
|
|
|
private Set<String> getClasses() {
|
|
|
|
return classes;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Map<String, String> getSuperClasses() {
|
|
|
|
return supers;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Set<Pair<String, String>> getInstanceFields() {
|
|
|
|
return instanceFields;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Set<Pair<String, String>> getStaticFields() {
|
|
|
|
return staticFields;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Map<Pair<String, Object>, Object> getInstanceMethods() {
|
|
|
|
return instanceMethods;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Map<Pair<String, Object>, Object> getStaticMethods() {
|
|
|
|
return staticMethods;
|
|
|
|
}
|
2007-11-16 01:53:34 +00:00
|
|
|
|
|
|
|
public TranslatorAssertions(Object[][] data) {
|
2007-11-16 21:01:09 +00:00
|
|
|
for (int dataIndex = 0; dataIndex < data.length; dataIndex++) {
|
|
|
|
Object[] entry = data[dataIndex];
|
|
|
|
String clsName = (String) entry[0];
|
|
|
|
this.classes.add(clsName);
|
|
|
|
|
|
|
|
String superName = (String) entry[1];
|
|
|
|
this.supers.put(clsName, superName);
|
|
|
|
|
|
|
|
String[] instanceFields = (String[]) entry[2];
|
|
|
|
if (instanceFields != null) {
|
|
|
|
for (int i = 0; i < instanceFields.length; i++) {
|
|
|
|
this.instanceFields.add(Pair.make(clsName, instanceFields[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String[] staticFields = (String[]) entry[3];
|
|
|
|
if (staticFields != null) {
|
|
|
|
for (int i = 0; i < staticFields.length; i++) {
|
|
|
|
this.staticFields.add(Pair.make(clsName, staticFields[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Pair[] instanceMethods = (Pair[]) entry[4];
|
|
|
|
if (instanceMethods != null) {
|
|
|
|
for (int i = 0; i < instanceMethods.length; i++) {
|
|
|
|
this.instanceMethods.put(Pair.make(clsName, instanceMethods[i].fst), instanceMethods[i].snd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Pair[] staticMethods = (Pair[]) entry[5];
|
|
|
|
if (staticMethods != null) {
|
|
|
|
for (int i = 0; i < staticMethods.length; i++) {
|
|
|
|
this.staticMethods.put(Pair.make(clsName, staticMethods[i].fst), staticMethods[i].snd);
|
|
|
|
}
|
|
|
|
}
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
2007-11-16 21:01:09 +00:00
|
|
|
}
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract Language getLanguage();
|
|
|
|
|
|
|
|
protected abstract String getTestPath();
|
|
|
|
|
|
|
|
protected abstract SingleClassLoaderFactory getClassLoaderFactory();
|
|
|
|
|
2008-12-16 14:57:18 +00:00
|
|
|
protected final IRFactory<IMethod> factory = AstIRFactory.makeDefaultFactory();
|
2007-11-16 21:01:09 +00:00
|
|
|
|
2007-11-16 01:53:34 +00:00
|
|
|
protected final SSAOptions options = new SSAOptions();
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
public ClassHierarchy runTranslator(SourceFileModule[] fileNames) throws Exception {
|
2007-11-16 01:53:34 +00:00
|
|
|
SingleClassLoaderFactory loaders = getClassLoaderFactory();
|
|
|
|
|
2012-02-17 20:21:59 +00:00
|
|
|
AnalysisScope scope = CAstCallGraphUtil.makeScope(fileNames, loaders, getLanguage());
|
2007-11-16 01:53:34 +00:00
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
ClassHierarchy cha = ClassHierarchy.make(scope, loaders, getLanguage());
|
2007-11-16 01:53:34 +00:00
|
|
|
|
|
|
|
return cha;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void dump(ClassHierarchy cha) {
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> clss = cha.iterator(); clss.hasNext();) {
|
|
|
|
IClass cls = (IClass) clss.next();
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("class " + cls));
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> flds = cls.getDeclaredInstanceFields().iterator(); flds.hasNext();) {
|
|
|
|
IField fld = (IField) flds.next();
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("instance field " + fld));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> flds = cls.getDeclaredStaticFields().iterator(); flds.hasNext();) {
|
|
|
|
IField fld = (IField) flds.next();
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("static field " + fld));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> mths = cls.getDeclaredMethods().iterator(); mths.hasNext();) {
|
|
|
|
IMethod mth = (IMethod) mths.next();
|
|
|
|
if (mth.isStatic())
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print("static ");
|
2009-04-28 19:52:34 +00:00
|
|
|
System.err.println(("method " + mth + " with " + mth.getNumberOfParameters() + " parameters"));
|
2007-11-16 21:01:09 +00:00
|
|
|
for (int i = 0; i < mth.getNumberOfParameters(); i++) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("param " + i + ": " + mth.getParameterType(i)));
|
2007-11-16 21:01:09 +00:00
|
|
|
}
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(factory.makeIR(mth, Everywhere.EVERYWHERE, options));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
public void checkAssertions(ClassHierarchy cha, TranslatorAssertions assertions) {
|
|
|
|
Set<String> classes = assertions.getClasses();
|
|
|
|
Map<String, String> supers = assertions.getSuperClasses();
|
|
|
|
Set<Pair<String, String>> instanceFields = assertions.getInstanceFields();
|
|
|
|
Set<Pair<String, String>> staticFields = assertions.getStaticFields();
|
|
|
|
Map<Pair<String, Object>, Object> instanceMethods = assertions.getInstanceMethods();
|
|
|
|
Map<Pair<String, Object>, Object> staticMethods = assertions.getStaticMethods();
|
2007-11-16 01:53:34 +00:00
|
|
|
|
|
|
|
int clsCount = 0;
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> clss = cha.iterator(); clss.hasNext();) {
|
|
|
|
IClass cls = (IClass) clss.next();
|
2007-11-16 01:53:34 +00:00
|
|
|
clsCount++;
|
2007-11-16 21:01:09 +00:00
|
|
|
Assert.assertTrue("found class " + cls.getName().toString(), classes.contains(cls.getName().toString()));
|
|
|
|
|
2009-04-28 19:52:34 +00:00
|
|
|
if (cls.getSuperclass() == null) {
|
|
|
|
Assert.assertTrue(cls.getName() + " has no superclass", supers.get(cls.getName()) == null);
|
|
|
|
} else {
|
|
|
|
Assert.assertTrue("super of " + cls.getName() + " is " + cls.getSuperclass().getName(), supers
|
|
|
|
.get(cls.getName().toString()).equals(cls.getSuperclass().getName().toString()));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> flds = cls.getDeclaredInstanceFields().iterator(); flds.hasNext();) {
|
|
|
|
IField fld = (IField) flds.next();
|
|
|
|
Assert.assertTrue(cls.getName() + " has field " + fld.getName(), instanceFields.contains(Pair.make(
|
|
|
|
cls.getName().toString(), fld.getName().toString())));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> flds = cls.getDeclaredStaticFields().iterator(); flds.hasNext();) {
|
|
|
|
IField fld = (IField) flds.next();
|
|
|
|
Assert.assertTrue(cls.getName() + " has static field " + fld.getName(), staticFields.contains(Pair.make(cls.getName()
|
|
|
|
.toString(), fld.getName().toString())));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
for (Iterator<?> mths = cls.getDeclaredMethods().iterator(); mths.hasNext();) {
|
|
|
|
IMethod mth = (IMethod) mths.next();
|
|
|
|
Integer np = new Integer(mth.getNumberOfParameters());
|
|
|
|
Pair<String, String> key = Pair.make(cls.getName().toString(), mth.getName().toString());
|
|
|
|
|
|
|
|
if (mth.isStatic()) {
|
|
|
|
Assert.assertTrue(cls.getName() + " has static method " + mth.getName(), staticMethods.containsKey(key));
|
|
|
|
Assert.assertTrue(cls.getName() + "::" + mth.getName() + " has " + np + " parameters", staticMethods.get(key).equals(np));
|
|
|
|
} else {
|
|
|
|
Assert.assertTrue(cls.getName() + " has method " + mth.getName(), instanceMethods.containsKey(key));
|
|
|
|
Assert.assertTrue(cls.getName() + "::" + mth.getName() + " has " + np + " parameters", instanceMethods.get(key)
|
|
|
|
.equals(np));
|
|
|
|
}
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
2007-11-16 21:01:09 +00:00
|
|
|
|
|
|
|
Assert.assertTrue("want " + classes.size() + " classes", clsCount == classes.size());
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
|
2007-11-16 21:01:09 +00:00
|
|
|
protected void testInternal(String[] args, TranslatorAssertions assertions) throws Exception {
|
2007-11-16 01:53:34 +00:00
|
|
|
String testPath = getTestPath();
|
2007-11-16 21:01:09 +00:00
|
|
|
SourceFileModule[] fileNames = new SourceFileModule[args.length];
|
|
|
|
for (int i = 0; i < args.length; i++) {
|
2007-11-16 01:53:34 +00:00
|
|
|
if (new File(args[i]).exists()) {
|
2012-02-17 20:21:59 +00:00
|
|
|
fileNames[i] = CAstCallGraphUtil.makeSourceModule(new File(args[i]).toURI().toURL(), args[i]);
|
2007-11-16 01:53:34 +00:00
|
|
|
} else if (new File(testPath + args[i]).exists()) {
|
2012-02-17 20:21:59 +00:00
|
|
|
fileNames[i] = CAstCallGraphUtil.makeSourceModule(new File(testPath + args[i]).toURI().toURL(), args[i]);
|
2007-11-16 01:53:34 +00:00
|
|
|
} else {
|
2007-11-16 21:01:09 +00:00
|
|
|
URL url = getClass().getClassLoader().getResource(args[i]);
|
2012-02-17 20:21:59 +00:00
|
|
|
fileNames[i] = CAstCallGraphUtil.makeSourceModule(url, args[i]);
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
Assert.assertTrue(args[i], fileNames[i] != null);
|
|
|
|
}
|
2007-11-16 21:01:09 +00:00
|
|
|
|
|
|
|
ClassHierarchy cha = runTranslator(fileNames);
|
|
|
|
dump(cha);
|
2007-11-16 01:53:34 +00:00
|
|
|
if (assertions != null) {
|
2007-11-16 21:01:09 +00:00
|
|
|
checkAssertions(cha, assertions);
|
2007-11-16 01:53:34 +00:00
|
|
|
} else {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("WARNING: no assertions for " + getClass()));
|
2007-11-16 01:53:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void testInternal(String arg, TranslatorAssertions assertions) {
|
|
|
|
try {
|
2007-11-16 21:01:09 +00:00
|
|
|
testInternal(new String[] { arg }, assertions);
|
2007-11-16 01:53:34 +00:00
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
Assert.assertTrue(e.toString(), false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|